diff --git a/docs/coverage.md b/docs/coverage.md index 8efe19a..999ec6c 100644 --- a/docs/coverage.md +++ b/docs/coverage.md @@ -6,5 +6,52 @@ The `codeql-extractor-iac` covers a number of technologies today but is being co [CSV Coverage reports](https://github.com/advanced-security/codeql-extractor-iac/actions/workflows/coverage.yml) are created every release and push into the main branch. + +| Suite | Query ID | Severity | +| ------------- | ---------------------------------------------------- | -------- | +| code-scanning | tf/alicloud/storage-publicly-accessible | 10.0 | +| code-scanning | tf/azure/database-unencrypted | 7.0 | +| code-scanning | tf/azure/database-geo-backup-unset-or-disabled | 2.0 | +| code-scanning | tf/azure/database-weak-encryption | 4.0 | +| code-scanning | tf/azure/database-tls-disable | 10.0 | +| code-scanning | tf/azure/security-center-disabled-notifications | 3.0 | +| code-scanning | tf/azure/vault-weak-key | 8.0 | +| code-scanning | tf/azure/storage-publicly-accessible | 10.0 | +| code-scanning | tf/azure/storage-unencrypted | 6.0 | +| code-scanning | tf/all/hardcoded-passwords | 8.0 | +| code-scanning | tf/gcp/abac-enabled | 8.0 | +| code-scanning | tf/gcp/cluster-pod-security-policy | 5.0 | +| code-scanning | tf/gcp/cluster-control-plane-publicly-accessible | 5.0 | +| code-scanning | tf/gcp/storage-publicly-accessible | 10.0 | +| code-scanning | tf/aws/storage-publicly-accessible | 10.0 | +| code-scanning | tf/aws/storage-versioning-disabled | 6.0 | +| code-scanning | tf/aws/storage-unencrypted | 6.0 | +| code-scanning | tf/aws/s3-public-access-disabled | 5.0 | +| code-scanning | tf/aws/storage-logging-disabled | 8.0 | +| code-scanning | tf/aws/elastic-search-disabled-logging | 6.0 | +| code-scanning | tf/aws/rds-database-unencrytped | 8.0 | +| code-scanning | tf/aws/eks-unencrypted-secrets | 8.0 | +| code-scanning | tf/aws/eks-public-cluster | 9.0 | +| code-scanning | hc/kubernetes/pod-run-as-root | 8.0 | +| code-scanning | hc/kubernetes/privileged-pod | 9.0 | +| code-scanning | openapi/web/http-allowed | 2.0 | +| code-scanning | actions/github/pull-request-target | NA | +| code-scanning | actions/github/workflow-permissions | NA | +| code-scanning | actions/github/unpinned-tag | 9.3 | +| code-scanning | containers/docker/latest-images | 2.0 | +| code-scanning | bicep/azure/storage-publicly-accessible | 10.0 | +| code-scanning | bicep/azure/storage-tls-disabled | 9.0 | +| code-scanning | cf/aws/storage-publicly-accessible | 10.0 | +| code-scanning | iac/ecs/assignpublicip | NA | +| code-scanning | iac/ecs/non-priv | NA | +| code-scanning | iac/ecs/container-insights | NA | +| code-scanning | iac/ecs/log-configuration | NA | +| code-scanning | iac/ecs/secrets | NA | +| code-scanning | iac/ecs/assign-publicip-taskset | NA | +| code-scanning | iac/ecs/read-only-root-filesystem | NA | +| code-scanning | iac/ecs/pidmode | NA | + + + Download the coverage report zip, extract the CSV file, and view the content. This will be continuously updated as new queries are added to the extractor. diff --git a/docs/workflows.md b/docs/workflows.md index c2fa9d7..ba5541c 100644 --- a/docs/workflows.md +++ b/docs/workflows.md @@ -6,7 +6,7 @@ To use the CodeQL Extractor, Library, and Queries for Infrastructure as Code, yo ```yaml - name: Initialize and Analyze IaC - uses: advanced-security/codeql-extractor-iac@main + uses: advanced-security/codeql-extractor-iac@v0.4.1 ``` ### Uploading SARIF files to GitHub @@ -16,7 +16,7 @@ This has to be done manually or using the `github/codeql-action/upload-sarif` ac ```yaml - name: Upload SARIF file - uses: github/codeql-action/upload-sarif@v2 + uses: github/codeql-action/upload-sarif@v3 with: sarif_file: codeql-iac.sarif ``` @@ -50,10 +50,10 @@ jobs: - name: Initialize and Analyze IaC id: codeql_iac - uses: advanced-security/codeql-extractor-iac@main + uses: advanced-security/codeql-extractor-iac@v0.4.1 - name: Upload SARIF file - uses: github/codeql-action/upload-sarif@v2 + uses: github/codeql-action/upload-sarif@v3 with: sarif_file: ${{ steps.codeql_iac.outputs.sarif }} ``` diff --git a/scripts/README.md b/scripts/README.md new file mode 100644 index 0000000..5fe9718 --- /dev/null +++ b/scripts/README.md @@ -0,0 +1,9 @@ +# Scripts + +## Coverage Script + +**Generate coverage report for docs:** + +```bash +uv run ./scripts/create-coverage.py report --markdown -o ./docs/coverage.md +``` diff --git a/scripts/create-coverage.py b/scripts/create-coverage.py index 08e4270..011c6d4 100755 --- a/scripts/create-coverage.py +++ b/scripts/create-coverage.py @@ -1,4 +1,11 @@ #!/usr/bin/env python3 +# /// script +# requires-python = ">=3.12" +# dependencies = [ +# "ghastoolkit" +# ] +# /// + import os import csv import json @@ -35,12 +42,8 @@ def generateCsv(csvfile, rules, src, src_suite, display: bool = True): def generateMarkdown(rules, suite: str = "code-scanning") -> str: markdown = """\ -# Code Scanning Coverage Report - -This report shows the coverage of Code Scanning rules for the current repository. - -| Suite | Query ID | Severity | -| ------------- | ------------------------------------------ | -------- | +| Suite | Query ID | Severity | +| ------------- | ---------------------------------------------------- | -------- | """ for rule in rules: @@ -48,7 +51,7 @@ def generateMarkdown(rules, suite: str = "code-scanning") -> str: props = rule.get("properties", {}) severity = props.get("security-severity", "NA") - markdown += f"| {suite} | {id:<42} | {severity:<8} |\n" + markdown += f"| {suite} | {id:<52} | {severity:<8} |\n" return markdown @dataclass @@ -87,6 +90,7 @@ def arguments(self): parser.add_argument("--pull-request", help="Output to pull_request") parser.add_argument("--csv", action="store_true", help="Output as csv") parser.add_argument("--markdown", action="store_true", help="Output as markdown") + parser.add_argument("-o", "--output", help="Output file") parser.add_argument("--rules", default="./scripts/rules", help="Path to query rules folder") @@ -116,7 +120,28 @@ def runReport(self, arguments): generateCsv("coverage.csv", rules, src, src_suite, display=not arguments.markdown) markdown = generateMarkdown(rules) - print(markdown) + + if arguments.output: + if not os.path.exists(arguments.output): + raise Exception(f"Markdown output file not found: {arguments.output}") + with open(arguments.output, "r") as handle: + content = handle.read() + + start_marker = "" + end_marker = "" + start_index = content.find(start_marker) + end_index = content.find(end_marker) + if start_index == -1 or end_index == -1: + raise Exception("Markers not found in markdown file") + + # Replace the content between the markers + new_content = content[:start_index + len(start_marker)] + "\n" + markdown + "\n" + content[end_index:] + with open(arguments.output, "w") as handle: + handle.write(new_content) + + else: + print("""# Code Scanning Coverage Report\n\nThis report shows the coverage of Code Scanning rules for the current repository.\n\n""") + print(markdown) def runRules(self, arguments): """Run and generate the queries.""" diff --git a/scripts/install-extractor.sh b/scripts/install-extractor.sh old mode 100755 new mode 100644