Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 85 additions & 0 deletions .github/workflows/zap-security-scan.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
name: OWASP ZAP Security Scan

on:
deployment_status:
workflow_dispatch:
inputs:
target_url:
description: 'Target URL to scan (overrides STAGING_URL secret)'
required: false
type: string

permissions:
contents: read
deployments: read
checks: write

Comment on lines +12 to +16

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== workflow =="
if [ -f .github/workflows/zap-security-scan.yml ]; then
  nl -ba .github/workflows/zap-security-scan.yml | sed -n '1,120p'
else
  echo "missing .github/workflows/zap-security-scan.yml"
fi

echo
echo "== search for action calls =="
rg -n "github/codeql-action/upload-sarif|zaproxy/action-baseline|permissions:|allow_issue_writing" .github/workflows || true

echo
echo "== git diff summary =="
git diff --stat || true

Repository: ritik4ever/stellar-goal-vault

Length of output: 222


🌐 Web query:

github codeql-action upload-sarif permissions security-events write

💡 Result:

To use the github/codeql-action/upload-sarif action, your GitHub Actions workflow job must be granted specific permissions to interact with the repository's security features and metadata [1][2]. The mandatory permission is: - security-events: write In addition to this, if you are working in a private or internal repository, you must also grant: - actions: read - contents: read These additional permissions are required because the action queries workflow run metadata during the upload process [3][4]. Failing to provide these permissions—particularly actions: read in private repositories—often results in a "Resource not accessible by integration" error [5][3]. Example configuration: jobs: upload-analysis: runs-on: ubuntu-latest permissions: security-events: write actions: read contents: read steps: - name: Upload SARIF uses: github/codeql-action/upload-sarif@v4 with: sarif_file: results.sarif

Citations:


🌐 Web query:

zaproxy action-baseline v0.10.0 README allow_issue_writing default true

💡 Result:

In the zaproxy/action-baseline GitHub Action, specifically in version 0.10.0 and subsequent versions, the allow_issue_writing input defaults to true [1][2]. This input determines whether the action will automatically create or update a GitHub issue with the ZAP scan report using the title provided in the issue_title input [3][1]. Setting allow_issue_writing to false disables this behavior [3][4].

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== workflow =="
if [ -f .github/workflows/zap-security-scan.yml ]; then
  awk '{ printf "%5d  %s\n", NR, $0 }' .github/workflows/zap-security-scan.yml | sed -n '1,120p'
else
  echo "missing .github/workflows/zap-security-scan.yml"
fi

echo
echo "== search for action calls and permissions =="
rg -n "github/codeql-action/upload-sarif|zaproxy/action-baseline|permissions:|allow_issue_writing|permissions:" .github/workflows || true

echo
echo "== git status/diff summary =="
git status --short || true
git diff --stat || true

Repository: ritik4ever/stellar-goal-vault

Length of output: 4595


Grant the permissions required by the SARIF upload action.

github/codeql-action/upload-sarif@v3 requires security-events: write; checks: write does not grant that permission, so the final SARIF upload step can fail with Resource not accessible by integration. Also set allow_issue_writing: false on zaproxy/action-baseline@v0.10.0 unless creating/updating ZAP issues is intentional; issue writing is enabled by default and can fail when issue permissions are not granted.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/zap-security-scan.yml around lines 12 - 16, The workflow
permissions must support SARIF uploads without enabling unintended issue
creation. Update the top-level permissions block to grant security-events: write
instead of checks: write, and configure zaproxy/action-baseline@v0.10.0 with
allow_issue_writing: false while preserving the existing scan and upload steps.

jobs:
zap-scan:
name: OWASP ZAP Passive Scan
runs-on: ubuntu-latest
if: >
github.event_name == 'workflow_dispatch' ||
github.event.deployment_status.state == 'success'
Comment on lines +21 to +23

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy lift

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== files =="
git ls-files '.github/workflows/*' | sed -n '1,120p'

echo
echo "== target workflow =="
if [ -f .github/workflows/zap-security-scan.yml ]; then
  cat -n .github/workflows/zap-security-scan.yml
else
  echo "missing .github/workflows/zap-security-scan.yml"
fi

