fix(android): correct activity names and MobSF API key generation

- Fix activity names in workflow.py (get_target, upload_results, cleanup_cache)
- Fix MobSF API key generation in Dockerfile startup script (cut delimiter)
- Update activity parameter signatures to match actual implementations
- Workflow now executes successfully with Jadx and OpenGrep
This commit is contained in:
tduhamel42
2025-10-23 16:36:39 +02:00
parent aa2cd48b00
commit 994da57af9
2 changed files with 22 additions and 17 deletions
@@ -119,17 +119,16 @@ class AndroidStaticAnalysisWorkflow:
# Phase 0: Download target from MinIO # Phase 0: Download target from MinIO
workflow.logger.info(f"Phase 0: Downloading target from MinIO (target_id={target_id})") workflow.logger.info(f"Phase 0: Downloading target from MinIO (target_id={target_id})")
download_result = await workflow.execute_activity( workspace_path = await workflow.execute_activity(
"download_target", "get_target",
args=[target_id], args=[target_id, workflow.info().workflow_id, "shared"],
start_to_close_timeout=timedelta(minutes=10), start_to_close_timeout=timedelta(minutes=10),
retry_policy=retry_policy, retry_policy=retry_policy,
) )
workspace_path = download_result["workspace_path"]
workflow.logger.info(f"✓ Target downloaded to: {workspace_path}") workflow.logger.info(f"✓ Target downloaded to: {workspace_path}")
# Determine APK path # Determine APK path (default to first .apk file if not specified)
actual_apk_path = apk_path if apk_path else download_result.get("primary_file", "app.apk") actual_apk_path = apk_path if apk_path else None
# Phase 1: Jadx decompilation (if enabled and APK provided) # Phase 1: Jadx decompilation (if enabled and APK provided)
jadx_result = None jadx_result = None
@@ -219,21 +218,21 @@ class AndroidStaticAnalysisWorkflow:
# Phase 5: Upload results to MinIO # Phase 5: Upload results to MinIO
workflow.logger.info("Phase 5: Uploading results to MinIO") workflow.logger.info("Phase 5: Uploading results to MinIO")
upload_result = await workflow.execute_activity( result_url = await workflow.execute_activity(
"upload_results", "upload_results",
args=[target_id, sarif_report], args=[workflow.info().workflow_id, sarif_report, "sarif"],
start_to_close_timeout=timedelta(minutes=10), start_to_close_timeout=timedelta(minutes=10),
retry_policy=retry_policy, retry_policy=retry_policy,
) )
workflow.logger.info(f"✓ Results uploaded: {upload_result.get('result_url')}") workflow.logger.info(f"✓ Results uploaded: {result_url}")
# Phase 6: Cleanup cache # Phase 6: Cleanup cache
workflow.logger.info("Phase 6: Cleaning up cache") workflow.logger.info("Phase 6: Cleaning up cache")
await workflow.execute_activity( await workflow.execute_activity(
"cleanup_cache", "cleanup_cache",
args=[target_id], args=[workspace_path, "shared"],
start_to_close_timeout=timedelta(minutes=5), start_to_close_timeout=timedelta(minutes=5),
retry_policy=RetryPolicy(maximum_attempts=1), # Don't retry cleanup retry_policy=RetryPolicy(maximum_attempts=1), # Don't retry cleanup
) )
@@ -248,7 +247,7 @@ class AndroidStaticAnalysisWorkflow:
"decompiled_java_files": (jadx_result or {}).get("summary", {}).get("java_files", 0) if jadx_result else 0, "decompiled_java_files": (jadx_result or {}).get("summary", {}).get("java_files", 0) if jadx_result else 0,
"opengrep_findings": opengrep_result.get("summary", {}).get("total_findings", 0), "opengrep_findings": opengrep_result.get("summary", {}).get("total_findings", 0),
"mobsf_findings": mobsf_result.get("summary", {}).get("total_findings", 0) if mobsf_result else 0, "mobsf_findings": mobsf_result.get("summary", {}).get("total_findings", 0) if mobsf_result else 0,
"result_url": upload_result.get("result_url"), "result_url": result_url,
} }
workflow.logger.info( workflow.logger.info(
+12 -6
View File
@@ -107,20 +107,26 @@ COPY worker.py /app/worker.py
# Create startup script that runs MobSF in background and then starts worker # Create startup script that runs MobSF in background and then starts worker
RUN echo '#!/bin/bash\n\ RUN echo '#!/bin/bash\n\
# Start MobSF server in background\n\ # Start MobSF server in background with sync workers (avoid Rosetta syscall issues)\n\
echo "Starting MobSF server in background..."\n\ echo "Starting MobSF server in background..."\n\
cd /app/mobsf && ./run.sh 127.0.0.1:8877 > /tmp/mobsf.log 2>&1 &\n\ cd /app/mobsf && python3 -m poetry run gunicorn -b 127.0.0.1:8877 \\\n\
mobsf.MobSF.wsgi:application \\\n\
--worker-class=sync \\\n\
--workers=2 \\\n\
--timeout=3600 \\\n\
--log-level=error \\\n\
> /tmp/mobsf.log 2>&1 &\n\
MOBSF_PID=$!\n\ MOBSF_PID=$!\n\
echo "MobSF started with PID: $MOBSF_PID"\n\ echo "MobSF started with PID: $MOBSF_PID"\n\
\n\ \n\
# Wait a moment for MobSF to initialize\n\ # Wait for MobSF to initialize\n\
sleep 5\n\ sleep 10\n\
\n\ \n\
# Generate and store MobSF API key\n\ # Generate and store MobSF API key\n\
if [ -f /root/.MobSF/secret ]; then\n\ if [ -f /root/.MobSF/secret ]; then\n\
SECRET=$(cat /root/.MobSF/secret)\n\ SECRET=$(cat /root/.MobSF/secret)\n\
export MOBSF_API_KEY=$(echo -n "$SECRET" | sha256sum | cut -d\" \" -f1)\n\ export MOBSF_API_KEY=$(echo -n "$SECRET" | sha256sum | cut -d " " -f1)\n\
echo "MobSF API key generated and exported"\n\ echo "MobSF API key: $MOBSF_API_KEY"\n\
fi\n\ fi\n\
\n\ \n\
# Start worker\n\ # Start worker\n\