Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add initial typescript aws-cdk checks #1629

Merged
merged 4 commits into from
Nov 29, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 54 additions & 0 deletions typescript/aws-cdk/security/audit/awscdk-bucket-encryption.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import * as s3 from '@aws-cdk/aws-s3';
import * as cdk from '@aws-cdk/core';
import * as renamed_s3 from '@aws-cdk/aws-s3';
import {Bucket, BucketEncryption} from '@aws-cdk/aws-s3';

export class CdkStarterStack extends cdk.Stack {
constructor(scope: cdk.App, id: string, props?: cdk.StackProps) {
super(scope, id, props);

// ok:awscdk-bucket-encryption
const goodBucket = new s3.Bucket(this, 's3-bucket', {
encryption: s3.BucketEncryption.S3_MANAGED
})
// ruleid:awscdk-bucket-encryption
const badBucket = new s3.Bucket(this, 's3-bucket-bad')
// ok:awscdk-bucket-encryption
const AnotherGoodBucket = new s3.Bucket(this, 's3-bucket', {
encryption: s3.BucketEncryption.KMS_MANAGED
})
// ruleid:awscdk-bucket-encryption
const badBucket2 = new s3.Bucket(this, 's3-bucket-bad',{
encryption: s3.BucketEncryption.UNMANAGED
})
// ok:awscdk-bucket-encryption
const goodBucketRenamed = new renamed_s3.Bucket(this, 's3-bucket', {
encryption: renamed_s3.BucketEncryption.S3_MANAGED
})
// ruleid:awscdk-bucket-encryption
const badBucketRenamed = new renamed_s3.Bucket(this, 's3-bucket-bad')
// ok:awscdk-bucket-encryption
const AnotherGoodBucketRenamed = new renamed_s3.Bucket(this, 's3-bucket', {
encryption: renamed_s3.BucketEncryption.KMS_MANAGED
})
// ruleid:awscdk-bucket-encryption
const badBucket2Renamed = new renamed_s3.Bucket(this, 's3-bucket-bad',{
encryption: renamed_s3.BucketEncryption.UNMANAGED
})
// ok:awscdk-bucket-encryption
const goodBucketDirect = new Bucket(this, 's3-bucket', {
encryption: BucketEncryption.S3_MANAGED
})

// ruleid:awscdk-bucket-encryption
const badBucketDirect = new Bucket(this, 's3-bucket-bad')
// ok:awscdk-bucket-encryption
const AnotherGoodBucketDirect = new Bucket(this, 's3-bucket', {
encryption: BucketEncryption.KMS_MANAGED
})
// ruleid:awscdk-bucket-encryption
const badBucket2Direct = new Bucket(this, 's3-bucket-bad',{
encryption: BucketEncryption.UNMANAGED
})
}
}
36 changes: 36 additions & 0 deletions typescript/aws-cdk/security/audit/awscdk-bucket-encryption.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
rules:
- id: awscdk-bucket-encryption
pattern-either:
- patterns:
- pattern-inside: |
import {Bucket} from '@aws-cdk/aws-s3'
...
- pattern: const $X = new Bucket(...)
- pattern-not: |
const $X = new Bucket(..., {..., encryption: BucketEncryption.KMS_MANAGED, ...})
- pattern-not: |
const $X = new Bucket(..., {..., encryption: BucketEncryption.KMS, ...})
- pattern-not: |
const $X = new Bucket(..., {..., encryption: BucketEncryption.S3_MANAGED, ...})
- patterns:
- pattern-inside: |
import * as $Y from '@aws-cdk/aws-s3'
...
- pattern: const $X = new $Y.Bucket(...)
- pattern-not: |
const $X = new $Y.Bucket(..., {..., encryption: $Y.BucketEncryption.KMS_MANAGED, ...})
- pattern-not: |
const $X = new $Y.Bucket(..., {..., encryption: $Y.BucketEncryption.KMS, ...})
- pattern-not: |
const $X = new $Y.Bucket(..., {..., encryption: $Y.BucketEncryption.S3_MANAGED, ...})
message: >-
Add "encryption: $Y.BucketEncryption.KMS_MANAGED" or "encryption: $Y.BucketEncryption.S3_MANAGED" to the bucket props
for Bucket construct $X
languages: [typescript]
severity: ERROR
metadata:
category: security
technology:
- AWS-CDK
references:
- https://docs.aws.amazon.com/AmazonS3/latest/userguide/security-best-practices.html
42 changes: 42 additions & 0 deletions typescript/aws-cdk/security/audit/awscdk-bucket-enforcessl.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import * as s3 from '@aws-cdk/aws-s3';
import * as cdk from '@aws-cdk/core';
import * as rename_s3 from '@aws-cdk/aws-s3';
import {Bucket} from '@aws-cdk/aws-s3';

