Project: KICS (Provisioning / Security & Compliance)
File: bom.md

This feature uses Rego queries to extract a list of used Terraform resources along with its metadata in the scanned IaC. Find the existing queries under: BoM queries extracts metadata about the resources and organizes it in the following structure: ```go billOfMaterialsRequiredFields := map[string]bool{ "acl": false, "policy": false, "resource_accessibility": true, "resource_category": true, "resource_encryption": true, "resource_engine": false, "resource_name": true, "resource_type": true, "resource_vendor": true, } ``` Observe more detailed information about it in the table below. | Field | Possible Values | Required | Resources | Type | |:-:|:-:|::|::|::| | acl | private,<br /> public-read,<br /> public-read-write,<br /> aws-exec-read,<br /> authenticated-read,<br /> bucket-owner-read,<br /> bucket-owner-full-control,<br /> log-delivery-write | No | `awss3bucket` | string | | policy | policy content (in case `resourceaccessibility` equals hasPolicy) | No | `awsefsfilesystem`,<br /> `awss3bucket`,<br /> `awssnstopic`,<br /> `awssqsqueue`,<br /> `awsdynamodbtable`| JSON marshalled | | resourceaccessibility | public, private, hasPolicy or unknown for <br /> `awsebsvolume`,<br /> `awsefsfilesystem`,<br /> `awsmqbroker`,<br /> `awsmskcluster`,<br /> `awss3bucket`,<br /> `awssnstopic`,<br /> `awssqsqueue`,<br /> `awsdbinstance`, <br /> `awsrdsclusterinstance`,<br /> `awskinesisstream`,<br /> and `awsdynamodbtable` <br /> <br /> at least one security group associated with the elasticache is unrestricted, all security groups associated with the elasticache are restricted or unknown for `awselasticache_cluster` | Yes | all | string | | resourcecategory | In Memory Data Structure for `awselasticachecluster`<br /><br /> Messaging for `awssnstopic`<br /><br /> Queues for `awsmqbroker` and `awssqsqueue`<br /><br /> Storage for `awsebsvolume`, `awsefsfilesystem`, `awss3bucket`,<br /> `awsdbinstance`, <br /> `awsrdsclusterinstance`, and `awsdynamodbtable` <br /><br /> Streaming for `awsmskcluster` and `awskinesis_stream` | Yes | all | string | | resource_encryption | encrypted,<br /> unencrypted,<br /> unknown | Yes | all | string | | resourceengine | memcached, redis or unknown for `awselasticachecluster`<br /><br /> ActiveMQ or RabbitMQ for `awsmqbroker` <br /><br /> parameter in or unknown for <br /> `awsdbinstance`, and <br /> `awsrdsclusterinstance` | No | `awselasticachecluster`, <br /> `awsmqbroker`,<br /> `awsdbinstance`,<br /> `awsrdscluster_instance` | string | | resource_name | anything (if the name is defined),<br /> unknown (if the name is not defined) | Yes | all | string | | resourcetype | awsebsvolume for `awsebsvolume`,<br /> awsefsfilesystem for `awsefsfilesystem`,<br /> awselasticachecluster for `awselasticachecluster`,<br /> awsmqbroker for `awsmqbroker`,<br /> awsmskcluster for `awsmskcluster`,<br /> awss3bucket for `awss3bucket`,<br /> awssnstopic for `awssnstopic`,<br /> awssqsqueue for `awssqsqueue` <br /> awsdbinstance for `awsdbinstance`,<br /> awsrdsclusterinstance for `awsrdsclusterinstance`,<br /> awsdynamodbtable for `awsdynamodbtable`, <br /> awskinesisstream for `awskinesis_stream` | Yes | all | string | | resource_vendor | AWS | Yes | all | string | ```rego CxPolicy[result] { bucketresource := input.document[i].resource.awss3_bucket[name] info := getaccessibility(bucketresource, name) bom_output = { "resourcetype": "awss3_bucket", "resourcename": getbucketname(bucketresource), "resource_accessibility": info.accessibility, "resourceencryption": commonlib.getencryptionifexists(bucketresource), "resource_vendor": "AWS", "resource_category": "Storage", "acl": getbucketacl(bucket_resource), } finalbomoutput = commonlib.getbomoutput(bomoutput, info.policy) result := { "documentId": input.document[i].id, "searchKey": sprintf("awss3bucket[%s]", [name]), "issueType": "BillOfMaterials", "keyExpectedValue": "", "keyActualValue": "", "searchLine": commonlib.buildsearchline(["resource", "awss3_bucket", name], []), "value": json.marshal(finalbomoutput), } } ``` Results will be found in the output and placed separately under `billofmaterials` key: ```json { // etc... "billofmaterials": [ { "query_name": "BOM - AWS S3 Buckets", "query_id": "2d16c3fb-35ba-4ec0-b4e4-06ee3cbd4045", "query_url": "https://kics.io", "severity": "TRACE", "platform": "Terraform", "cloud_provider": "AWS", "category": "Bill Of Materials", "description": "A list of S3 resources found. Amazon Simple Storage Service (Amazon S3) is an object storage service that offers industry-leading scalability, data availability, security, and performance.", "description_id": "0bdf2341", "files": [ { "filename": "assets\\queries\\terraform\\awsbom\\s3_bucket\\test\\positive8.tf", "similarity_id": "aaf7959a055b67a35369c2b02aad327f28e85cca02e2daff3d3e40e2b460f36a", "line": 1, "issue_type": "BillOfMaterials", "searchkey": "awss3_bucket[positive8]", "search_line": 0, "search_value": "", "expected_value": "", "actual_value": "", "value": "{\"acl\":\"public-read\",\"policy\":{\"Id\":\"MYBUCKETPOLICY\",\"Statement\":[{\"Action\":\"s3:GetObject\",\"Condition\":{\"IpAddress\":{\"aws:SourceIp\":\"8.8.8.8/32\"}},\"Effect\":\"Allow\",\"Principal\":{\"AWS\":[\"arn:aws:iam::123456789012:root\",\"arn:aws:iam::555555555555:root\"]},\"Resource\":\"arn:aws:s3:::mytftestbucket/*\",\"Sid\":\"IPAllow\"}],\"Version\":\"2012-10-17\"},\"resourceaccessibility\":\"hasPolicy\",\"resourcecategory\":\"Storage\",\"resourceencryption\":\"encrypted\",\"resourcename\":\"my-tf-test-bucket\",\"resourcetype\":\"awss3bucket\",\"resource_vendor\":\"AWS\"}" } ] } ] } ``` To enable bill-of-materials in the results use the `--bom`