echo
echo "== related workflow references =="
rg -n "zap-security-scan|workflow_dispatch|deployment_status|deployment|deployment_status\.state|ref =|ZAP|zap" .github/workflows || true

echo
echo "== current branch/workflow files diff stat =="
git diff --stat -- .github/workflows || true

Repository: ritik4ever/stellar-goal-vault

Length of output: 7549


🌐 Web query:

GitHub Actions deployment_status event runs after status reports back deployment workflow cannot be blocked by downstream job after deployment_status success

💡 Result:

In GitHub Actions, a workflow configured with the deployment_status event trigger runs independently whenever an external service updates the deployment status (e.g., to success, failure, or pending) [1][2][3]. This workflow is not "blocked" or managed by the workflow that originally created the deployment; rather, it is a separate event-driven process [4][3]. Because the deployment_status event fires for every state change, your workflow will be triggered multiple times throughout the deployment lifecycle [4]. If you only want your workflow jobs to execute after a successful deployment, you must explicitly filter them using a conditional expression at the job level [4][5]: jobs: run-after-deploy: if: github.event.deployment_status.state == 'success' runs-on: ubuntu-latest steps: - run: echo "Deployment was successful!" Regarding your query about downstream blocking: 1. Independent Execution: The deployment_status workflow is triggered by the GitHub webhook event, not by the completion of another workflow [1][3]. There is no native mechanism for a "downstream job" to block the initiation of this event-driven workflow [4]. 2. State Dependency: Since you cannot prevent the workflow from triggering on non-success states (like pending or in_progress) without potentially missing the success event, the standard pattern is to allow the workflow to start and then use the if condition to skip unwanted jobs [4][6]. 3. Context Limitations: Be aware that the deployment_status event context often lacks certain information, such as the github.ref (branch or tag), because the event is tied to a specific deployment instance rather than a repository ref [7][8]. If you need to verify the branch, you may need to use the GitHub API to fetch the associated commit or deployment details [8]. In summary, you cannot block the deployment_status event from triggering, nor can you block the overall workflow run from starting via a downstream job. You should design your workflow to be idempotent and use job-level conditionals to ensure your logic only proceeds when the deployment state reaches success [4][5].

Citations:


Gate the scan before reporting deployment success.

This workflow is triggered by deployment_status, so it starts after the deployment status is already reported; if it fails after the state is success, the deployment cannot be rolled back by GitHub Actions alone. Satisfy Issue #628 by making this a required pre-success check/protection gate or having the deployment workflow wait for the scan result before reporting success.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/zap-security-scan.yml around lines 21 - 23, Change the
deployment and ZAP scan workflow coordination so the scan completes before
deployment reports success, rather than gating on
github.event.deployment_status.state == 'success' in the current workflow
condition. Implement the required pre-success protection gate or make the
deployment workflow wait for the scan result, ensuring failed scans prevent
deployment success.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Repository files matching zap-security-scan:"
fd -a 'zap-security-scan\.yml$|zap-security-scan\.yaml$' . || true

echo
echo "Workflow contents:"
if [ -f .github/workflows/zap-security-scan.yml ]; then
  cat -n .github/workflows/zap-security-scan.yml
fi

echo
echo "Event/trigger references in workflows:"
rg -n "ghcr.io|zap|security|on:|deployment_status|workflow_dispatch|environment" .github/workflows || true

echo
echo "Relevant GitHub Actions docs via local source absent; checking public docs with web query"

Repository: ritik4ever/stellar-goal-vault

Length of output: 11101


🌐 Web query:

GitHub Actions deployment_status object environment field event.deployment_status.environment

💡 Result:

