cfn-policy-validator を使ってCLIで「外部アクセス許可の検証」をしてみた
いわさです。
IAM Access Analyzerを使うとリソースの意図しないパブリックアクセス、クロスアカウントアクセスの原因となるリソースポリシーの検出が可能です。
以前、チバユキさんがブログを書かれていました。
上記ではマネジメントコンソール上で確認をされています。
チバユキさんもブログの中で、CLIから検出を実施する場合はCreateAccessPreview
を使う必要があるよう言及されています。
そして、APIをラップしたcfn-policy-validator
なるツールが登場したそうなので手軽に検出出来るようになったようです。
本日は試してみました。
インストール
Python製のツールで、pipよりすぐセットアップして使えるようになります。
iwasa.takahito@hoge ~ % pip install cfn-policy-validator Collecting cfn-policy-validator Downloading cfn_policy_validator-0.0.2-py3-none-any.whl (69 kB) |████████████████████████████████| 69 kB 1.5 MB/s Collecting pyYAML>=5.3 Downloading PyYAML-5.4.1-cp39-cp39-macosx_10_9_x86_64.whl (259 kB) |████████████████████████████████| 259 kB 2.5 MB/s Requirement already satisfied: urllib3>=1.25 in ./.pyenv/versions/3.9.4/lib/python3.9/site-packages (from cfn-policy-validator) (1.26.4) Collecting jsonschema>=3.2 Downloading jsonschema-4.0.0-py3-none-any.whl (69 kB) |████████████████████████████████| 69 kB 4.8 MB/s Requirement already satisfied: boto3>=1.17 in ./.pyenv/versions/3.9.4/lib/python3.9/site-packages (from cfn-policy-validator) (1.18.35) Requirement already satisfied: s3transfer<0.6.0,>=0.5.0 in ./.pyenv/versions/3.9.4/lib/python3.9/site-packages (from boto3>=1.17->cfn-policy-validator) (0.5.0) Requirement already satisfied: botocore<1.22.0,>=1.21.35 in ./.pyenv/versions/3.9.4/lib/python3.9/site-packages (from boto3>=1.17->cfn-policy-validator) (1.21.35) Requirement already satisfied: jmespath<1.0.0,>=0.7.1 in ./.pyenv/versions/3.9.4/lib/python3.9/site-packages (from boto3>=1.17->cfn-policy-validator) (0.10.0) Requirement already satisfied: python-dateutil<3.0.0,>=2.1 in ./.pyenv/versions/3.9.4/lib/python3.9/site-packages (from botocore<1.22.0,>=1.21.35->boto3>=1.17->cfn-policy-validator) (2.8.1) Collecting pyrsistent!=0.17.0,!=0.17.1,!=0.17.2,>=0.14.0 Downloading pyrsistent-0.18.0-cp39-cp39-macosx_10_9_x86_64.whl (68 kB) |████████████████████████████████| 68 kB 3.1 MB/s Collecting attrs>=17.4.0 Downloading attrs-21.2.0-py2.py3-none-any.whl (53 kB) |████████████████████████████████| 53 kB 2.9 MB/s Requirement already satisfied: six>=1.5 in ./.pyenv/versions/3.9.4/lib/python3.9/site-packages (from python-dateutil<3.0.0,>=2.1->botocore<1.22.0,>=1.21.35->boto3>=1.17->cfn-policy-validator) (1.16.0) Installing collected packages: pyrsistent, attrs, pyYAML, jsonschema, cfn-policy-validator Successfully installed attrs-21.2.0 cfn-policy-validator-0.0.2 jsonschema-4.0.0 pyYAML-5.4.1 pyrsistent-0.18.0
検出出来るのはマネジメントコンソールと同様で、バケットポリシー、KMSキー、SQSキューポリシーなど様々です。
詳細は以下をご確認ください。
ためしてみた
外部プリンシパルの指定あり
では早速、外部のIAMユーザーを指定したバケットポリシーを作成してみます。
AWSTemplateFormatVersion: "2010-09-09" Resources: ArtifactBucket: Type: AWS::S3::Bucket Properties: BucketName: iwasa-app-artifacts ArtifactBucketPolicy: Type: AWS::S3::BucketPolicy Properties: Bucket: !Ref ArtifactBucket PolicyDocument: Version: "2012-10-17" Statement: - Action: "*" Effect: Allow Resource: "arn:aws:s3:::iwasa-app-artifacts/*" Principal: AWS: "arn:aws:iam::999999999999:user/iwasa"
cfn-policy-validator
コマンドにCloudFormationテンプレートファイルを指定して実行します。
iwasa.takahito@hoge policy-validator % cfn-policy-validator validate --template-path ./01_template.yaml --region ap-northeast-1 --profile hoge { "BlockingFindings": [ { "findingType": "SECURITY_WARNING", "code": "EXTERNAL_PRINCIPAL", "message": "Resource policy allows access from external principals.", "resourceName": "iwasa-app-artifacts", "policyName": "BucketPolicy", "details": { "action": [ "s3:AbortMultipartUpload", "s3:BypassGovernanceRetention", "s3:DeleteBucket", ...省略... "s3:ReplicateObject", "s3:ReplicateTags", "s3:RestoreObject" ], "changeType": "NEW", "condition": {}, "createdAt": "2021-09-30T11:52:04+00:00", "id": "11111111-1111-1111-1111-111111111111", "isPublic": false, "principal": { "AWS": "arn:aws:iam::999999999999:user/iwasa" }, "resource": "arn:aws:s3:::iwasa-app-artifacts", "resourceOwnerAccount": "123456789012", "resourceType": "AWS::S3::Bucket", "sources": [ { "type": "POLICY" } ], "status": "ACTIVE" } } ], "NonBlockingFindings": [] }
SECURITY_WARNING
が発生しましたね。
外部プリンシパルからのアクセスが許可されているとメッセージに表示されています。
外部アクセスなし
外部プリンシパルを指定しなかった場合はどうなるでしょうか。
AWSTemplateFormatVersion: "2010-09-09" Resources: ArtifactBucket: Type: AWS::S3::Bucket Properties: BucketName: iwasa-app-artifacts ArtifactBucketPolicy: Type: AWS::S3::BucketPolicy Properties: Bucket: !Ref ArtifactBucket PolicyDocument: Version: "2012-10-17" Statement: - Action: "*" Effect: Allow Resource: "arn:aws:s3:::iwasa-app-artifacts/*" Principal: AWS: "arn:aws:iam::123456789012:user/hoge"
iwasa.takahito@hoge policy-validator % cfn-policy-validator validate --template-path ./01_template.yaml --region ap-northeast-1 --profile hoge { "BlockingFindings": [], "NonBlockingFindings": [] }
エラーメッセージが何も出なくなりましたね。
AllowかつNotPrincipalを使用
NotPrincipalでAllowを指定してみましょう。
この組み合わせは個別に検出されて専用メッセージが出力されます。
AWSTemplateFormatVersion: "2010-09-09" Resources: ArtifactBucket: Type: AWS::S3::Bucket Properties: BucketName: iwasa-app-artifacts ArtifactBucketPolicy: Type: AWS::S3::BucketPolicy Properties: Bucket: !Ref ArtifactBucket PolicyDocument: Version: "2012-10-17" Statement: - Action: "*" Effect: Allow Resource: "arn:aws:s3:::iwasa-app-artifacts/*" NotPrincipal: AWS: "arn:aws:iam::999999999999:user/iwasa"
iwasa.takahito@hoge policy-validator % cfn-policy-validator validate --template-path ./01_template.yaml --region ap-northeast-1 --profile hoge { "BlockingFindings": [ { "findingType": "SECURITY_WARNING", "code": "ALLOW_WITH_NOT_PRINCIPAL", "message": "Using Allow with NotPrincipal can be overly permissive. We recommend that you use Principal instead.", "resourceName": "iwasa-app-artifacts", "policyName": "BucketPolicy", "details": { "findingDetails": "Using Allow with NotPrincipal can be overly permissive. We recommend that you use Principal instead.", "findingType": "SECURITY_WARNING", "issueCode": "ALLOW_WITH_NOT_PRINCIPAL", "learnMoreLink": "https://docs.aws.amazon.com/IAM/latest/UserGuide/access-analyzer-reference-policy-checks.html#access-analyzer-reference-policy-checks-security-warning-allow-with-not-principal", "locations": [ { "path": [ { "value": "Statement" }, { "index": 0 }, { "value": "Effect" } ], "span": { "end": { "column": 73, "line": 1, "offset": 73 }, "start": { "column": 66, "line": 1, "offset": 66 } } }, { "path": [ { "value": "Statement" }, { "index": 0 }, { "value": "NotPrincipal" } ], "span": { "end": { "column": 188, "line": 1, "offset": 188 }, "start": { "column": 141, "line": 1, "offset": 141 } } } ] } }, { "findingType": "SECURITY_WARNING", "code": "EXTERNAL_PRINCIPAL", "message": "Resource policy allows access from external principals.", "resourceName": "iwasa-app-artifacts", "policyName": "BucketPolicy", "details": { "action": [ "s3:AbortMultipartUpload", "s3:BypassGovernanceRetention", "s3:DeleteBucket", "s3:DeleteBucketOwnershipControls", "s3:DeleteBucketWebsite", "s3:DeleteObject", ... "s3:ReplicateObject", "s3:ReplicateTags", "s3:RestoreObject" ], "changeType": "NEW", "condition": {}, "createdAt": "2021-09-30T12:14:55+00:00", "id": "11111111-1111-1111-1111-111111111111", "isPublic": true, "principal": { "AWS": "*" }, "resource": "arn:aws:s3:::iwasa-app-artifacts", "resourceOwnerAccount": "123456789012", "resourceType": "AWS::S3::Bucket", "sources": [ { "type": "POLICY" } ], "status": "ACTIVE" } } ], "NonBlockingFindings": [] }
ALLOW_WITH_NOT_PRINCIPAL
ということで警告が発生しましたね。
親切に、learnMoreLink
を確認するとALLOW_WITH_NOT_PRINCIPAL
に対する対策内容が確認出来ます。
この辺りの検出内容はひととおり対応されていそうです。
さいごに
検出結果が抽出された場合はパイプラインを中断するなど、IAM Access Analyzerの外部アクセスポリシー検出機能をCI/CDパイプラインに組み込みやすくなりました。
他にも、cfn-lintやCloudFormation Guardを併せて組み込むことで厳格なデプロイパイプラインを構築出来そうです。
参考
Validate IAM policies in CloudFormation templates using IAM Access Analyzer | AWS Security Blog