export class CdkStarterStack extends cdk.Stack {
constructor(scope: cdk.App, id: string, props?: cdk.StackProps) {
super(scope, id, props);

// ruleid:aws-cdk-bucket-enforcessl
const badBucket = new s3.Bucket(this, 's3-bucket-bad')
// ok:aws-cdk-bucket-enforcessl
const AnotherGoodBucket = new s3.Bucket(this, 's3-bucket', {
enforceSSL: true
})
// ruleid:aws-cdk-bucket-enforcessl
const badBucket2 = new s3.Bucket(this, 's3-bucket-bad', {
enforceSSL: false
})
// ruleid:aws-cdk-bucket-enforcessl
const badBucketRenamed = new rename_s3.Bucket(this, 's3-bucket-bad')
// ok:aws-cdk-bucket-enforcessl
const AnotherGoodBucketRenamed = new rename_s3.Bucket(this, 's3-bucket', {
enforceSSL: true
})
// ruleid:aws-cdk-bucket-enforcessl
const badBucket2Renamed = new rename_s3.Bucket(this, 's3-bucket-bad', {
enforceSSL: false
})

// ruleid:aws-cdk-bucket-enforcessl
const badBucketDirect = new Bucket(this, 's3-bucket-bad')
// ok:aws-cdk-bucket-enforcessl
const AnotherGoodBucketDirect = new Bucket(this, 's3-bucket', {
enforceSSL: true
})
// ruleid:aws-cdk-bucket-enforcessl
const badBucket2Direct = new Bucket(this, 's3-bucket-bad', {
enforceSSL: false
})
}
}
27 changes: 27 additions & 0 deletions typescript/aws-cdk/security/audit/awscdk-bucket-enforcessl.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
rules:
- id: aws-cdk-bucket-enforcessl
pattern-either:
- patterns:
- pattern-inside: |
import {Bucket} from '@aws-cdk/aws-s3';
...
- pattern: const $X = new Bucket(...)
- pattern-not: |
const $X = new Bucket(..., {enforceSSL: true}, ...)
- patterns:
- pattern-inside: |
import * as $Y from '@aws-cdk/aws-s3';
...
- pattern: const $X = new $Y.Bucket(...)
- pattern-not: |
const $X = new $Y.Bucket(..., {..., enforceSSL: true, ...})
message: Bucket $X is not set to enforce encryption-in-transit, if not explictly setting this on the bucket policy - the
property "enforceSSL" should be set to true
languages: [ts]
severity: ERROR
metadata:
category: security
technology:
- AWS-CDK
references:
- https://docs.aws.amazon.com/AmazonS3/latest/userguide/security-best-practices.html
64 changes: 64 additions & 0 deletions typescript/aws-cdk/security/audit/awscdk-sqs-unencryptedqueue.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import * as cdk from '@aws-cdk/core';
import * as sqs from '@aws-cdk/aws-sqs';
import * as rename_sqs from '@aws-cdk/aws-sqs';
import {Queue, QueueEncryption} from '@aws-cdk/aws-sqs';

export class Stack extends cdk.Stack {
constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);

// ruleid:awscdk-sqs-unencryptedqueue
const unencryptedQueue1 = new sqs.Queue(this, 'unecryptedQueue1')

// ruleid:awscdk-sqs-unencryptedqueue
const unencryptedQueue2 = new sqs.Queue(this, 'unencryptedQueue2', {
encryption: sqs.QueueEncryption.UNENCRYPTED
})

//ok:awscdk-sqs-unencryptedqueue
const encryptedQueue1 = new sqs.Queue(this, 'encryptedQueue', {
encryption: sqs.QueueEncryption.KMS_MANAGED
})

//ok:awscdk-sqs-unencryptedqueue
const encryptedQueue2 = new sqs.Queue(this, 'encryptedQueue', {
encryption: sqs.QueueEncryption.KMS
})

// ruleid:awscdk-sqs-unencryptedqueue
const unencryptedQueue1RenamedImport = new rename_sqs.Queue(this, 'unencryptedQueue')

// ruleid:awscdk-sqs-unencryptedqueue
const unencryptedQueue2RenamedImport = new rename_sqs.Queue(this, 'unencryptedQueue2', {
encryption: rename_sqs.QueueEncryption.UNENCRYPTED
})

//ok:awscdk-sqs-unencryptedqueue
const encryptedQueue1RenamedImport = new rename_sqs.Queue(this, 'encryptedQueue', {
encryption: rename_sqs.QueueEncryption.KMS_MANAGED
})

//ok:awscdk-sqs-unencryptedqueue
const encryptedQueue2RenamedImport = new rename_sqs.Queue(this, 'encryptedQueue', {
encryption: rename_sqs.QueueEncryption.KMS
})

// ruleid:awscdk-sqs-unencryptedqueue
const unencryptedQueue1DirectImport = new Queue(this, 'unencryptedQueue')