In GitHub Actions workflows, the github.event.deployment_status.environment field contains the name of the target deployment environment (e.g., "production", "staging", "qa") associated with a deployment_status event [1][2][3]. Key details regarding this field include: * Data Source: The field is part of the deployment_status object within the webhook payload for the deployment_status event [4][2]. * Behavior: When a deployment status is created, this field identifies the specific environment being targeted [3][5]. If this field is not explicitly defined when the status is created, GitHub defaults to the environment of the previous status on the deployment, if one exists; otherwise, it defaults to the environment of the original deployment [6][3][7]. * Usage in Workflows: It is commonly used in GitHub Actions to filter jobs or trigger specific logic based on the environment being deployed to. For example, developers often use it in if conditions to ensure deployment-related workflows only execute for specific environments: on: deployment_status: jobs: deploy-check: runs-on: ubuntu-latest if: github.event.deployment_status.environment == 'production' steps: - run: echo "Deploying to production" * Security Warning: Because environment (along with other payload fields) is provided by the external service or tool that triggers the deployment, it should be treated as untrusted input [1]. When using this field to make security decisions or run tests, ensure your workflow is configured safely, as improper handling of deployment-related inputs can potentially be exploited [1].

Citations:


Restrict deployment-status scans to staging.

This workflow runs on every successful deployment-status event; gate that branch on the deployment environment so production or other environments cannot trigger the ZAP scan.

Proposed condition
 github.event_name == 'workflow_dispatch' ||
- github.event.deployment_status.state == 'success'
+ (github.event.deployment_status.state == 'success' &&
+  github.event.deployment_status.environment == 'staging')
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if: >
github.event_name == 'workflow_dispatch' ||
github.event.deployment_status.state == 'success'
if: >
github.event_name == 'workflow_dispatch' ||
(github.event.deployment_status.state == 'success' &&
github.event.deployment_status.environment == 'staging')
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/zap-security-scan.yml around lines 21 - 23, Update the
workflow trigger condition to require a staging deployment environment whenever
github.event_name is deployment_status, while preserving the existing
workflow_dispatch path. Use the deployment status environment field exposed by
the event payload and ensure successful production or other non-staging
deployments cannot start the ZAP scan.


steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Determine target URL
id: target
run: |
if [ -n "${{ github.event.inputs.target_url }}" ]; then
echo "url=${{ github.event.inputs.target_url }}" >> $GITHUB_OUTPUT
elif [ -n "${{ github.event.deployment_status.target_url }}" ]; then
echo "url=${{ github.event.deployment_status.target_url }}" >> $GITHUB_OUTPUT
Comment on lines +34 to +35

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== workflow occurrences =="
if [ -f .github/workflows/zap-security-scan.yml ]; then
  nl -ba .github/workflows/zap-security-scan.yml | sed -n '1,140p'
else
  echo "missing .github/workflows/zap-security-scan.yml"
fi

echo
echo "== deployment-status related references =="
rg -n "deployment_status|environment_url|target_url|url=|--url" .github/workflows || true

echo
echo "== docs/API behavior from installed GitHub REST docs? =="
python3 - <<'PY'
import json, urllib.request
url="https://docs.github.com/en/rest/deployments/statuses"
try:
    with urllib.request.urlopen(url, timeout=20) as r:
        text=r.read(500).decode()
    print(text)
except Exception as e:
    print(type(e).__name__, e)
PY

Repository: ritik4ever/stellar-goal-vault

Length of output: 234


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== workflow occurrences =="
if [ -f .github/workflows/zap-security-scan.yml ]; then
  awk '{print NR": "$0}' .github/workflows/zap-security-scan.yml | sed -n '1,140p'
else
  echo "missing .github/workflows/zap-security-scan.yml"
fi

echo
echo "== deployment-status related references =="
rg -n "deployment_status|environment_url|target_url|url=|--url" .github/workflows || true

echo
echo "== external doc/API fields for deployment statuses =="
python3 - <<'PY'
from urllib.request import urlopen
fields=[]
for url in [
  "https://docs.github.com/en/rest/deployments/deployments?apiVersion=2022-11-28",
  "https://docs.github.com/en/rest/deployments/statuses?apiVersion=2022-11-28",
  "https://rest.github-api.org/en/v1/rest/deployments/deployments?apiVersion=2022-11-28",
]:
    try:
        text=urlopen(url, timeout=20).read(5000).decode()
        print(f"--- {url!r} ---")
        print(text)
        print()
    except Exception as e:
        print(f"--- {url!r} ---")
        print(f"ERROR {type(e).__name__}: {e}")
        print()
PY

Repository: ritik4ever/stellar-goal-vault

Length of output: 5654


🌐 Web query:

