Skip to content

Commit

Permalink
feat: add initial typescript aws-cdk checks (#1629)
Browse files Browse the repository at this point in the history
* feat: add initial typescript aws-cdk checks

* chore: remove whitespace

* chore: fix multiline operators in config files

* Precommit

Co-authored-by: grayson <[email protected]>
  • Loading branch information
rileydakota and minusworld authored Nov 29, 2021
1 parent c455468 commit 341779f
Show file tree
Hide file tree
Showing 10 changed files with 429 additions and 0 deletions.
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

0 comments on commit 341779f

Please sign in to comment.