@shinyaz

AWS Security Agent Verification — How Source Code Improves Detection Rate

Table of Contents

Introduction

In the previous article, we ran AWS Security Agent's penetration test with URL-only configuration and detected 4 out of 5 known vulnerabilities (0 false positives, cost ~$136). The only miss was Path Traversal — the /api/files/download endpoint had no links on any HTML page, so the CRAWLER likely never discovered it.

This article examines how providing source code changes detection outcomes. Security Agent offers two methods for supplying source code:

  • sourceCode — Upload as a ZIP archive to S3. The CLI description explicitly states "for static analysis"
  • documents — Upload to S3 or via artifacts. Described as "providing context for testing"

We ran an A/B comparison across three conditions — URL-only (previous article), documents, and sourceCode — to determine whether these two methods produce meaningfully different results. The source code was stripped of vulnerability markers (# VULN: comments etc.) to evaluate whether the AI can discover vulnerabilities purely through code structure analysis.

Prerequisites:

  • Reused the same environment from the previous article (Agent Space, EC2, Flask app)
  • Test regions: ap-northeast-1 (documents), us-east-1 (sourceCode)

Source Code Preparation

We used a clean version of the previous article's app.py with vulnerability-indicating comments (# VULN:, # --- Vulnerability N:, # No sanitization, etc.) and WARNING docstrings removed. This ensures the AI discovers vulnerabilities through code structure analysis rather than comment hints.

Registering Source Code

documents (Tokyo Region)

Upload source code to an S3 bucket and reference it via update-pentest's assets.documents. No ZIP required — raw files can be specified directly.

Steps to register documents

Reuse the variables created in the previous article: $ACCOUNT_ID, $REGION, $AGENT_SPACE_ID, $PENTEST_ID, $SERVICE_ROLE_ARN, $PRIVATE_DNS.

Terminal
S3_BUCKET="security-agent-pentest-source-${ACCOUNT_ID}"
 
# Create S3 bucket and upload
aws s3 mb s3://${S3_BUCKET} --region $REGION
aws s3 cp app-clean.py s3://${S3_BUCKET}/app.py
 
# Grant S3 read access to the service role
aws iam put-role-policy \
  --role-name SecurityAgentPentestRole \
  --policy-name SecurityAgentS3ReadAccess \
  --policy-document "{
    \"Version\": \"2012-10-17\",
    \"Statement\": [{
      \"Effect\": \"Allow\",
      \"Action\": [\"s3:GetObject\", \"s3:ListBucket\"],
      \"Resource\": [\"arn:aws:s3:::${S3_BUCKET}\", \"arn:aws:s3:::${S3_BUCKET}/*\"]
    }]
  }"
 
# Add S3 bucket to Agent Space (preserve existing vpcs and iamRoles, add s3Buckets)
aws securityagent update-agent-space \
  --agent-space-id $AGENT_SPACE_ID \
  --name "pentest-verification" \
  --aws-resources "{
    \"vpcs\": [{
      \"vpcArn\": \"$VPC_ID\",
      \"securityGroupArns\": [\"$SG_ID\"],
      \"subnetArns\": [\"$SUBNET_ID\"]
    }],
    \"iamRoles\": [\"$SERVICE_ROLE_ARN\"],
    \"s3Buckets\": [\"arn:aws:s3:::${S3_BUCKET}\"]
  }" \
  --target-domain-ids "$TARGET_DOMAIN_ID" \
  --region $REGION
 
# Register documents in the pentest
aws securityagent update-pentest \
  --pentest-id $PENTEST_ID \
  --agent-space-id $AGENT_SPACE_ID \
  --service-role $SERVICE_ROLE_ARN \
  --assets "{
    \"endpoints\": [{\"uri\": \"http://${PRIVATE_DNS}\"}],
    \"documents\": [{\"s3Location\": \"s3://${S3_BUCKET}/app.py\"}]
  }" --region $REGION

sourceCode (us-east-1)

Upload a ZIP archive to S3 and reference it via assets.sourceCode. Specifying a raw file triggers a "Source code S3 URL must point to a ZIP archive" error.

A notable caveat: two attempts to use sourceCode in the Tokyo region both failed with INTERNAL_ERROR during the Setup Testing Environment phase. S3 Source Access Validation passed successfully, confirming that source code retrieval itself was not the issue. Removing sourceCode from the same environment allowed tests to complete normally, pointing to sourceCode processing as the root cause. Since us-east-1 did not exhibit this error, sourceCode in the Tokyo region may be unstable as of April 2026.