GitHub REST Deployment Statuses fields target_url environment_url documentation

💡 Result:

In the GitHub REST API, both target_url and environment_url are fields used when creating or retrieving a deployment status [1][2]. 1. target_url: This is a string field intended to provide a link to the output of the deployment, which helps users monitor the task while it is running or access historical information about the deployment [1][3]. GitHub currently recommends using the log_url parameter instead of target_url [1][2]. While target_url is still accepted to support legacy integrations, log_url is the preferred field for providing the full URL of the deployment's output [1][4]. Notably, if you set log_url, GitHub automatically sets target_url to the same value [1][3]. 2. environment_url: This is a string field that specifies the URL for accessing the deployed environment (e.g., the live application URL) [1][2]. It is distinct from the target_url or log_url, which are typically used for deployment logs or task status tracking [1][3]. When interacting with the POST /repos/{owner}/{repo}/deployments/{deployment_id}/statuses endpoint, both target_url (or log_url) and environment_url are optional fields provided in the request body [1][4]. Both fields are also returned as part of the deployment status object when retrieving status information [1][2].

Citations:


Use environment_url as the scan target.

deployment_status.target_url is intended for deployment output/log links, not the deployed environment/app URL. Set url from github.event.deployment_status.environment_url so the ZAP scan does not target a deployment log.

🧰 Tools
🪛 zizmor (1.28.0)

[error] 34-34: code injection via template expansion (template-injection): may expand into attacker-controllable code

(template-injection)


[error] 35-35: code injection via template expansion (template-injection): may expand into attacker-controllable code

(template-injection)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/zap-security-scan.yml around lines 34 - 35, Update the URL
assignment in the workflow’s deployment-status handling to use
github.event.deployment_status.environment_url instead of
github.event.deployment_status.target_url. Preserve the existing non-empty check
and GITHUB_OUTPUT assignment so ZAP receives the deployed environment URL.

elif [ -n "${{ secrets.STAGING_URL }}" ]; then
echo "url=${{ secrets.STAGING_URL }}" >> $GITHUB_OUTPUT
Comment on lines +32 to +37

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🔴 Critical | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== workflow file =="
cat -n .github/workflows/zap-security-scan.yml

echo
echo "== occurrences of github.event/secrets in workflow =="
rg -n '\$\{\{\s*(github\.event|secrets\.STAGING_URL)' .github/workflows/zap-security-scan.yml || true

Repository: ritik4ever/stellar-goal-vault

Length of output: 4642


Do not interpolate external values into shell source.

The target values on lines 32-37 are expanded directly into the run script, so inputs/secret values containing " and untrusted deployment URLs containing $() can alter the commands. Pass the target through env and use quoted printf for shell output; avoid interpolating steps.target.outputs.url into the summary line as well unless it is validated/escaped first.

🧰 Tools
🪛 zizmor (1.28.0)

[error] 32-32: code injection via template expansion (template-injection): may expand into attacker-controllable code

(template-injection)


[error] 33-33: code injection via template expansion (template-injection): may expand into attacker-controllable code

(template-injection)


[error] 34-34: code injection via template expansion (template-injection): may expand into attacker-controllable code

(template-injection)


[error] 35-35: code injection via template expansion (template-injection): may expand into attacker-controllable code

(template-injection)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/zap-security-scan.yml around lines 32 - 37, Update the
target-selection step to pass each external URL through the step environment
rather than interpolating it into the shell script, then emit the selected value
with quoted printf into GITHUB_OUTPUT. Also update the summary output to consume
the step output safely without directly embedding unvalidated
steps.target.outputs.url in shell source; validate or escape it before use.

Source: Linters/SAST tools

else
echo "No target URL available. Set STAGING_URL secret or provide target_url input."
exit 1
fi

- name: ZAP Baseline Passive Scan
id: zap
uses: zaproxy/action-baseline@v0.10.0

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🔴 Critical | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== workflow excerpt =="
if [ -f .github/workflows/zap-security-scan.yml ]; then
  nl -ba .github/workflows/zap-security-scan.yml | sed -n '1,80p'
else
  echo "missing .github/workflows/zap-security-scan.yml"
fi

