How Helpful and Secure can AI be? A Little Comparison of ChatGPT and Amazon Q Developer
Every now and then there are these small tasks that end up on my table that are too tedious to write from scratch but there is too much overhead to delegate. So naturally I ask AI for help and hope to get it done in a manner of minutes instead of manually writing the required code. Since I mostly do infra stuff, the code in this case is Terraform. The task is quite simple: Create terraform code with an IAM user with permissions to upload to an S3 bucket. Create an S3 bucket using KMS encryption and the corresponding KMS Key. ChatGPT Response and Analysis Since its launch some time ago, ChatGPT earned its place on the bookmark bar in my browser. Just thanks to muscle memory it tends to be the tool of choice for similar tasks. And mostly it also does the job right, however this time I was a bit disappointed. provider "aws" { region = "us-east-1" # Specify the AWS region of your choice } # Create an S3 bucket with KMS encryption resource "aws_s3_bucket" "example_bucket" { bucket = "example-bucket-with-kms-encryption" # Change to your desired bucket name server_side_encryption_configuration { rule { apply_server_side_encryption_by_default { sse_algorithm = "aws:kms" kms_master_key_id = aws_kms_key.s3_bucket_key.arn } } } } # Create the KMS key for S3 bucket encryption resource "aws_kms_key" "s3_bucket_key" { description = "KMS key for S3 bucket encryption" deletion_window_in_days = 30 enable_key_rotation = true policy =

Every now and then there are these small tasks that end up on my table that are too tedious to write from scratch but there is too much overhead to delegate. So naturally I ask AI for help and hope to get it done in a manner of minutes instead of manually writing the required code. Since I mostly do infra stuff, the code in this case is Terraform.
The task is quite simple:
Create terraform code with an IAM user with permissions to upload to an S3 bucket. Create an S3 bucket using KMS encryption and the corresponding KMS Key.
ChatGPT Response and Analysis
Since its launch some time ago, ChatGPT earned its place on the bookmark bar in my browser. Just thanks to muscle memory it tends to be the tool of choice for similar tasks. And mostly it also does the job right, however this time I was a bit disappointed.
provider "aws" {
region = "us-east-1" # Specify the AWS region of your choice
}
# Create an S3 bucket with KMS encryption
resource "aws_s3_bucket" "example_bucket" {
bucket = "example-bucket-with-kms-encryption" # Change to your desired bucket name
server_side_encryption_configuration {
rule {
apply_server_side_encryption_by_default {
sse_algorithm = "aws:kms"
kms_master_key_id = aws_kms_key.s3_bucket_key.arn
}
}
}
}
# Create the KMS key for S3 bucket encryption
resource "aws_kms_key" "s3_bucket_key" {
description = "KMS key for S3 bucket encryption"
deletion_window_in_days = 30
enable_key_rotation = true
policy = <
Let's dissect this step by step.
Deprecated Code
The aws_s3_bucket_server_side_encryption_configuration
argument in the s3 bucket resource definition is deprecated and should be replaced by a separate resource.. Doesn't break anything, perhaps the model in the backend is outdated, but nothing major.
Potential Ransomware Attack
Here comes the interesting part. The actual KMS key policy and its statements.
{
"Sid": "Enable IAM User Permissions",
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": "kms:*",
"Resource": "*"
}
Thank you ChatGPT, you've just enabled any principal in any AWS account to do anything with my KMS key, including updating its key policy. That could lead to a potential ransomware attack where the attacker could make the key defunct and allow only himself to fix the key policy and thus release your data.
Wrong and Unnecessary Statement in the Key Policy
{
"Sid": "Allow S3 to use the key",
"Effect": "Allow",
"Principal": {
"Service": "s3.amazonaws.com"
},
"Action": [
"kms:Encrypt",
"kms:Decrypt",
"kms:ReEncrypt*",
"kms:GenerateDataKey*",
"kms:DescribeKey"
],
"Resource": "*",
"Condition": {
"StringEquals": {
"kms:EncryptionContext:aws:s3:arn": "${aws_s3_bucket.example_bucket.arn}"
}
}
This is not wrong per se, it just doesn't work like this. What ChatGPT wanted to achieve is to allow the key to be used only within a certain encryption context, meaning the KMS key can only be used for the given S3 bucket. This wasn't requested in the prompt. Furthermore, the S3 service itself doesn't really need the given permissions, the principal (e.g. an IAM user) does. Perhaps what ChatGPT wanted to do was to use the kms:ViaService condition to allow usage of the key only when when S3 in involved.
Insufficient Permissions
{
Effect = "Allow",
Action = [
"s3:PutObject",
"s3:PutObjectAcl"
],
Resource = "${aws_s3_bucket.example_bucket.arn}/*"
}
Lastly, the permissions given to the user are not sufficient to successfully upload files to the S3 bucket because there are no explicit Allow
s in the user's IAM policy or in the KMS key policy.
Result
Result? Not only the code doesn't do what it's supposed to, it also opens the door into my AWS account and possibly exposes my data to attackers. There are some safety measures to alert you about this even if such code gets deployed, such as AWS IAM Access Analyzer, provided it's configured correctly and the alerting works.
Amazon Q Developer Response and Analysis
The installation of Amazon Q Developer into your IDE is ridiculously quick and easy and requires just a Builder ID. Installing the Amazon Q Developer VS Code Extension and logging in with the Builder ID took less than 5 minutes. Upon clicking on the Q logo in VS Code a chat window opens and lets you input your prompts.
Now let's check the code provided by the Amazon Q Developer.
Compared to ChatGPT, Q spat out a clean code with no deprecated parameters and included a few interesting pieces where it's obvious that it follows the AWS best practices also in terms of security.
To improve readability I'm not including the code provided by the Q Developer, just the interesting bits.
Versioning Enabled
Versioning is enabled on the S3 bucket allowing you to restore accidentally deleted or overwritten data.
resource "aws_s3_bucket_versioning" "bucket_versioning" {
bucket = aws_s3_bucket.encrypted_bucket.id
versioning_configuration {
status = "Enabled"
}
}
Public Access Blocked Preemptively
Public access is explicitly blocked on the bucket preventing you from accidentally exposing your data.
resource "aws_s3_bucket_public_access_block" "bucket_public_access_block" {
bucket = aws_s3_bucket.encrypted_bucket.id
block_public_acls = true
block_public_policy = true
ignore_public_acls = true
restrict_public_buckets = true
}
Working KMS and IAM Policies
Using a default KMS key policy allows usage of the key only within the AWS account:
{
Sid = "Enable IAM User Permissions"
Effect = "Allow"
Principal = {
AWS = "arn:aws:iam::${data.aws_caller_identity.current.account_id}:root"
}
Action = "kms:*"
Resource = "*"
}
The IAM permissions for the user allow him to encrypt uploaded data with the KMS key.
{
Sid = "AllowKMSAccess"
Effect = "Allow"
Action = [
"kms:Decrypt",
"kms:GenerateDataKey"
]
Resource = [
aws_kms_key.s3_key.arn
]
}
Result
I'm quite happy with the results and especially with the nice to have features and quirks such as public access block which is not really necessary at this stage but is a good safeguard measure if the bucket policy gets updated later.
Conclusion
Humans are creatures of habit. Sometimes it's a good idea to reevaluate your habits and try something new especially in the fast-paced industry that IT is. Amazon Q Developer convinced me of it. An even more important message: make sure you understand every single line of code before deploying.