Steps to register sourceCode (new environment in us-east-1)

Because sourceCode did not work in Tokyo, we built a new EC2 + Agent Space environment in us-east-1. The EC2 and Flask app deployment steps are the same as the previous article's "EC2 Deployment Steps" (just change the region to us-east-1). Below covers only the Security Agent-specific setup.

Terminal (us-east-1)
REGION=us-east-1
S3_BUCKET="security-agent-pentest-source-use1-${ACCOUNT_ID}"
 
# Create Agent Space
AGENT_SPACE_ID=$(aws securityagent create-agent-space \
  --name "pentest-verification-use1" \
  --region $REGION --query "agentSpaceId" --output text)
 
# Register and verify Target Domain (UNREACHABLE is OK — VPC Config handles connectivity)
TARGET_DOMAIN_ID=$(aws securityagent create-target-domain \
  --target-domain-name "$PRIVATE_DNS" \
  --verification-method HTTP_ROUTE \
  --region $REGION --query "targetDomainId" --output text)
aws securityagent verify-target-domain \
  --target-domain-id $TARGET_DOMAIN_ID --region $REGION
 
# Create S3 bucket and upload ZIP
aws s3 mb s3://${S3_BUCKET} --region $REGION
zip app-clean.zip app-clean.py
aws s3 cp app-clean.zip s3://${S3_BUCKET}/app.zip --region $REGION
 
# Grant S3 read and CloudWatch Logs access to the service role
# (IAM roles are global, but policies are added for us-east-1 resources)
aws iam put-role-policy --role-name SecurityAgentPentestRole \
  --policy-name SecurityAgentS3ReadAccessUSE1 \
  --policy-document "{...}"  # Specify S3 bucket ARN
aws iam put-role-policy --role-name SecurityAgentPentestRole \
  --policy-name SecurityAgentLogsAccessUSE1 \
  --policy-document "{...}"  # Specify /aws/securityagent/* in us-east-1
 
# Register VPC, IAM, S3, and Target Domain with Agent Space
aws securityagent update-agent-space \
  --agent-space-id $AGENT_SPACE_ID \
  --name "pentest-verification-use1" \
  --aws-resources "{
    \"vpcs\": [{\"vpcArn\": \"$VPC_ID\", \"securityGroupArns\": [\"$SG_ID\"], \"subnetArns\": [\"$SUBNET_ID\"]}],
    \"iamRoles\": [\"$SERVICE_ROLE_ARN\"],
    \"s3Buckets\": [\"arn:aws:s3:::${S3_BUCKET}\"]
  }" \
  --target-domain-ids "$TARGET_DOMAIN_ID" \
  --region $REGION
 
# Create pentest with sourceCode
PENTEST_ID=$(aws securityagent create-pentest \
  --title "vulnerable-flask-app-pentest-sourcecode" \
  --agent-space-id $AGENT_SPACE_ID \
  --service-role $SERVICE_ROLE_ARN \
  --assets "{
    \"endpoints\": [{\"uri\": \"http://${PRIVATE_DNS}\"}],
    \"sourceCode\": [{\"s3Location\": \"s3://${S3_BUCKET}/app.zip\"}]
  }" \
  --vpc-config "{
    \"vpcArn\": \"$VPC_ID\",
    \"securityGroupArns\": [\"$SG_ID\"],
    \"subnetArns\": [\"$SUBNET_ID\"]
  }" \
  --region $REGION --query "pentestId" --output text)
 
# Start the test
aws securityagent start-pentest-job \
  --pentest-id $PENTEST_ID \
  --agent-space-id $AGENT_SPACE_ID \
  --region $REGION

Results: documents (Tokyo Region)

Full test results:

#FindingconfidenceriskLevel
1SQL Injection in Login — Complete Auth BypassHIGHCRITICAL
2JWT Token Forgery — Missing Signature VerificationHIGHCRITICAL
3JWT + XSS Chain Attack — Stored XSS in Admin ContextHIGHCRITICAL
4Path Traversal in File Download — Arbitrary File ReadHIGHHIGH
5Complete Auth Bypass on File DownloadHIGHHIGH
6Unauthorized File Download — No Access ControlHIGHHIGH
7Arbitrary File Write via Path Traversal in UploadHIGHHIGH
8Unrestricted File Type UploadHIGHHIGH
9IDOR — Unauthorized User Profile AccessHIGHMEDIUM
10Stored XSS in CommentsHIGHMEDIUM
11SQLite Error Messages Expose DB StructureHIGHMEDIUM
12Server Crash on Upload to Non-Existent SubdirectoriesHIGHMEDIUM
13Internal Server Error on File Download Without ParamHIGHMEDIUM