echo
echo "== current action files in GitHub =="
tmpdir="$(mktemp -d)"
curl -fsSL -o "$tmpdir/action-current.yml" https://raw.githubusercontent.com/zaproxy/action-baseline/main/action.yml 2>/dev/null || true
curl -fsSL -o "$tmpdir/action-v010.yml" https://raw.githubusercontent.com/zaproxy/action-baseline/v0.10.0/action.yml 2>/dev/null || true
if [ -s "$tmpdir/action-current.yml" ] || [ -s "$tmpdir/action-v010.yml" ]; then
  node - <<'JS'
const fs = require('fs');
const path = require('path');
const files = [
  'current-main',
  'v0.10.0'
].map(k => ({ k, v: path.join(process.env.HOME === undefined ? '/tmp' : process.env.HOME, 'NOTUSED')) });
console.log("not executed");
JS
fi
for f in "$tmpdir"/action-*.yml; do
  [ -s "$f" ] || continue
  echo "--- $f ---"
  nl -ba "$f" | sed -n '1,80p'
done

echo
echo "== github-hosted runner node version facts =="
python3 - <<'PY'
from datetime import datetime
print("GitHub Actions runner node support window context:")
print("- Node.js 16 was removed from hosted-runners on 2024-11-12.")
print("The current v0.10.0 release pin should be examined for runs.using value.")
PY

Repository: ritik4ever/stellar-goal-vault

Length of output: 230


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== workflow excerpt =="
if [ -f .github/workflows/zap-security-scan.yml ]; then
  nl -ba .github/workflows/zap-security-scan.yml | sed -n '1,80p'
else
  echo "missing .github/workflows/zap-security-scan.yml"
fi

echo
echo "== current action files in GitHub =="
tmpdir="$(mktemp -d)"
curl -fsSL -o "$tmpdir/action-current.yml" https://raw.githubusercontent.com/zaproxy/action-baseline/main/action.yml || true
curl -fsSL -o "$tmpdir/action-v010.yml" https://raw.githubusercontent.com/zaproxy/action-baseline/v0.10.0/action.yml || true

for f in "$tmpdir"/action-*.yml; do
  [ -s "$f" ] || continue
  echo "--- $f ($(basename "$f")) ---"
  nl -ba "$f" | sed -n '1,80p'
done

echo
echo "== Node version references in zaps baseline repository tags =="
python3 - <<'PY'
import subprocess, json, re
tags = []
try:
  tags = json.loads(subprocess.check_output(["git", "ls-remote", "--tags", "https://github.com/zaproxy/action-baseline.git"], text=True))
except Exception as e:
  print("git ls-remote failed:", e)
for ref, sha in sorted(tags.items()):
    if "refs/tags/v0.10.0" in ref:
        print(ref, sha)
PY

Repository: ritik4ever/stellar-goal-vault

Length of output: 230


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== workflow excerpt =="
if [ -f .github/workflows/zap-security-scan.yml ]; then
  awk '{printf "%6d\t%s\n", NR, $0}' .github/workflows/zap-security-scan.yml | sed -n '1,100p'
else
  echo "missing .github/workflows/zap-security-scan.yml"
fi

echo
echo "== action.yml files =="
tmpdir="$(mktemp -d)"
curl -fsSL -o "$tmpdir/action-current.yml" https://raw.githubusercontent.com/zaproxy/action-baseline/main/action.yml || true
curl -fsSL -o "$tmpdir/action-v010.yml" https://raw.githubusercontent.com/zaproxy/action-baseline/v0.10.0/action.yml || true
curl -fsSL -o "$tmpdir/action-v011.yml" https://raw.githubusercontent.com/zaproxy/action-baseline/v0.11.0/action.yml || true

for f in "$tmpdir"/action-*.yml; do
  [ -s "$f" ] || continue
  echo "--- $f ($(basename "$f")) ---"
  awk '/^(name|runs):|^[[:space:]]*using:|^[[:space:]]*main:|^  node-version:/' "$f" || sed -n '1,80p' "$f"
done

echo
echo "== package manifests mentioning node versions =="
for p in package.json package-lock.json pnpm-lock.yaml yarn.lock; do
  if [ -f "$p" ]; then
    echo "--- $p ---"
    grep -nEi '"(node|engines|packageManager)|engines:' "$p" || true
  fi
