diff --git a/.github/workflows/docker-hub-publish.yml b/.github/workflows/docker-hub-publish.yml index 20302aa..f6a35a4 100644 --- a/.github/workflows/docker-hub-publish.yml +++ b/.github/workflows/docker-hub-publish.yml @@ -34,7 +34,7 @@ jobs: - name: Build the Docker image - run: docker build . --file Dockerfile -t mobilesecurity/mdast_cli:2026.7.1 -t mobilesecurity/mdast_cli:latest + run: docker build . --file Dockerfile -t mobilesecurity/mdast_cli:2026.7.2 -t mobilesecurity/mdast_cli:latest - name: Docker Hub push latest image @@ -42,8 +42,7 @@ jobs: - name: Docker Hub push tagged image - run: docker push mobilesecurity/mdast_cli:2026.7.1 - + run: docker push mobilesecurity/mdast_cli:2026.7.2 diff --git a/mdast_cli/distribution_systems/rustore.py b/mdast_cli/distribution_systems/rustore.py index 968659b..73311ed 100644 --- a/mdast_cli/distribution_systems/rustore.py +++ b/mdast_cli/distribution_systems/rustore.py @@ -1,9 +1,11 @@ import logging import os +import warnings import zipfile import requests from tqdm import tqdm +from urllib3.exceptions import InsecureRequestWarning from mdast_cli.helpers.file_utils import ensure_download_dir, cleanup_file @@ -110,13 +112,16 @@ def rustore_download_app(package_name, download_path): 'Accept': '*/*' } - r = requests.get( - app_info['download_url'], - headers=download_headers, - stream=True, - allow_redirects=True, - timeout=120 - ) + with warnings.catch_warnings(): + warnings.simplefilter('ignore', InsecureRequestWarning) + r = requests.get( + app_info['download_url'], + headers=download_headers, + stream=True, + allow_redirects=True, + timeout=120, + verify=False + ) if r.status_code != 200: raise RuntimeError( f"Rustore - Failed to download application. Status: {r.status_code}, " diff --git a/setup.py b/setup.py index 861ce6d..40ba730 100644 --- a/setup.py +++ b/setup.py @@ -6,7 +6,7 @@ setup( name="mdast_cli", - version='2026.7.1', + version='2026.7.2', python_requires='>=3.12', diff --git a/tests/test_rustore.py b/tests/test_rustore.py new file mode 100644 index 0000000..96056d0 --- /dev/null +++ b/tests/test_rustore.py @@ -0,0 +1,66 @@ +import io +import warnings +import zipfile +from unittest import mock + +from urllib3.exceptions import InsecureRequestWarning + +from mdast_cli.distribution_systems import rustore + + +def _apk_bytes(): + buffer = io.BytesIO() + with zipfile.ZipFile(buffer, 'w') as archive: + archive.writestr('AndroidManifest.xml', b'\x00') + return buffer.getvalue() + + +def _rustore_zip_bytes(): + buffer = io.BytesIO() + with zipfile.ZipFile(buffer, 'w') as archive: + archive.writestr('app.apk', _apk_bytes()) + return buffer.getvalue() + + +def test_download_disables_tls_verification(monkeypatch, tmp_path): + apk = _rustore_zip_bytes() + download_url = 'https://static-m.rustore.ru/app.zip' + monkeypatch.setattr(rustore, 'get_app_info', lambda _package_name: { + 'download_url': download_url, + 'package_name': 'com.example.app', + 'version_name': '1.0', + }) + + response = mock.Mock( + status_code=200, + headers={ + 'Content-Type': 'application/zip', + 'content-length': str(len(apk)), + }, + ) + response.iter_content.return_value = [apk] + + def request(*_args, **_kwargs): + warnings.warn('TLS verification is disabled', InsecureRequestWarning) + return response + + get = mock.Mock(side_effect=request) + monkeypatch.setattr(rustore.requests, 'get', get) + + with warnings.catch_warnings(record=True) as caught: + warnings.simplefilter('always') + result = rustore.rustore_download_app('com.example.app', str(tmp_path)) + + get.assert_called_once_with( + download_url, + headers={ + 'User-Agent': 'mdast-cli/1.0 (+https://stingray-tech.ru)', + 'Accept': '*/*', + }, + stream=True, + allow_redirects=True, + timeout=120, + verify=False, + ) + assert not caught + assert zipfile.is_zipfile(result)