13 findings, all with HIGH confidence. A 2.6x increase from the URL-only run (5 findings).

What changed compared to the URL-only run:

  • Path Traversal newly detected — Previously missed, but with source code context the agent discovered /api/files/download and reproduced arbitrary file reads via ../../etc/passwd. This brings detection to 5/5
  • Chain attack newly discovered — JWT token forgery combined with Stored XSS for admin-context exploitation (#3). This multi-step finding was absent from the URL-only run
  • File upload vulnerabilities newly discovered — Arbitrary file writes via Path Traversal (#7), missing file type restrictions (#8)
  • Error information leakage newly discovered — SQLite error messages exposing DB structure (#11), server errors on missing parameters (#13)
  • Previously detected vulnerabilities (SQLi, JWT, IDOR, XSS) remain detected. All confidence levels improved to HIGH (XSS was LOW in the URL-only run)

Results: sourceCode (us-east-1)

28 findings were reported (24 HIGH confidence, 4 FALSE_POSITIVE).

The presence of FALSE_POSITIVE findings is significant. The sourceCode CODE SCANNER flagged numerous candidates through static analysis, and the VALIDATOR TASK dynamically tested each one — ultimately classifying 4 as false positives. Neither documents nor the URL-only run produced any FALSE_POSITIVE results. This reflects the combination of broad static analysis coverage with precise dynamic validation.

Key findings (HIGH confidence, CRITICAL/HIGH only):

#FindingriskLevelCategory
1SQL Injection — Complete Auth BypassCRITICALVuln 1
2JWT Authentication Bypass — No Signature VerificationCRITICALVuln 4
3JWT Accepts Invalid Signature + Identity SpoofingCRITICALVuln 4 related
4JWT Temporal Claims Not ValidatedCRITICALVuln 4 related
5Multi-Stage Privilege Escalation ChainCRITICALChain attack
6MD5 Password Hashing Without SaltCRITICALUnexpected
7Missing Rate Limiting — Brute ForceCRITICALUnexpected
8Lack of Input Validation FrameworkCRITICALUnexpected
9Path Traversal in File DownloadHIGHVuln 5
10File Overwrite via Filename CollisionHIGHUnexpected
11Auth Bypass on File DownloadHIGHVuln 5 related
12Unrestricted File Upload with Path TraversalHIGHUnexpected
13JWT Token Validation Failures — Type ConfusionHIGHVuln 4 related
14Complete JWT Authentication BypassCRITICALVuln 4 related

Additional findings include 8 MEDIUM-severity items (XSS, IDOR, missing security headers, GDPR concerns, DB foreign key constraints, JWT null value handling) and 2 INFORMATIONAL items (Flask dev server settings, SQLite temp directory).

5/5 vulnerabilities detected. Beyond that, sourceCode reported issues that documents did not detect — MD5 hashing, missing rate limiting, absent input validation, JWT type confusion, and expired token acceptance. These were only reported by the CODE SCANNER's static analysis. Whether documents missed them due to the absence of static analysis or due to non-determinism in test execution cannot be determined from this verification alone.

Three-Way Comparison

Pipeline Differences Between documents and sourceCode

Internal task comparison observed during testing:

Phasedocuments (Tokyo)sourceCode (us-east-1)
PREFLIGHTS3 Source Access Validation, Setup Testing EnvS3 Source Access Validation, Setup Testing Env
STATIC_ANALYSISDOCUMENTS, SCANNER, TLS SCANNER, CRAWLERCODE SCANNER [BUSINESS LOGIC / IMPORTANT FLOWS / FRAMEWORKS], SCANNER, TLS SCANNER, CRAWLER
PENTEST13 attack categories + VALIDATOR13 attack categories + VALIDATOR

The critical difference is in the STATIC_ANALYSIS phase:

  • documents: A DOCUMENTS task processes the source code, followed by the standard CRAWLER. The source code serves as contextual information for the AI agent, and findings are only reported during the dynamic attacks in the PENTEST phase
  • sourceCode: Three CODE SCANNER tasks (BUSINESS LOGIC, IMPORTANT FLOWS, FRAMEWORKS) run in parallel for systematic static analysis, detecting vulnerabilities before PENTEST even begins. A VALIDATOR TASK dynamically reproduces findings, then proceeds to CRAWLER and PENTEST

Detection Comparison

MetricURL-only (prev.)documents (Tokyo)sourceCode (us-east-1)
Findings51328
HIGH confidence41324
FALSE_POSITIVE004
Planted vulns4/55/55/5
Path TraversalNoYesYes
Chain attacksNoYes (JWT+XSS)Yes (Multi-Stage Escalation)
Static analysis findingsNoneNoneYes (pre-PENTEST detection)
JWT-related findings126
Code quality findingsNoneNoneYes (MD5, rate limiting, CSRF, security headers, etc.)

Summary

Providing source code dramatically improves detection rates. URL-only produced 5 findings with 4/5 detection; documents jumped to 13 findings with 5/5 detection; sourceCode reached 28 findings with 5/5 detection. The sourceCode method is particularly notable for its CODE SCANNER, which performs systematic static analysis and reported code-quality vulnerabilities (MD5 hashing, missing rate limiting, absent input validation) that were not detected by the other two methods.

AspectURL-onlydocumentssourceCode
Setup effortNoneS3 upload + update-pentest (minutes)S3 ZIP upload + update-pentest (minutes)
Finding count513 (2.6x)28 (5.6x)
Processing pipelineCRAWLER, PENTESTDOCUMENTS, CRAWLER, PENTESTCODE SCANNER x3, CRAWLER, PENTEST
Static analysisNoneNoneBUSINESS LOGIC / IMPORTANT FLOWS / FRAMEWORKS
Tokyo regionYesYesNo (INTERNAL_ERROR)
  • In this verification, source code provision increased findings by 2.6-5.6x — Detection of endpoints with no HTML links (API endpoints, etc.) improved significantly. Source code registration takes only a few minutes, making it a high cost-effectiveness option
  • Choose sourceCode when available — The CODE SCANNER's static analysis offers unique value absent from documents. Code quality findings (MD5, rate limiting, security headers) make it practical as a security review tool
  • Fall back to documents in the Tokyo regionsourceCode hit INTERNAL_ERROR in Tokyo as of April 2026. documents still achieved 5/5 detection in this verification and is perfectly viable
  • FALSE_POSITIVE only occurs with sourceCode — Broader static analysis naturally produces candidates that cannot be dynamically reproduced. The VALIDATOR TASK automatically flags false positives, so no manual triage is needed

Cleanup

Resource deletion
Terminal
# Tokyo region
aws s3 rb s3://security-agent-pentest-source-${ACCOUNT_ID} --force --region ap-northeast-1
aws iam delete-role-policy --role-name SecurityAgentPentestRole \
  --policy-name SecurityAgentS3ReadAccess 2>/dev/null
 
# us-east-1
aws securityagent batch-delete-pentests \
  --agent-space-id $AGENT_SPACE_ID_USE1 \
  --pentest-ids $PENTEST_ID_USE1 --region us-east-1
aws securityagent delete-target-domain \
  --target-domain-id $TARGET_DOMAIN_ID_USE1 --region us-east-1
aws securityagent delete-agent-space \
  --agent-space-id $AGENT_SPACE_ID_USE1 --region us-east-1
aws ec2 terminate-instances --instance-ids $INSTANCE_ID_USE1 --region us-east-1
aws ec2 delete-security-group --group-id $SG_ID_USE1 --region us-east-1
aws s3 rb s3://security-agent-pentest-source-use1-${ACCOUNT_ID} --force --region us-east-1
aws iam delete-role-policy --role-name SecurityAgentPentestRole \
  --policy-name SecurityAgentS3ReadAccessUSE1 2>/dev/null
aws iam delete-role-policy --role-name SecurityAgentPentestRole \
  --policy-name SecurityAgentLogsAccessUSE1 2>/dev/null
aws securityagent delete-application --application-id $APP_ID_USE1 --region us-east-1

Share this post

Shinya Tahara

Shinya Tahara

Solutions Architect @ AWS

I'm a Solutions Architect at AWS, providing technical guidance primarily to financial industry customers. I share learnings about cloud architecture and AI/ML on this site.The views and opinions expressed on this site are my own and do not represent the official positions of my employer.

Related Posts