done

Repository: ritik4ever/stellar-goal-vault

Length of output: 12632


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== zaps action tags/branch references =="
python3 - <<'PY'
import subprocess, sys
for ref_pat in [
    ["git", "ls-remote", "--exit-code", "--heads", "https://github.com/zaproxy/action-baseline.git"],
    ["git", "ls-remote", "--exit-code", "--tags", "https://github.com/zaproxy/action-baseline.git"],
]:
    cmd = ref_pat[:]
    try:
        out = subprocess.check_output(cmd, stderr=subprocess.DEVNULL, text=True)
    except subprocess.CalledProcessError as exc:
        print(" ".join(cmd), "no_match", file=sys.stderr)
        continue
    for line in out.splitlines():
        if "node" in line.lower() or "main" in line.lower():
            print(line)
PY

echo
echo "== report inputs from action manifests =="
tmpdir="$(mktemp -d)"
url='https://raw.githubusercontent.com/zaproxy/action-baseline/${REF}/action.yml'
for ref in v0.11.0 main; do
  curl -fsSL -o "$tmpdir/action-$ref.yml" "${url/\${REF}/$ref}" || continue
  echo "--- $ref input/output scan summary ---"
  awk '
    /^inputs:/,/^(outputs:|env:|runs:|branding:|name:)/ {print}
    /^outputs:/,/^(env:|runs:|branding:|name:)/ {print}
  ' "$tmpdir/action-$ref.yml"
done

Repository: ritik4ever/stellar-goal-vault

Length of output: 648


Upgrade the pinned ZAP action off Node16.

zaproxy/action-baseline@v0.10.0 still uses runs.using: node16, and the scan runs on ubuntu-latest where Node16 is no longer supported on hosted runners. Switch to the latest supported release that declares node20 and verify its input/output contract before merging.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/zap-security-scan.yml at line 45, Update the
zaproxy/action-baseline reference in the workflow to the latest supported
release that declares runs.using node20, and verify that its inputs and outputs
remain compatible with the existing scan step before merging.

with:
target: ${{ steps.target.outputs.url }}
cmd_options: '-I -T 60'
fail_action: true
Comment on lines +43 to +49

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== workflow excerpt =="
sed -n '1,140p' .github/workflows/zap-security-scan.yml

echo
echo "== zap-related files =="
rg -n "riskcode|fail_action|baseline|severity|counts|ZAP|zap" .github/workflows/zap-security-scan.yml .github 2>/dev/null || true

echo
echo "== action usage references =="
rg -n "zaproxy/action-baseline|fail_action|cmd_options" .github/workflows || true

Repository: ritik4ever/stellar-goal-vault

Length of output: 9179


🌐 Web query:

ZAP action baseline fail_action true WARN FAIL riskcode documentation

💡 Result:

In the context of the OWASP ZAP Baseline Scan GitHub Action, the fail_action parameter is used to control whether the GitHub workflow run status is marked as failed when ZAP identifies security alerts [1][2][3]. When set to true, the GitHub Action will fail if the underlying ZAP baseline scan identifies any alerts or fails to scan the target [2]. If set to false (the default), the action will report the results but will not fail the GitHub workflow status due to identified alerts [2][3]. Regarding the control of alert levels (WARN, FAIL, etc.), this is managed separately from the fail_action parameter. You can configure which rules trigger a failure using a ZAP configuration file [4][5]. In this file, you can change the alert level of specific rules to FAIL, which will cause the ZAP scan script itself to return a non-zero exit code, or IGNORE, which suppresses them [4][6][7]. The baseline scan script typically classifies alerts as WARN by default [5]. When running the ZAP Docker container, you can pass a configuration file using the -c command-line option to customize these rule levels [4][7]. In summary: - fail_action: true (in the GitHub Action) determines if the overall CI/CD job fails when any alerts are found [2]. - Configuration file (rules.tsv): Used to define which specific alert risk codes or rules should be treated as FAIL (causing the scan to exit with a failure code) or IGNORE (ignoring them entirely) [4][5]. Top results: [1], [2], [4], [5]

