From e9fb6bbc43bfb4ea76952bbc6e343dec076bbb25 Mon Sep 17 00:00:00 2001 From: Robert Fink Date: Wed, 28 May 2025 15:22:38 -0400 Subject: [PATCH 1/3] add zizmor pre-commit check --- .clinerules | 14 ++- .git-hooks/pre-commit | 25 ++++++ zizmor.sarif | 194 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 232 insertions(+), 1 deletion(-) create mode 100644 zizmor.sarif diff --git a/.clinerules b/.clinerules index f9ac145..e61985b 100644 --- a/.clinerules +++ b/.clinerules @@ -20,5 +20,17 @@ - Handle errors gracefully, logging only essential details. - Use unique error codes or identifiers for easier debugging. -## 6. CI considerations +## 7. CI considerations - Make sure changes are not committed directly to the `main` branch + +## 8. Exclusions +exclude: + - "*.png" + +## 9. Context limits +context: + handoff_threshold: 50% + carry_over: + - summaries + - file_states + - next_steps diff --git a/.git-hooks/pre-commit b/.git-hooks/pre-commit index e389996..988d3fe 100755 --- a/.git-hooks/pre-commit +++ b/.git-hooks/pre-commit @@ -26,6 +26,31 @@ if [ -n "$STAGED_FILES" ]; then fi fi +# Check if the staged files include GitHub Actions workflow files +STAGED_WORKFLOW_FILES=$(git diff --cached --name-only --diff-filter=ACM | grep -E '^\.github/workflows/.*\.ya?ml$' || true) + +# If GitHub Actions workflow files are staged, run zizmor +if [ -n "$STAGED_WORKFLOW_FILES" ]; then + echo "Running zizmor to check GitHub Actions workflows..." + + # Check if zizmor is installed + if ! command -v zizmor >/dev/null 2>&1; then + echo "zizmor is not installed. Please install it and try again." + exit 1 + fi + + # Run zizmor on each staged workflow file with pedantic persona and medium thresholds + for file in $STAGED_WORKFLOW_FILES; do + echo "Checking $file with zizmor (pedantic mode, medium+ severity/confidence)..." + if ! zizmor --persona=pedantic --min-severity=medium --min-confidence=medium "$ROOT_DIR/$file"; then + echo "Zizmor detected issues in $file. Commit aborted." + exit 1 + fi + done + + echo "All GitHub Actions workflows passed zizmor security checks!" +fi + # Check if the staged files include JavaScript files in the javascriptapp directory STAGED_JS_FILES=$(git diff --cached --name-only --diff-filter=ACM | grep -E '^javascriptapp/.*\.js$' || true) diff --git a/zizmor.sarif b/zizmor.sarif new file mode 100644 index 0000000..72d75ec --- /dev/null +++ b/zizmor.sarif @@ -0,0 +1,194 @@ +{ + "$schema": "https://docs.oasis-open.org/sarif/sarif/v2.1.0/os/schemas/sarif-schema-2.1.0.json", + "runs": [ + { + "invocations": [ + { + "executionSuccessful": true + } + ], + "results": [ + { + "kind": "fail", + "level": "warning", + "locations": [ + { + "logicalLocations": [ + { + "properties": { + "symbolic": { + "annotation": "default permissions used due to no permissions: block", + "key": { + "Local": { + "given_path": "./.github/workflows/checks.yml", + "prefix": "." + } + }, + "kind": "Primary", + "route": { + "components": [] + } + } + } + } + ], + "message": { + "text": "default permissions used due to no permissions: block" + }, + "physicalLocation": { + "artifactLocation": { + "uri": ".github/workflows/checks.yml" + }, + "region": { + "endColumn": 1, + "endLine": 33, + "snippet": { + "text": "name: Checks\n\non:\n push:\n paths:\n - javascriptapp/**\n pull_request:\n paths:\n - javascriptapp/**\n\njobs:\n build-and-test:\n runs-on: ubuntu-latest\n\n steps:\n - name: Check out code\n uses: actions/checkout@v2\n\n - name: Use Node\n uses: actions/setup-node@v3\n with:\n node-version: 18\n\n - name: Install dependencies\n working-directory: javascriptapp\n run: npm install\n\n - name: Run tests with coverage\n working-directory: javascriptapp\n env:\n OPENWEATHER_API_KEY: ${{ secrets.OPENWEATHER_API_KEY }}\n run: npm test\n" + }, + "sourceLanguage": "yaml", + "startColumn": 1, + "startLine": 1 + } + } + } + ], + "message": { + "text": "default permissions used due to no permissions: block" + }, + "relatedLocations": [], + "ruleId": "zizmor/excessive-permissions" + }, + { + "kind": "fail", + "level": "warning", + "locations": [ + { + "logicalLocations": [ + { + "properties": { + "symbolic": { + "annotation": "default permissions used due to no permissions: block", + "key": { + "Local": { + "given_path": "./.github/workflows/checks.yml", + "prefix": "." + } + }, + "kind": "Primary", + "route": { + "components": [ + { + "Key": "jobs" + }, + { + "Key": "build-and-test" + } + ] + } + } + } + } + ], + "message": { + "text": "default permissions used due to no permissions: block" + }, + "physicalLocation": { + "artifactLocation": { + "uri": ".github/workflows/checks.yml" + }, + "region": { + "endColumn": 1, + "endLine": 33, + "snippet": { + "text": " build-and-test:\n runs-on: ubuntu-latest\n\n steps:\n - name: Check out code\n uses: actions/checkout@v2\n\n - name: Use Node\n uses: actions/setup-node@v3\n with:\n node-version: 18\n\n - name: Install dependencies\n working-directory: javascriptapp\n run: npm install\n\n - name: Run tests with coverage\n working-directory: javascriptapp\n env:\n OPENWEATHER_API_KEY: ${{ secrets.OPENWEATHER_API_KEY }}\n run: npm test\n" + }, + "sourceLanguage": "yaml", + "startColumn": 3, + "startLine": 12 + } + } + } + ], + "message": { + "text": "default permissions used due to no permissions: block" + }, + "relatedLocations": [ + { + "logicalLocations": [ + { + "properties": { + "symbolic": { + "annotation": "this job", + "key": { + "Local": { + "given_path": "./.github/workflows/checks.yml", + "prefix": "." + } + }, + "kind": "Related", + "route": { + "components": [ + { + "Key": "jobs" + }, + { + "Key": "build-and-test" + } + ] + } + } + } + } + ], + "message": { + "text": "this job" + }, + "physicalLocation": { + "artifactLocation": { + "uri": ".github/workflows/checks.yml" + }, + "region": { + "endColumn": 1, + "endLine": 33, + "snippet": { + "text": " build-and-test:\n runs-on: ubuntu-latest\n\n steps:\n - name: Check out code\n uses: actions/checkout@v2\n\n - name: Use Node\n uses: actions/setup-node@v3\n with:\n node-version: 18\n\n - name: Install dependencies\n working-directory: javascriptapp\n run: npm install\n\n - name: Run tests with coverage\n working-directory: javascriptapp\n env:\n OPENWEATHER_API_KEY: ${{ secrets.OPENWEATHER_API_KEY }}\n run: npm test\n" + }, + "sourceLanguage": "yaml", + "startColumn": 3, + "startLine": 12 + } + } + } + ], + "ruleId": "zizmor/excessive-permissions" + } + ], + "tool": { + "driver": { + "downloadUri": "https://github.com/zizmorcore/zizmor", + "informationUri": "https://docs.zizmor.sh", + "name": "zizmor", + "rules": [ + { + "help": { + "markdown": "`excessive-permissions`: overly broad permissions\n\nDocs: ", + "text": "overly broad permissions" + }, + "helpUri": "https://docs.zizmor.sh/audits/#excessive-permissions", + "id": "zizmor/excessive-permissions", + "name": "excessive-permissions", + "properties": { + "tags": [ + "security" + ] + } + } + ], + "semanticVersion": "1.8.0", + "version": "1.8.0" + } + } + } + ], + "version": "2.1.0" +} \ No newline at end of file From 7825cb25c4f5ba8b2f248b2861ac4f609854f94d Mon Sep 17 00:00:00 2001 From: Robert Fink Date: Wed, 28 May 2025 15:50:49 -0400 Subject: [PATCH 2/3] update readme --- README.md | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/README.md b/README.md index ff67879..8e95998 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,7 @@ This repository contains various projects and examples used for AI experimentati ## Structure +- **goapp/**: A Go application that fetches and displays stock data using the Alpha Vantage API. - **javascriptapp/**: A simple JavaScript application with tests and coverage reports. - **mermaid_diagrams/**: Examples of using Mermaid to create diagrams for various architectures and workflows. - **.git-hooks/**: Git hooks for code quality and testing. See [Git Hooks](#git-hooks) section below. @@ -32,6 +33,39 @@ brew install gitleaks The pre-commit hook will block commits if any secrets are detected in the staged files. +### GitHub Actions Security Scanning with Zizmor + +This repository uses [zizmor](https://github.com/zizmorcore/zizmor) to scan GitHub Actions workflows for security vulnerabilities and misconfigurations. Zizmor is a security auditing tool that analyzes workflow files and identifies potential security issues such as excessive permissions, unsafe practices, and other workflow-related security concerns. + +To use zizmor on your system, you can install it via multiple package managers: + +**macOS (Homebrew):** +```bash +brew install zizmor +``` + +**Rust (Cargo):** +```bash +cargo install zizmor +``` + +**From GitHub Releases:** +Download the appropriate binary from the [releases page](https://github.com/zizmorcore/zizmor/releases). + +To scan the GitHub Actions workflows in this repository: + +```bash +zizmor . +``` + +The tool will output results in SARIF format, which can be viewed in compatible editors or saved to a file: + +```bash +zizmor . --format sarif > zizmor.sarif +``` + +For more information about zizmor and its security audits, see the [official documentation](https://docs.zizmor.sh). + ## Note This repository is part of an AI experimentation project and is not actively maintained. Contributions are not being accepted at this time. From 8f7e1df2f4c2a23ff5dcc4e458f2eee9bdb2cece Mon Sep 17 00:00:00 2001 From: Robert Fink Date: Wed, 28 May 2025 16:26:27 -0400 Subject: [PATCH 3/3] fix the zizmor findings and add a zizmor gh workflow --- .github/workflows/checks.yml | 8 +- .github/workflows/zizmor_sarif.yml | 45 ++++++++ zizmor.sarif | 174 +---------------------------- 3 files changed, 54 insertions(+), 173 deletions(-) create mode 100644 .github/workflows/zizmor_sarif.yml diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml index 520b3ff..f1b078e 100644 --- a/.github/workflows/checks.yml +++ b/.github/workflows/checks.yml @@ -8,13 +8,19 @@ on: paths: - javascriptapp/** +# Restrict permissions to minimum required (fixes zizmor excessive-permissions) +permissions: + contents: read # Only read access to repository contents + jobs: build-and-test: runs-on: ubuntu-latest steps: - name: Check out code - uses: actions/checkout@v2 + uses: actions/checkout@v4 + with: + persist-credentials: false - name: Use Node uses: actions/setup-node@v3 diff --git a/.github/workflows/zizmor_sarif.yml b/.github/workflows/zizmor_sarif.yml new file mode 100644 index 0000000..405dfd3 --- /dev/null +++ b/.github/workflows/zizmor_sarif.yml @@ -0,0 +1,45 @@ +name: Zizmor Security Scan + +on: + push: + branches: [main] + paths: + - ".github/workflows/**" + pull_request: + paths: + - ".github/workflows/**" + workflow_dispatch: + +permissions: + contents: read + +jobs: + zizmor-scan: + runs-on: ubuntu-latest + name: Zizmor GitHub Actions Security Scan + permissions: + contents: read + security-events: write + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Install Rust and zizmor + run: | + curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y + source ~/.cargo/env + cargo install zizmor + + - name: Run zizmor security scan + run: | + source ~/.cargo/env + zizmor --persona=pedantic --min-severity=medium --min-confidence=medium --format=sarif .github/workflows/ > zizmor.sarif + continue-on-error: true + + - name: Upload SARIF results to GitHub + uses: github/codeql-action/upload-sarif@v3 + with: + sarif_file: zizmor.sarif + category: zizmor + if: always() diff --git a/zizmor.sarif b/zizmor.sarif index 72d75ec..a21b6ca 100644 --- a/zizmor.sarif +++ b/zizmor.sarif @@ -7,183 +7,13 @@ "executionSuccessful": true } ], - "results": [ - { - "kind": "fail", - "level": "warning", - "locations": [ - { - "logicalLocations": [ - { - "properties": { - "symbolic": { - "annotation": "default permissions used due to no permissions: block", - "key": { - "Local": { - "given_path": "./.github/workflows/checks.yml", - "prefix": "." - } - }, - "kind": "Primary", - "route": { - "components": [] - } - } - } - } - ], - "message": { - "text": "default permissions used due to no permissions: block" - }, - "physicalLocation": { - "artifactLocation": { - "uri": ".github/workflows/checks.yml" - }, - "region": { - "endColumn": 1, - "endLine": 33, - "snippet": { - "text": "name: Checks\n\non:\n push:\n paths:\n - javascriptapp/**\n pull_request:\n paths:\n - javascriptapp/**\n\njobs:\n build-and-test:\n runs-on: ubuntu-latest\n\n steps:\n - name: Check out code\n uses: actions/checkout@v2\n\n - name: Use Node\n uses: actions/setup-node@v3\n with:\n node-version: 18\n\n - name: Install dependencies\n working-directory: javascriptapp\n run: npm install\n\n - name: Run tests with coverage\n working-directory: javascriptapp\n env:\n OPENWEATHER_API_KEY: ${{ secrets.OPENWEATHER_API_KEY }}\n run: npm test\n" - }, - "sourceLanguage": "yaml", - "startColumn": 1, - "startLine": 1 - } - } - } - ], - "message": { - "text": "default permissions used due to no permissions: block" - }, - "relatedLocations": [], - "ruleId": "zizmor/excessive-permissions" - }, - { - "kind": "fail", - "level": "warning", - "locations": [ - { - "logicalLocations": [ - { - "properties": { - "symbolic": { - "annotation": "default permissions used due to no permissions: block", - "key": { - "Local": { - "given_path": "./.github/workflows/checks.yml", - "prefix": "." - } - }, - "kind": "Primary", - "route": { - "components": [ - { - "Key": "jobs" - }, - { - "Key": "build-and-test" - } - ] - } - } - } - } - ], - "message": { - "text": "default permissions used due to no permissions: block" - }, - "physicalLocation": { - "artifactLocation": { - "uri": ".github/workflows/checks.yml" - }, - "region": { - "endColumn": 1, - "endLine": 33, - "snippet": { - "text": " build-and-test:\n runs-on: ubuntu-latest\n\n steps:\n - name: Check out code\n uses: actions/checkout@v2\n\n - name: Use Node\n uses: actions/setup-node@v3\n with:\n node-version: 18\n\n - name: Install dependencies\n working-directory: javascriptapp\n run: npm install\n\n - name: Run tests with coverage\n working-directory: javascriptapp\n env:\n OPENWEATHER_API_KEY: ${{ secrets.OPENWEATHER_API_KEY }}\n run: npm test\n" - }, - "sourceLanguage": "yaml", - "startColumn": 3, - "startLine": 12 - } - } - } - ], - "message": { - "text": "default permissions used due to no permissions: block" - }, - "relatedLocations": [ - { - "logicalLocations": [ - { - "properties": { - "symbolic": { - "annotation": "this job", - "key": { - "Local": { - "given_path": "./.github/workflows/checks.yml", - "prefix": "." - } - }, - "kind": "Related", - "route": { - "components": [ - { - "Key": "jobs" - }, - { - "Key": "build-and-test" - } - ] - } - } - } - } - ], - "message": { - "text": "this job" - }, - "physicalLocation": { - "artifactLocation": { - "uri": ".github/workflows/checks.yml" - }, - "region": { - "endColumn": 1, - "endLine": 33, - "snippet": { - "text": " build-and-test:\n runs-on: ubuntu-latest\n\n steps:\n - name: Check out code\n uses: actions/checkout@v2\n\n - name: Use Node\n uses: actions/setup-node@v3\n with:\n node-version: 18\n\n - name: Install dependencies\n working-directory: javascriptapp\n run: npm install\n\n - name: Run tests with coverage\n working-directory: javascriptapp\n env:\n OPENWEATHER_API_KEY: ${{ secrets.OPENWEATHER_API_KEY }}\n run: npm test\n" - }, - "sourceLanguage": "yaml", - "startColumn": 3, - "startLine": 12 - } - } - } - ], - "ruleId": "zizmor/excessive-permissions" - } - ], + "results": [], "tool": { "driver": { "downloadUri": "https://github.com/zizmorcore/zizmor", "informationUri": "https://docs.zizmor.sh", "name": "zizmor", - "rules": [ - { - "help": { - "markdown": "`excessive-permissions`: overly broad permissions\n\nDocs: ", - "text": "overly broad permissions" - }, - "helpUri": "https://docs.zizmor.sh/audits/#excessive-permissions", - "id": "zizmor/excessive-permissions", - "name": "excessive-permissions", - "properties": { - "tags": [ - "security" - ] - } - } - ], + "rules": [], "semanticVersion": "1.8.0", "version": "1.8.0" }