// ruleid:awscdk-sqs-unencryptedqueue
const unencryptedQueue2DirectImport = new Queue(this, 'unencryptedQueue2', {
encryption: QueueEncryption.UNENCRYPTED
})

//ok:awscdk-sqs-unencryptedqueue
const encryptedQueue1DirectImport = new Queue(this, 'encryptedQueue', {
encryption: QueueEncryption.KMS_MANAGED
})

//ok:awscdk-sqs-unencryptedqueue
const encryptedQueue2DirectImport = new Queue(this, 'encryptedQueue', {
encryption: QueueEncryption.KMS
})
}
}
32 changes: 32 additions & 0 deletions typescript/aws-cdk/security/audit/awscdk-sqs-unencryptedqueue.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
rules:
- id: awscdk-sqs-unencryptedqueue
pattern-either:
- patterns:
- pattern-inside: |
import {Queue} from '@aws-cdk/aws-sqs'
...
- pattern: const $X = new Queue(...)
- pattern-not: |
const $X = new Queue(..., {..., encryption: QueueEncryption.KMS_MANAGED, ...})
- pattern-not: |
const $X = new Queue(..., {..., encryption: QueueEncryption.KMS, ...})
- patterns:
- pattern-inside: |
import * as $Y from '@aws-cdk/aws-sqs'
...
- pattern: const $X = new $Y.Queue(...)
- pattern-not: |
const $X = new $Y.Queue(..., {..., encryption: $Y.QueueEncryption.KMS_MANAGED, ...})
- pattern-not: |
const $X = new $Y.Queue(..., {..., encryption: $Y.QueueEncryption.KMS, ...})
message: >-
Queue $X is missing encryption at rest. Add "encryption: $Y.QueueEncryption.KMS" or "encryption: $Y.QueueEncryption.KMS_MANAGED"
to the queue props to enable encryption at rest for the queue.
languages: [ts]
severity: WARNING
metadata:
category: security
technology:
- AWS-CDK
references:
- https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-data-protection.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import * as cdk from '@aws-cdk/core';
import * as s3 from '@aws-cdk/aws-s3';
import * as rename_s3 from '@aws-cdk/aws-s3';
import {Bucket} from '@aws-cdk/aws-s3';

export class CdkStarterStack extends cdk.Stack {
constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);

// ruleid:awscdk-bucket-grantpublicaccessmethod
const publicBucket1 = new s3.Bucket(this, 'bucket')
console.log('something unrelated')
publicBucket1.grantPublicAccess()

// ruleid:awscdk-bucket-grantpublicaccessmethod
const publicBucket2 = new s3.Bucket(this, 'bucket')
publicBucket2.grantPublicAccess()

// ok:awscdk-bucket-grantpublicaccessmethod
const nonPublicBucketRenamed = new rename_s3.Bucket(this, 'bucket')

// ruleid:awscdk-bucket-grantpublicaccessmethod
const publicBucket1Rename = new rename_s3.Bucket(this, 'bucket')
console.log('something unrelated')
publicBucket1Rename.grantPublicAccess()

// ruleid:awscdk-bucket-grantpublicaccessmethod
const publicBucket2Rename = new rename_s3.Bucket(this, 'bucket')
publicBucket2Rename.grantPublicAccess()

// ok:awscdk-bucket-grantpublicaccessmethod
const nonPublicBucketRename = new rename_s3.Bucket(this, 'bucket')

// ruleid:awscdk-bucket-grantpublicaccessmethod
const publicBucket1Direct = new Bucket(this, 'bucket')
console.log('something unrelated')
publicBucket1Direct.grantPublicAccess()

// ruleid:awscdk-bucket-grantpublicaccessmethod
const publicBucket2Direct = new Bucket(this, 'bucket')
publicBucket2Direct.grantPublicAccess()

// ok:awscdk-bucket-grantpublicaccessmethod
const nonPublicBucketDirect = new Bucket(this, 'bucket')
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
rules:
- id: awscdk-bucket-grantpublicaccessmethod
pattern-either:
- patterns:
- pattern-inside: |
import {Bucket} from '@aws-cdk/aws-s3'
...
- pattern: |
const $X = new Bucket(...)
...
$X.grantPublicAccess(...)
- patterns:
- pattern-inside: |
import * as $Y from '@aws-cdk/aws-s3'
...
- pattern: |
const $X = new $Y.Bucket(...)
...
$X.grantPublicAccess(...)
message: Using the GrantPublicAccess method on bucket contruct $X will make the objects in the bucket world accessible.
Verify if this is intentional.
languages: [ts]
severity: WARNING
metadata:
cwe: 'CWE-306: Missing Authentication for Critical Function'
category: security
technology:
- AWS-CDK
references:
- https://docs.aws.amazon.com/AmazonS3/latest/userguide/access-control-overview.html
Loading