sodcalculator

10 Tech How-To

Fix AWS Security Misconfigurations in Self-Hosted Apps

Guide 10-12159 · Updated · Step by step

This guide walks you through the most common AWS security misconfigurations that affect self-hosted applications—things like overly permissive S3 buckets, open security groups, and exposed IAM keys. You’ll learn how to identify each issue, apply the fix, and verify it, so your app stays secure without breaking functionality. No prior AWS security expertise is needed, but you should have console access to your AWS account and basic familiarity with the services you use.

What You’ll Need

  • AWS Management Console access with permissions to modify IAM, EC2, S3, and related services.
  • The AWS CLI installed and configured (optional but helpful for verification).
  • A list of your self-hosted app’s resources (EC2 instances, S3 buckets, IAM users, etc.).
  • A text editor to note changes and rollback plans.

Step-by-Step

  1. Audit S3 bucket permissions. Go to the S3 console, select each bucket used by your app, and check the “Permissions” tab. Look for public access (“Everyone” with read/write) or bucket policies that allow any principal. If you find public access, change the Block Public Access settings to block all public access, then remove any bucket policies that grant public access. For fine-grained control, use bucket policies that restrict access to specific IAM roles or IP ranges.
  2. Tighten security group rules. In the EC2 console, navigate to “Security Groups” and review the inbound rules for groups attached to your instances. Remove any rule that allows traffic from 0.0.0.0/0 on ports other than 80/443 (or your app’s required ports). For SSH (port 22), restrict the source to your office IP or a VPN. Apply the same logic to outbound rules—deny all by default and allow only necessary destinations.
  3. Rotate and restrict IAM credentials. List all IAM users and check for access keys that are older than 90 days. For each, create a new key, update your application to use it, then deactivate and delete the old key. Also, review IAM policies for overly broad permissions (e.g., “*” on all resources). Replace them with least-privilege policies that only allow the actions your app needs.
  4. Enable encryption on S3 and EBS. For each S3 bucket, go to the “Properties” tab and enable default encryption (SSE-S3 or SSE-KMS). For EC2 volumes, select the volume, choose “Actions” > “Modify Volume,” and enable EBS encryption. This protects data at rest without changing your app code.
  5. Check for exposed environment variables. If your app runs on EC2 or ECS, review your startup scripts, user data, and task definitions for hardcoded secrets like database passwords or API keys. Move them to AWS Secrets Manager or Parameter Store, and reference them in your app configuration.
  6. Review CloudTrail and enable logging. Ensure CloudTrail is enabled for your region and that logs are sent to S3. This gives you a record of API calls, which helps detect unauthorized access. Also, enable S3 server access logging for your buckets to track requests.
  7. Set up AWS Config rules (optional but recommended). Use AWS Config to continuously check for misconfigurations like public S3 buckets or unrestricted security groups. Create rules that trigger alerts when resources drift from your desired state.

Common Mistakes

  • Over-restricting and breaking the app: Removing all inbound rules or blocking all outbound traffic can make your app unreachable. Always test after changes.
  • Forgetting to update the app after rotating keys: If you deactivate an old key before updating your app, you’ll cause downtime. Always update the app first, then deactivate.
  • Only fixing one resource: You might fix a public S3 bucket but miss another bucket or an open security group. Do a full audit, not a one-off.
  • Ignoring IAM roles for EC2: Instead of using access keys on instances, use IAM roles. This is a common oversight that leaves keys lying around.

Tips

  • Use the AWS Trusted Advisor dashboard (or AWS Security Hub) to get a prioritized list of security issues.
  • Implement a tagging strategy to identify which resources belong to which app, making audits easier.
  • Set up billing alerts to detect unexpected usage that might indicate a compromised resource.
  • Schedule regular security reviews—quarterly is a good cadence.

Troubleshooting

App becomes unreachable after changing security groups: Check the security group’s inbound rules—you may have removed the rule for your app’s port. Re-add it with the correct port and source (e.g., 0.0.0.0/0 for a public web app). Also verify that the instance is in the correct subnet with a route to the internet gateway.

S3 bucket access denied for your app: If you blocked public access, your app’s IAM role or user must have explicit permissions to read/write the bucket. Update the bucket policy to allow the specific IAM principal, or attach a policy to the IAM role that grants s3:GetObject and s3:PutObject on that bucket.

CloudTrail logs are empty: Ensure you enabled CloudTrail in the correct region and that the S3 bucket for logs has the right bucket policy (CloudTrail’s service principal needs write access). Also, wait a few minutes for logs to appear.

IAM key rotation fails because the app still uses the old key: Search your codebase for the old access key ID and replace it with the new one. If you can’t find it, you may have hardcoded it in a config file that’s not in version control—check all servers and environment files.

Frequently Asked Questions

How do I know if my S3 bucket is publicly accessible?

In the S3 console, the “Permissions” tab shows “Public access” for the bucket. You can also use the AWS CLI: aws s3api get-bucket-acl --bucket your-bucket and look for grants to “AllUsers” or “AuthenticatedUsers”.

What’s the difference between a security group and a network ACL?

Security groups are stateful and act as a virtual firewall for instances; network ACLs are stateless and operate at the subnet level. For most self-hosted apps, you only need to manage security groups.

Should I use IAM roles or access keys on EC2?

Always use IAM roles. They are automatically rotated and eliminate the risk of keys being exposed in code or on disk. Access keys should be reserved for local development or CLI use.

How often should I rotate IAM access keys?

AWS recommends rotating keys every 90 days. If you have compliance requirements, you may need to do it more frequently.

Can I use AWS Config to automatically fix misconfigurations?

Yes, AWS Config supports remediation actions via Systems Manager Automation documents. For example, you can create a rule that automatically removes public access from S3 buckets.

What should I do if I suspect my account is compromised?

Immediately rotate all IAM credentials, delete any unauthorized resources, enable CloudTrail if not already, and review the root account activity. Contact AWS Support for assistance.

Related

General steps for current mainstream versions; menus can differ by device and version. See the disclaimer or report an error.

More in this bed

The whole Tech How-To bed →