Citations:


Make the parsed medium/high alert count the gate.

fail_action: true makes this step fail when ZAP Baseline finds alerts, but Baseline rules default to WARN, and -I prevents warning rules from making the scan exit non-zero unless they are reconfigured as FAIL. The later explicit check counts riskcode == "2" and "3", so if the two paths disagree the summary can say deploy is blocked after the job already failed for unrelated warnings. Set fail_action: false and use the explicit report check as the workflow-level failure.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/zap-security-scan.yml around lines 43 - 49, Update the ZAP
Baseline Passive Scan step identified by id zap to set fail_action to false,
allowing the scan to complete without failing on its default alert handling.
Preserve the later explicit report check as the workflow-level gate based on
parsed medium and high risk counts.

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== workflow excerpt =="
if [ -f .github/workflows/zap-security-scan.yml ]; then
  nl -ba .github/workflows/zap-security-scan.yml | sed -n '1,120p'
else
  echo "workflow not found"
fi

echo
echo "== zap/action references =="
rg -n "zaproxy/action-baseline|action-baseline|report_json|report_html|report_md|results\.sarif|zap-report|sarif|sarif|artifacts|upload-artifact" .github/workflows || true

Repository: ritik4ever/stellar-goal-vault

Length of output: 230


🌐 Web query:

zaproxy action-baseline v0.10.0 report_json.json report_html.html report_md.md sarif

💡 Result:

The zaproxy/action-baseline GitHub Action, including version 0.10.0 [1][2], facilitates ZAP baseline scans by wrapping the ZAP Docker baseline scan script [3][4]. Regarding the requested report files (report_json.json, report_html.html, report_md.md) and SARIF support: 1. JSON, HTML, and Markdown Reports: The underlying ZAP baseline scan script supports generating these reports via command-line flags (-J, -r, -w) [5][6]. To use these with the GitHub Action, you must pass the corresponding flags through the cmd_options input [3][7]. For example, you could include: cmd_options: '-J report_json.json -r report_html.html -w report_md.md' 2. SARIF Support: The official action does not natively support SARIF report generation as a direct input or output field [7]. While ZAP has a SARIF report generator add-on [8][9], users typically must configure the underlying ZAP container to generate it via cmd_options or use third-party methods to convert ZAP output to SARIF for GitHub Advanced Security integration [9]. 3. Artifact Handling: By default, the action uploads an artifact named zap_scan [7]. If you generate additional files (like the specific report files requested) within the Docker container during the scan, they will not be automatically uploaded as GitHub workflow artifacts unless you explicitly configure the action or add a subsequent step to upload them using the official actions/upload-artifact action. Version 0.10.0 introduced support for authentication environment variables (ZAP_AUTH_HEADER, ZAP_AUTH_HEADER_VALUE, ZAP_AUTH_HEADER_SITE) [1][2], but did not introduce native support for the specific report formats listed in your query [2].

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

tool() {
  local name="$1"
  command -v "$name" >/dev/null 2>&1 && printf '%s\n' "$name"
}
for n in nl head sed grep awk find git; do
  echo "tool=$n"
  tool "$n"
done

echo "== workflow excerpt =="
if [ -f .github/workflows/zap-security-scan.yml ]; then
  awk '{printf "%5d\t%s\n", NR, $0}' .github/workflows/zap-security-scan.yml | sed -n '1,130p'
else
  echo "workflow not found"
fi

echo
echo "== zap/report references in workflows =="
grep -RInE "zaproxy/action-baseline|action-baseline|report_json|report_html|report_md|results\.sarif|zap-report|upload-artifact|sarif" .github/workflows .github 2>/dev/null || true

