
Security News
Deno 2.6 + Socket: Supply Chain Defense In Your CLI
Deno 2.6 introduces deno audit with a new --socket flag that plugs directly into Socket to bring supply chain security checks into the Deno CLI.
mdast-cli
Advanced tools
Python script for automating security analysis of mobile applications.
This script is designed to integrate mobile applications' security analysis into the continuous development process (CI/CD). It supports downloading applications from various distribution systems and performing dynamic security analysis (DAST).
The easiest way to use mdast_cli is via Docker:
# Pull the latest image
docker pull mobilesecurity/mdast_cli:latest
# Run with volume mounts for files and reports
docker run -it \
-v /path/to/apps:/mdast/files \
-v /path/to/reports:/mdast/report \
mobilesecurity/mdast_cli:latest \
--distribution_system file \
--file_path /mdast/files/app.apk \
--url "https://saas.mobile.appsec.world" \
--company_id 1 \
--token "YOUR_TOKEN" \
--profile_id 1
Benefits:
Install from PyPI using pip:
pip install mdast_cli
After installation, you can use the mdast_cli command directly:
mdast_cli --help
Note: You may need to install additional system dependencies depending on your distribution system choice (e.g., apkeep for Google Play).
Requirements:
Clone the repository and install dependencies:
git clone https://github.com/Dynamic-Mobile-Security/mdast-cli.git
cd mdast-cli
pip install -r requirements.txt
Then run the script directly:
python3 mdast_cli/mdast_scan.py --help
mdast_cli -d \
--distribution_system google_play \
--google_play_package_name com.example.app \
--google_play_email user@example.com \
--google_play_aas_token "YOUR_AAS_TOKEN"
mdast_cli \
--distribution_system file \
--file_path app.apk \
--url "https://saas.mobile.appsec.world" \
--company_id 1 \
--token "YOUR_TOKEN" \
--profile_id 1 \
--testcase_id 4 \
--summary_report_json_file_name report.json
Use the --download_only (or -d) flag to download applications without scanning:
mdast_cli -d --distribution_system google_play --google_play_package_name com.example.app ...
Output:
--download_path (default: downloaded_apps/)DOWNLOAD_PATH=/path/to/app.apk for CI/CD parsingUse Cases:
Without --download_only, the script will:
file distribution)--nowait is set)Use a local APK/IPA file for scanning.
Required Parameters:
--distribution_system file--file_path <path> - Absolute or relative path to the application fileExample:
mdast_cli \
--distribution_system file \
--file_path /path/to/app.apk \
--url "https://saas.mobile.appsec.world" \
--company_id 1 \
--token "YOUR_TOKEN" \
--profile_id 1
Docker Example:
docker run -it \
-v /host/path/to/apps:/mdast/files \
-v /host/path/to/reports:/mdast/report \
mobilesecurity/mdast_cli:latest \
--distribution_system file \
--file_path /mdast/files/app.apk \
--url "https://saas.mobile.appsec.world" \
--company_id 1 \
--token "YOUR_TOKEN" \
--summary_report_json_file_name /mdast/report/report.json
Download applications from Google Play Store using apkeep.
Prerequisites:
Install apkeep:
# Using Rust (requires Rust toolchain)
cargo install apkeep
# Or download prebuilt binary from:
# https://github.com/EFForg/apkeep/releases
# Place binary in your PATH
Obtain authentication:
Required Parameters:
--distribution_system google_play--google_play_package_name <package> - Package name (e.g., com.instagram.android)--google_play_email <email> - Google account email--google_play_oauth2_token <token> - OAuth2 token to fetch AAS automatically--google_play_aas_token <token> - Direct AAS token (from previous run)Optional Parameters:
--google_play_file_name <name> - Custom filename for downloaded app--google_play_proxy <proxy> - Proxy configuration (e.g., socks5://user:pass@host:port)Getting Package Name:
play.google.com/store/apps/details?id=<PACKAGE_NAME>Authentication Flow:
First Run (OAuth2):
mdast_cli -d \
--distribution_system google_play \
--google_play_package_name com.example.app \
--google_play_email user@example.com \
--google_play_oauth2_token "ya29.a0AVvZ..."
AAS token: aas_et/... in the outputSubsequent Runs (AAS Token):
mdast_cli -d \
--distribution_system google_play \
--google_play_package_name com.example.app \
--google_play_email user@example.com \
--google_play_aas_token "aas_et/AKppINZUCsnVs80yu3k4ZpiApuOlHlOnxSlwNNMOPjomkWDDbNi1SKd0PRTbOFSS6TNLQFlY70SIrUoxUnababWUcBXuhuVdpmrVUvff5etUCWqToxpRkHV8jf4RLcwX56AMkGhlslqrY4hrAH28-yCyOf9FFeLnhCo9p3ydbRrT5at3Le3Tnc-0CPILroJ_NldfLpDeQvBcj2BM_wBM-Tc"
Important Notes:
Example with Scan:
mdast_cli \
--distribution_system google_play \
--google_play_package_name com.instagram.android \
--google_play_email user@example.com \
--google_play_aas_token "YOUR_AAS_TOKEN" \
--google_play_file_name instagram_latest \
--url "https://saas.mobile.appsec.world" \
--company_id 1 \
--token "YOUR_TOKEN" \
--profile_id 1 \
--testcase_id 4 \
--summary_report_json_file_name report.json
Download iOS applications (.ipa) from the App Store.
Prerequisites:
Required Parameters:
--distribution_system appstore--appstore_app_id <id> - Application ID from App Store URL--appstore_bundle_id <bundle> - Bundle identifier--appstore_apple_id <email> - iTunes account email--appstore_password <password> - iTunes account password--appstore_2FA <code> - 6-digit 2FA codeOptional Parameters:
--appstore_file_name <name> - Custom filename for downloaded IPAGetting App ID:
apps.apple.com/app/id{APP_ID}id398129933 → use 3981299332FA Setup (First Time):
--appstore_2FApassword2FA (e.g., P@ssword742877)Deprecated Parameter:
--appstore_password2FA - Will be removed on 01.05.2023. Use separate --appstore_password and --appstore_2FA instead.Example:
mdast_cli \
--distribution_system appstore \
--appstore_app_id 564177498 \
--appstore_apple_id user@icloud.com \
--appstore_password "YourPassword" \
--appstore_2FA 123456 \
--appstore_file_name my_app \
--url "https://saas.mobile.appsec.world" \
--company_id 2 \
--token "YOUR_TOKEN" \
--profile_id 1246 \
--architecture_id 3
Troubleshooting:
Note: This integration uses ipatool - thanks to all contributors!
Download applications from Firebase App Distribution.
Prerequisites:
cloud-platform scopeRequired Parameters:
--distribution_system firebase--firebase_project_number <number> - Project number (integer)--firebase_app_id <id> - Application ID (format: 1:PROJECT:android:APP_ID)--firebase_account_json_path <path> - Path to Service Account JSON key file--firebase_file_extension <ext> - File extension: apk or ipaOptional Parameters:
--firebase_file_name <name> - Custom filename (defaults to version name)Finding Project Number:
Finding App ID:
1:PROJECT_NUMBER:android:APP_ID or 1:PROJECT_NUMBER:ios:APP_IDCreating Service Account:
Cloud Platform scope (/auth/cloud-platform)Example:
mdast_cli -d \
--distribution_system firebase \
--firebase_project_number 1231231337 \
--firebase_app_id "1:1337:android:123123" \
--firebase_account_json_path /path/to/service_account.json \
--firebase_file_extension apk \
--firebase_file_name my_app
Security Note: Never commit Service Account JSON files to version control. Use environment variables or secure secret management in CI/CD.
Download applications from Nexus Repository Manager 3.x (Maven repository).
Required Parameters:
--distribution_system nexus--nexus_url <url> - Nexus server URL (e.g., https://nexus.example.com)--nexus_login <username> - Nexus username--nexus_password <password> - Nexus password--nexus_repo_name <name> - Repository name--nexus_group_id <group> - Maven group ID--nexus_artifact_id <artifact> - Maven artifact ID--nexus_version <version> - Application versionMaven Coordinates: The script uses standard Maven coordinates to locate artifacts:
group_id:artifact_id:versioncom.example:myapp:1.0.0Uploading to Nexus: See these gists for uploading apps to Nexus:
Example:
mdast_cli -d \
--distribution_system nexus \
--nexus_url https://nexus.example.com \
--nexus_login myuser \
--nexus_password mypass \
--nexus_repo_name releases \
--nexus_group_id com.example \
--nexus_artifact_id myapp \
--nexus_version 1.0.0
Download applications from Nexus Repository Manager 2.x.
Required Parameters:
--distribution_system nexus2--nexus2_url <url> - Nexus2 server URL--nexus2_login <username> - Nexus2 username--nexus2_password <password> - Nexus2 password--nexus2_repo_name <name> - Repository name--nexus2_group_id <group> - Maven group ID--nexus2_artifact_id <artifact> - Maven artifact ID--nexus2_version <version> - Application version--nexus2_extension <ext> - File extension (e.g., apk, ipa)Optional Parameters:
--nexus2_file_name <name> - Custom filenameExample:
mdast_cli -d \
--distribution_system nexus2 \
--nexus2_url http://nexus:8081/nexus/ \
--nexus2_login admin \
--nexus2_password admin123 \
--nexus2_repo_name releases \
--nexus2_group_id com.example \
--nexus2_artifact_id myapp \
--nexus2_version 1.337 \
--nexus2_extension apk \
--nexus2_file_name my_app
Download Android applications from RuStore (Russian app store).
Required Parameters:
--distribution_system rustore--rustore_package_name <package> - Package name (e.g., ru.example.app)Getting Package Name:
Example:
mdast_cli -d \
--distribution_system rustore \
--rustore_package_name ru.example.app
Download applications from Huawei AppGallery.
Required Parameters:
--distribution_system appgallery--appgallery_app_id <id> - Application ID from AppGalleryOptional Parameters:
--appgallery_file_name <name> - Custom filenameGetting App ID:
appgallery.huawei.com/app/{APP_ID}C101184875 → use C101184875Example:
mdast_cli -d \
--distribution_system appgallery \
--appgallery_app_id C123456789 \
--appgallery_file_name huawei_app
Download Android applications from RuMarket (Russian app store).
Required Parameters:
--distribution_system rumarket--rumarket_package_name <package> - Package nameExample:
mdast_cli -d \
--distribution_system rumarket \
--rumarket_package_name com.example.app
When --testcase_id is not specified:
Use Case: Quick security checks, initial assessments
Example:
mdast_cli \
--distribution_system file \
--file_path app.apk \
--url "https://saas.mobile.appsec.world" \
--company_id 1 \
--token "YOUR_TOKEN" \
--profile_id 1
# No --testcase_id = manual scan
When --testcase_id is specified:
Use Case: Deep security analysis, regression testing, CI/CD integration
Example:
mdast_cli \
--distribution_system file \
--file_path app.apk \
--url "https://saas.mobile.appsec.world" \
--company_id 1 \
--token "YOUR_TOKEN" \
--profile_id 1 \
--testcase_id 4 # Automated scan with testcase #4
Parameter: --architecture_id <id>
Select the target architecture/OS version for scanning:
Example:
mdast_cli ... --architecture_id 5 # Use architecture ID 5
Parameter: --profile_id <id> (optional)
Auto-create in Existing Project:
mdast_cli ... --project_id 10 # Create profile in project #10
Generate a structured JSON report with scan summary and statistics.
Parameter: --summary_report_json_file_name <filename>
Output Format:
Example:
mdast_cli \
--distribution_system file \
--file_path app.apk \
--url "https://saas.mobile.appsec.world" \
--company_id 1 \
--token "YOUR_TOKEN" \
--profile_id 1 \
--summary_report_json_file_name scan_results.json
Use Case: CI/CD integration, automated reporting, data analysis
Generate a detailed PDF report with full scan results.
Parameter: --pdf_report_file_name <filename>
Output Format:
Example:
mdast_cli \
--distribution_system file \
--file_path app.apk \
--url "https://saas.mobile.appsec.world" \
--company_id 1 \
--token "YOUR_TOKEN" \
--profile_id 1 \
--pdf_report_file_name detailed_report.pdf
Use Case: Compliance reporting, stakeholder presentations, documentation
Generate a CR (Change Request) report in HTML format.
Required Parameters (when --cr_report is set):
--cr_report - Enable CR report generation--stingray_login <login> - Stingray platform login--stingray_password <password> - Stingray platform passwordOptional Parameters:
--organization_name <name> - Organization name (default: "ООО Стингрей Технолоджиз")--engineer_name <name> - Engineer name--controller_name <name> - Controller name--use_ldap - Use LDAP authentication--authority_server_id <id> - Authority server ID--cr_report_path <path> - Output file path (default: stingray-CR-report.html)Example:
mdast_cli \
--distribution_system file \
--file_path app.apk \
--url "https://saas.mobile.appsec.world" \
--company_id 1 \
--token "YOUR_TOKEN" \
--profile_id 1337 \
--architecture_id 3 \
--cr_report \
--stingray_login user@example.com \
--stingray_password "password" \
--organization_name "My Company" \
--engineer_name "John Doe" \
--controller_name "Jane Smith" \
--cr_report_path custom-report.html
Use --nowait (or -nw) to start a scan and exit immediately without waiting for completion.
Use Case:
Example:
mdast_cli \
--distribution_system file \
--file_path app.apk \
--url "https://saas.mobile.appsec.world" \
--company_id 1 \
--token "YOUR_TOKEN" \
--profile_id 1 \
--nowait # Exit immediately after starting scan
Note: Reports will not be generated when using --nowait. Poll the API separately for results.
Use --long_wait to extend the maximum wait time to 1 week (instead of default timeout).
Use Case:
Example:
mdast_cli \
--distribution_system file \
--file_path app.apk \
--url "https://saas.mobile.appsec.world" \
--company_id 1 \
--token "YOUR_TOKEN" \
--profile_id 1 \
--testcase_id 4 \
--long_wait # Wait up to 1 week for completion
Use --appium_script_path to provide a custom Appium script for automated testing.
Parameter: --appium_script_path <path>
Use Case:
Example:
mdast_cli \
--distribution_system file \
--file_path app.apk \
--url "https://saas.mobile.appsec.world" \
--company_id 1 \
--token "YOUR_TOKEN" \
--profile_id 1 \
--appium_script_path /path/to/appium_script.py
Parameter: --download_path <path> (or -p <path>)
Specify where downloaded applications should be saved.
downloaded_apps/Example:
mdast_cli -d \
--distribution_system google_play \
--google_play_package_name com.example.app \
--google_play_email user@example.com \
--google_play_aas_token "TOKEN" \
--download_path /custom/path/to/apps
Problem: DF-DFERH-01 error or authentication failures
Solutions:
apkeep is installed and in PATH: apkeep --versionaas_et/)Problem: "Wrong Apple ID" or login failures
Solutions:
password2FA (e.g., P@ssword742877)Problem: Authentication or permission errors
Solutions:
cloud-platform scope enabledProblem: Downloads fail or time out
Solutions:
--google_play_proxy for Google Play if behind firewallProblem: Application file not found after download
Solutions:
--download_path directory permissions--help to see all available options-d flag to isolate download issuesThe script uses standardized exit codes for CI/CD integration:
| Code | Constant | Description |
|---|---|---|
| 0 | SUCCESS | Operation completed successfully |
| 1 | INVALID_ARGS | Invalid command-line arguments |
| 2 | AUTH_ERROR | Authentication failed |
| 3 | DOWNLOAD_FAILED | Application download failed |
| 4 | NETWORK_ERROR | Network/connection error |
| 5 | SCAN_FAILED | Scan execution or upload failed |
Example CI/CD Usage:
#!/bin/bash
mdast_cli --distribution_system file --file_path app.apk ...
EXIT_CODE=$?
if [ $EXIT_CODE -eq 0 ]; then
echo "Scan completed successfully"
elif [ $EXIT_CODE -eq 3 ]; then
echo "Download failed - check distribution system"
exit 1
else
echo "Scan failed with code $EXIT_CODE"
exit 1
fi
#!/bin/bash
set -e
# Download application
mdast_cli -d \
--distribution_system google_play \
--google_play_package_name com.example.app \
--google_play_email ci@example.com \
--google_play_aas_token "$GOOGLE_PLAY_AAS_TOKEN" \
--download_path ./artifacts
# Extract download path from output
DOWNLOAD_PATH=$(mdast_cli -d ... 2>&1 | grep "DOWNLOAD_PATH=" | cut -d'=' -f2)
# Run security scan
mdast_cli \
--distribution_system file \
--file_path "$DOWNLOAD_PATH" \
--url "$DAST_URL" \
--company_id "$COMPANY_ID" \
--token "$DAST_TOKEN" \
--profile_id "$PROFILE_ID" \
--testcase_id "$TESTCASE_ID" \
--summary_report_json_file_name ./reports/scan_results.json \
--pdf_report_file_name ./reports/scan_results.pdf
# Check results
if [ -f ./reports/scan_results.json ]; then
CRITICAL_COUNT=$(jq '.vulnerabilities.critical' ./reports/scan_results.json)
if [ "$CRITICAL_COUNT" -gt 0 ]; then
echo "Critical vulnerabilities found!"
exit 1
fi
fi
version: '3.8'
services:
mdast-scan:
image: mobilesecurity/mdast_cli:latest
volumes:
- ./apps:/mdast/files
- ./reports:/mdast/report
environment:
- DAST_URL=https://saas.mobile.appsec.world
- COMPANY_ID=1
- TOKEN=${DAST_TOKEN}
command:
- --distribution_system
- file
- --file_path
- /mdast/files/app.apk
- --url
- ${DAST_URL}
- --company_id
- ${COMPANY_ID}
- --token
- ${TOKEN}
- --profile_id
- "1"
- --summary_report_json_file_name
- /mdast/report/results.json
# Test multiple distribution systems
for DIST in google_play appstore firebase; do
echo "Testing $DIST..."
mdast_cli -d \
--distribution_system "$DIST" \
--download_path "./downloads/$DIST" \
# ... distribution-specific parameters
done
See LICENSE file for details.
For issues, questions, or contributions, please visit the GitHub repository or contact support.
Note: This documentation is maintained alongside the codebase. For the latest information, always refer to the version-specific documentation or the --help command output.
FAQs
Dynamic-Mobile-Security
We found that mdast-cli demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Deno 2.6 introduces deno audit with a new --socket flag that plugs directly into Socket to bring supply chain security checks into the Deno CLI.

Security News
New DoS and source code exposure bugs in React Server Components and Next.js: what’s affected and how to update safely.

Security News
Socket CEO Feross Aboukhadijeh joins Software Engineering Daily to discuss modern software supply chain attacks and rising AI-driven security risks.