Category: CONTAINERS
AWS App Runner deploys containerized web apps and APIs from source code or container images. Security risks include environment variable exposure, IAM role abuse, and source code theft.
| Risk Level | Scope | Source | Compute |
|---|---|---|---|
| MEDIUM | Regional | ECR/GitHub | Auto-Scale |
Connects to GitHub repositories for automatic builds and deployments. Stores GitHub connection credentials. Build logs may contain sensitive information.
Attack note: GitHub connection ARN can be enumerated to understand repository access. Build commands may expose secrets.
Pulls images from ECR (public or private). Auto-deploys on image push. Service runs with instance role that can access other AWS services.
Attack note: Instance role often overly permissive. Container environment variables may contain database credentials.
███████░░░ 6.5/10 (HIGH)
App Runner simplifies deployment but abstracts security controls. Environment variables, IAM roles, and source code connections are common attack vectors for credential theft and lateral movement.
- Environment variables with secrets
- Build logs exposing credentials
- GitHub token from connection
- Instance role credential theft
- ECR credentials in service config
- Application vulnerability exploitation
- SSRF to metadata service
- Container escape attempts
- Auto-deploy hijacking
- Source code repository poisoning
- Instance role with AdministratorAccess
- Access role allowing all ECR repos
- No condition keys on IAM policies
- Cross-account role trust too broad
- Missing VPC egress controls
- Secrets in plain environment variables
- Public endpoint without WAF
- No VPC connector configured
- Observability logs exposing data
- Auto-scaling allows resource abuse
List Services
aws apprunner list-servicesDescribe Service
aws apprunner describe-service \\
--service-arn SERVICE_ARNList Connections
aws apprunner list-connectionsList Auto Scaling Configs
aws apprunner list-auto-scaling-configurationsList VPC Connectors
aws apprunner list-vpc-connectors- SSRF to 169.254.170.2 for task credentials
- Instance role → S3/DynamoDB access
- Instance role → Secrets Manager
- ECR access role → Pull other images
- VPC connector → Internal resources
- App vuln → SSRF → Instance role creds
- Build logs → GitHub token → Repo access
- Env vars → DB creds → Data access
- VPC connector → Private subnet resources
- Auto-deploy → Code injection → RCE
- Environment variables
- Build output logs
- Application logs
- Container filesystem
- Connected GitHub repos
- DATABASE_URL with credentials
- API_KEY for third-party services
- AWS_ACCESS_KEY_ID (anti-pattern)
- JWT_SECRET for authentication
- GITHUB_TOKEN for integrations
- CreateService - new service
- UpdateService - config changes
- DescribeService - recon activity
- ListConnections - enum connections
- AssociateCustomDomain - domain changes
- Unusual outbound connections
- Metadata service access patterns
- Failed authentication attempts
- Unexpected deployments
- Environment variable changes
Get Service Details (includes env vars)
aws apprunner describe-service \\
--service-arn SERVICE_ARN \\
--query 'Service.SourceConfiguration'Get Connection Details
aws apprunner describe-custom-domains \\
--service-arn SERVICE_ARNList Operations (deployment history)
aws apprunner list-operations \\
--service-arn SERVICE_ARNSSRF to Get Task Role (from app)
curl http://169.254.170.2$AWS_CONTAINER_CREDENTIALS_RELATIVE_URIGet Build Logs
aws logs get-log-events \\
--log-group-name /aws/apprunner/SERVICE/BUILDGet Application Logs
aws logs get-log-events \\
--log-group-name /aws/apprunner/SERVICE/application{
"Effect": "Allow",
"Action": "apprunner:*",
"Resource": "*"
}Full App Runner access - can create/modify services and view secrets
{
"Effect": "Allow",
"Action": [
"apprunner:DescribeService",
"apprunner:ListServices"
],
"Resource": "arn:aws:apprunner:*:*:service/prod-*"
}Only describe specific services matching pattern
{
"Effect": "Allow",
"Action": [
"s3:*",
"dynamodb:*",
"secretsmanager:*"
],
"Resource": "*"
}Instance role with broad access - SSRF leads to full compromise
{
"Effect": "Allow",
"Action": [
"s3:GetObject"
],
"Resource": "arn:aws:s3:::app-assets/*",
"Condition": {
"StringEquals": {"aws:SourceVpc": "vpc-xxx"}
}
}Instance role limited to specific bucket with VPC condition
Store secrets in Secrets Manager instead of environment variables.
aws secretsmanager create-secret --name app/database --secret-string ...Apply least privilege to instance role. Only grant required permissions.
Use VPC connector to restrict network access and enable private connectivity.
Associate WAF WebACL with App Runner service for application-layer protection.
Enable tracing and logging but ensure no secrets in log output.
Audit build logs for credential exposure. Use secrets in build environment.
AWS App Runner Security Card
Always obtain proper authorization before testing