NOTE Bill of Materials queries should always have: `severity: "TRACE"` `category: "Bill Of Materials"` `issue_type: "BillOfMaterials"` This feature uses Rego queries to extract a list of used CloudFormation resources along with its metadata in the scanned IaC. Find the existing queries under: BoM queries extracts metadata about the resources and organizes it in the following structure: ```go billOfMaterialsRequiredFields := map[string]bool{ "acl": false, "policy": false, "resource_accessibility": true, "resource_category": true, "resource_encryption": true, "resource_engine": false, "resource_name": true, "resource_type": true, "resource_vendor": true, } ``` Observe more detailed information about it in the table below. | Field | Possible Values | Required | Resources | Type | |:-:|:-:|::|::|::| | acl | Private,<br /> PublicRead,<br /> PublicReadWrite,<br /> AuthenticatedRead,<br /> LogDeliveryWrite,<br /> BucketOwnerRead,<br /> BucketOwnerFullControl,<br /> AwsExecRead | No | `AWS::S3::Bucket` | string | | policy | policy content (in case `resource_accessibility` equals hasPolicy) | No | `AWS::EFS::FileSystem`,<br /> `AWS::S3::Bucket`,<br /> `AWS::SNS::Topic`,<br /> `AWS::SQS::Queue`,<br /> `AWS::DynamoDB::Table`| JSON marshalled | | resource_accessibility | public, private, hasPolicy or unknown for <br />`AWS::EC2::Volume`,<br />`AWS::EFS::FileSystem`,<br />`AWS::AmazonMQ::Broker`,<br />`AWS::MSK::Cluster`,<br />`AWS::S3::Bucket`, <br />`AWS::SNS::Topic`,<br />`AWS::SQS::Queue`,<br />`AWS::RDS::DBInstance`, <br />`AWS::Kinesis::Stream`, <br />`AWS::DynamoDB::Table`, <br /> and `AWS::Cassandra::Table` <br /> <br /> at least one security group associated with the elasticache is unrestricted, all security groups associated with the elasticache are restricted or unknown for `AWS::ElastiCache::CacheCluster` | Yes | all | string | | resource_category | In Memory Data Structure for `AWS::ElastiCache::CacheCluster`<br /><br /> Messaging for `AWS::SNS::Topic`<br /><br /> Queues for `AWS::AmazonMQ::Broker` and `AWS::SQS::Queue`<br /><br /> Storage for `AWS::EC2::Volume`, `AWS::EFS::FileSystem`, `AWS::S3::Bucket`, `AWS::RDS::DBInstance`, `AWS::DynamoDB::Table`, `AWS::Cassandra::Table`, and `AWS::Kinesis::Stream`<br /><br /> Streaming for `AWS::MSK::Cluster` | Yes | all | string | | resource_encryption | encrypted,<br /> unencrypted,<br /> unknown | Yes | all | string | | resource_engine | memcached, redis or unknown for `AWS::ElastiCache::CacheCluster`<br /><br /> ACTIVEMQ or RABBITMQ for `AWS::AmazonMQ::Broker` <br /><br /> aurora, aurora-mysql, aurora-postgresql, mariadb, mysql, oracle-ee, oracle-ee-cdb, oracle-se2, oracle-se2-cdb, postgres, sqlserver-ee, sqlserver-se, sqlserver-ex, sqlserver-web or unknown for `AWS::RDS::DBInstance` | No | `AWS::ElastiCache::CacheCluster`, <br /> `AWS::AmazonMQ::Broker`,<br /> `AWS::RDS::DBInstance` | string | | resource_name | anything (if the name is defined),<br /> unknown (if the name is not defined) | Yes | all | string | | resource_type | AWS::EC2::Volume for `AWS::EC2::Volume`,<br /> AWS::EFS::FileSystem for `AWS::EFS::FileSystem`,<br /> AWS::ElastiCache::CacheCluster for `AWS::ElastiCache::CacheCluster`,<br /> AWS::AmazonMQ::Broker for `AWS::AmazonMQ::Broker`,<br /> AWS::MSK::Cluster for `AWS::MSK::Cluster`,<br /> AWS::S3::Bucket for `AWS::S3::Bucket`,<br /> AWS::SNS::Topic for `AWS::SNS::Topic`, <br/>AWS::SQS::Queue for `AWS::SQS::Queue`,<br/> AWS::RDS::DBInstance for `AWS::RDS::DBInstance`,<br /> AWS::DynamoDB::Table for `AWS::DynamoDB::Table`,<br /> AWS::Kinesis::Stream for `AWS::Kinesis::Stream`, <br /> AWS::Cassandra::Table for `AWS::Cassandra::Table`| Yes | all | string | | resource_vendor | AWS | Yes | all | string | ``` CxPolicy[result] { document := input.document bucket_resource := document[i].Resources[name] bucket_resource.Type == "AWS::S3::Bucket" info := getresourceaccessibility(bucket_resource, name) bom_output = { "resource_type": "AWS::S3::Bucket", "resourcename": getbucketname(bucketresource), "resource_accessibility": info.accessibility, "resourceencryption": cflib.getencryption(bucketresource), "resource_vendor": "AWS", "resource_category": "Storage", "acl": getbucketacl(bucket_resource), } finalbomoutput := commonlib.getbomoutput(bomoutput, info.policy) result := { "documentId": input.document[i].id, "searchKey": sprintf("Resources.%s", [name]), "issueType": "BillOfMaterials", "keyExpectedValue": "", "keyActualValue": "", "searchLine": commonlib.buildsearch_line(["Resources", name], []), "value": json.marshal(finalbomoutput), } } ``` Results will be found in the output and placed separately under `billofmaterials` key: ```json { // etc... "billofmaterials": [ { "query_name": "BOM - AWS S3 Buckets", "query_id": "b5d6a2e0-8f15-4664-bd5b-68ec5c9bab83", "query_url": "https://kics.io", "severity": "TRACE", "platform": "CloudFormation", "cloud_provider": "AWS", "category": "Bill Of Materials", "description": "A list of S3 resources found. Amazon Simple Storage Service (Amazon S3) is an object storage service that offers industry-leading scalability, data availability, security, and performance.", "description_id": "a46851fb", "files": [ { "file_name": "positive2.json", "similarity_id": "a307e0f377932f42880de350fc69f83084aa8451a2e1e2a37cc97fc4eae7cf94", "line": 5, "issue_type": "BillOfMaterials", "search_key": "Resources.JenkinsArtifacts03", "search_line": 0, "search_value": "", "expected_value": "", "actual_value": "", "value": "{\"acl\":\"BucketOwnerFullControl\",\"resourceaccessibility\":\"unknown\",\"resourcecategory\":\"Storage\",\"resourceencryption\":\"unencrypted\",\"resourcename\":\"jenkins-artifacts\",\"resourcetype\":\"AWS::S3::Bucket\",\"resourcevendor\":\"AWS\"}" }, { "file_name": "positive1.yaml", "similarity_id": "24a0036d2e94676f33c505c5cfd6686ef414072a14e576b08283e9a77596f7eb", "line": 4, "issue_type": "BillOfMaterials", "search_key": "Resources.MyBucket", "search_line": 0, "search_value": "", "expected_value": "", "actual_value": "", "value": "{\"acl\":\"BucketOwnerFullControl\",\"policy\":{\"Statement\":[{\"Action\":[\"s3:GetObject\"],\"Condition\":{\"StringLike\":{\"aws:Referer\":[\"http://www.example.com/\",\"http://example.net/\"]}},\"Effect\":\"Allow\",\"Principal\":\"\",\"Resource\":[\"\",{\"playbooks\":[\"arn:aws:s3:::\",\"DOC-EXAMPLE-BUCKET\",\"/\"]}]}],\"Version\":\"2012-10-17\"},\"resourceaccessibility\":\"hasPolicy\",\"resourcecategory\":\"Storage\",\"resourceencryption\":\"encrypted\",\"resourcename\":\"jenkins-artifacts\",\"resourcetype\":\"AWS::S3::Bucket\",\"resourcevendor\":\"AWS\"}" } ] } ] } ```