echo
echo "== fetch action metadata/release files =="
python3 - <<'PY'
import urllib.request
for url in [
    "https://raw.githubusercontent.com/zaproxy/action-baseline/v0.10.0/action.yml",
    "https://raw.githubusercontent.com/zaproxy/action-baseline/v0.10.0/dist/index.js",
    "https://raw.githubusercontent.com/zaproxy/action-baseline/v0.10.0/README.md",
]:
    print(f"\n--- {url} ---")
    try:
        data = urllib.request.urlopen(url, timeout=20).read().decode("utf-8", "replace")
    except Exception as e:
        print(f"ERROR: {e}")
        continue
    for term in ["report_json", "report_html", "report_md", "sarif", "commandOptions", "cmdOptions"]:
        if term in data:
            print(term)
    # print concise contexts around report paths
    for i, line in enumerate(data.splitlines(), 1):
        if "report_json" in line or "report_html" in line or "report_md" in line or "sarif" in line:
            start=max(1,i-3); end=min(len(data.splitlines()),i+3)
            lines=data.splitlines()
            for j in range(start,end+1):
                print(f"{j:5d}\t{lines[j-1]}")
PY

Repository: ritik4ever/stellar-goal-vault

Length of output: 175


Align the report paths with the baseline action output.

zaproxy/action-baseline@v0.10.0 emits report_json.json, report_html.html, and report_md.md; it does not create results.sarif or zap-report.*, so the SARIF upload and JSON enforcement steps will miss the generated reports. Use the emitted filenames for JSON/HTML processing, and add a separate SARIF-generation/conversion step if SARIF is required.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/zap-security-scan.yml around lines 43 - 49, The ZAP
workflow references report filenames that the baseline action does not generate.
Update the JSON and HTML processing steps to use report_json.json and
report_html.html, and update Markdown handling to use report_md.md; if SARIF
remains required, add a separate conversion step that produces the SARIF file
before upload.


- name: Upload SARIF report
if: always()
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: results.sarif
category: zap-scan

- name: Upload ZAP HTML report as artifact
if: always()
uses: actions/upload-artifact@v4
with:
name: zap-html-report
path: zap-report.html

- name: Check for high-severity findings
if: always()
run: |
if [ -f zap-report.json ]; then
HIGH_COUNT=$(jq '[.site[]?.alerts[]? | select(.riskcode == "3" or .riskcode == "2")] | length' zap-report.json 2>/dev/null || echo "0")
echo "## OWASP ZAP Scan Results" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "- **Target:** ${{ steps.target.outputs.url }}" >> $GITHUB_STEP_SUMMARY
echo "- **High-severity alerts:** $(jq '[.site[]?.alerts[]? | select(.riskcode == "3")] | length' zap-report.json 2>/dev/null || echo "0")" >> $GITHUB_STEP_SUMMARY
echo "- **Medium-severity alerts:** $(jq '[.site[]?.alerts[]? | select(.riskcode == "2")] | length' zap-report.json 2>/dev/null || echo "0")" >> $GITHUB_STEP_SUMMARY
echo "- **Low-severity alerts:** $(jq '[.site[]?.alerts[]? | select(.riskcode == "1")] | length' zap-report.json 2>/dev/null || echo "0")" >> $GITHUB_STEP_SUMMARY
if [ "$HIGH_COUNT" -gt 0 ]; then
echo "❌ **Deploy blocked:** $HIGH_COUNT high-severity or medium-severity findings detected." >> $GITHUB_STEP_SUMMARY
echo "Please review the ZAP report artifact for details."
exit 1
else
echo "✅ **No high-severity or medium-severity findings.** Scan passed." >> $GITHUB_STEP_SUMMARY
fi
else
echo "No ZAP JSON report found. Scan results may not be available."
fi
Comment on lines +68 to +85

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Fail closed when the report is missing or invalid.

jq errors are converted to zero counts, and the missing-report branch exits successfully. A failed or malformed scan can therefore appear to pass with no findings. Require a non-empty, schema-valid JSON report and exit nonzero on any parsing or publication failure.

🧰 Tools
🪛 zizmor (1.28.0)

[info] 72-72: code injection via template expansion (template-injection): may expand into attacker-controllable code

(template-injection)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/zap-security-scan.yml around lines 68 - 85, Update the ZAP
report handling around the zap-report.json existence check and jq count
calculations to fail closed: require a non-empty report, validate its
JSON/schema before counting alerts, and treat every jq or summary-publication
failure as an error. Ensure malformed or missing reports and failed writes to
GITHUB_STEP_SUMMARY exit nonzero instead of reporting a successful scan, while
preserving the existing blocking behavior for high- or medium-severity findings.