Unauthorized access to files - S3 Bucket - Java

Unauthorized access to files - S3 Bucket - Java

Need

Secure access control for S3 buckets

Context

  • Usage of Java 8 for developing applications with enhanced features and performance improvements
  • Usage of AWS Java SDK for S3 operations

Description

Non compliant code

        import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;

public class S3BucketAccess {
    private static final String BUCKET_NAME = "bucket-name";

    public static void main(String[] args) {
        final AmazonS3 s3 = AmazonS3ClientBuilder.defaultClient();
        s3.putObject(BUCKET_NAME, "key-name", "file-content");
    }
}
        
        

This code snippet represents a Java backend application that uses the Amazon S3 service to store files. The AmazonS3ClientBuilder is used to create a client that connects to the S3 service.

The main method uses this client to put an object, in this case a file, into a specified S3 bucket. The putObject method takes three parameters: the name of the bucket, the key under which to store the new object, and the content of the object.

The vulnerability in this code exists because the S3 bucket is publicly accessible. This means that anyone who knows the bucket's name and the key under which an object is stored can access, modify, or delete that object. This is a serious security risk because it allows unauthorized users to manipulate the application's data.

The vulnerability could be exploited by an attacker who guesses or obtains the bucket name and object keys. They could then use the Amazon S3 API to access the objects in the bucket, modify their content, or delete them. The attacker could also upload malicious files to the bucket, which could be executed if they are downloaded and run by the application or its users.

The application does not require any authentication to access the S3 bucket. This is a violation of the principle of least privilege, which states that a user should only have the permissions necessary to perform their tasks. By granting public access to the bucket, the application is giving all users, including potential attackers, more permissions than they need.

Steps

  • Implement proper access control mechanisms to restrict public access to S3 buckets.
  • Use authentication and authorization mechanisms to ensure that only authorized users can access the S3 buckets.
  • Configure the S3 bucket policies to deny public access by default.
  • Regularly review and audit the S3 bucket permissions to identify and remove any unintended public access.
  • Encrypt sensitive data stored in S3 buckets to protect it from unauthorized access.
  • Implement logging and monitoring mechanisms to detect and respond to any unauthorized access attempts.

Compliant code

        import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.s3.model.BucketPolicy;
import com.amazonaws.services.s3.model.CannedAccessControlList;

public class S3BucketAccess {
    private static final String BUCKET_NAME = "bucket-name";

    public static void main(String[] args) {
        final AmazonS3 s3 = AmazonS3ClientBuilder.defaultClient();

        // Set the bucket policy to deny public access
        String bucketPolicy = "{\\n" +
                "    \\"Version\\": \\"2012-10-17\\",\\n" +
                "    \\"Statement\\": [\\n" +
                "        {\\n" +
                "            \\"Sid\\": \\"AddPerm\\",\\n" +
                "            \\"Effect\\": \\"Deny\\",\\n" +
                "            \\"Principal\\": \\"*\\",\\n" +
                "            \\"Action\\": \\"s3:*\\",\\n" +
                "            \\"Resource\\": \\"arn:aws:s3:::" + BUCKET_NAME + "/*\\"\\n" +
                "        }\\n" +
                "    ]\\n" +
                "}";
        s3.setBucketPolicy(BUCKET_NAME, bucketPolicy);

        // Set the access control list to private
        s3.setBucketAcl(BUCKET_NAME, CannedAccessControlList.Private);

        // Put the object in the bucket
        s3.putObject(BUCKET_NAME, "key-name", "file-content");
    }
}
        
        

The updated code now includes proper access control mechanisms to restrict public access to the S3 bucket.

Firstly, a bucket policy is set to deny all actions ( s3:*) from all principals ( *), effectively denying public access to the bucket. This policy is set using the setBucketPolicy method of the AmazonS3 client.

Secondly, the access control list (ACL) of the bucket is set to private using the setBucketAcl method and the CannedAccessControlList.Private enum. This ensures that only the AWS account that created the bucket can access it.

Finally, the object is put in the bucket as before. However, due to the updated bucket policy and ACL, this object cannot be accessed publicly.

Remember to regularly review and audit the S3 bucket permissions to identify and remove any unintended public access. Also, consider encrypting sensitive data stored in S3 buckets to further protect it from unauthorized access. Implement logging and monitoring mechanisms to detect and respond to any unauthorized access attempts.

References