Skip to content
Merged
Show file tree
Hide file tree
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
62 changes: 62 additions & 0 deletions .github/workflows/shiftleft.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
---
# This workflow integrates Harness SAST and SCA with GitHub
# Visit https://docs.shiftleft.io for help
name: Harness SAST and SCA

on:
pull_request:
workflow_dispatch:

jobs:
NextGen-Static-Analysis:

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2: The workflow does not define a permissions block, so the GITHUB_TOKEN will inherit the repository's default permissions, which are often overly broad. Adding an explicit permissions block scoped to only what's needed (e.g., contents: read) follows the principle of least privilege and reduces blast radius if the workflow is compromised.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At .github/workflows/shiftleft.yml, line 11:

<comment>The workflow does not define a `permissions` block, so the `GITHUB_TOKEN` will inherit the repository's default permissions, which are often overly broad. Adding an explicit permissions block scoped to only what's needed (e.g., `contents: read`) follows the principle of least privilege and reduces blast radius if the workflow is compromised.</comment>

<file context>
@@ -0,0 +1,62 @@
+  workflow_dispatch:
+
+jobs:
+  NextGen-Static-Analysis:
+    runs-on: ubuntu-latest
+    steps:
</file context>

runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Found 2 issues:

1. credential persistence through GitHub Actions artifacts [zizmor:zizmor/artipacked]


2. the runner of "actions/checkout@v3" action is too old to run on GitHub Actions. update the action's version to fix this issue [actionlint:action]

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1: The workflow executes mutable action tags in a job that handles the SAST access token. Pin both third-party action references to full commit SHAs (with version comments) to make reviewed workflow execution reproducible.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At .github/workflows/shiftleft.yml, line 14:

<comment>The workflow executes mutable action tags in a job that handles the SAST access token. Pin both third-party action references to full commit SHAs (with version comments) to make reviewed workflow execution reproducible.</comment>

<file context>
@@ -0,0 +1,62 @@
+  NextGen-Static-Analysis:
+    runs-on: ubuntu-latest
+    steps:
+    - uses: actions/checkout@v3
+    - name: Setup Java JDK v8
+      uses: actions/setup-java@v3
</file context>

- name: Setup Java JDK v8
uses: actions/setup-java@v3

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

the runner of "actions/setup-java@v3" action is too old to run on GitHub Actions. update the action's version to fix this issue [actionlint:action]

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2: actions/setup-java@v3 uses a deprecated Node.js runtime version on GitHub-hosted runners. Update to actions/setup-java@v4 to ensure continued compatibility.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At .github/workflows/shiftleft.yml, line 16:

<comment>`actions/setup-java@v3` uses a deprecated Node.js runtime version on GitHub-hosted runners. Update to `actions/setup-java@v4` to ensure continued compatibility.</comment>

<file context>
@@ -0,0 +1,62 @@
+    steps:
+    - uses: actions/checkout@v3
+    - name: Setup Java JDK v8
+      uses: actions/setup-java@v3
+      with:
+        distribution: zulu
</file context>
Suggested change
uses: actions/setup-java@v3
uses: actions/setup-java@v4

with:
distribution: zulu
java-version: 8

- name: Download Harness SAST and SCA CLI
run: |
curl https://cdn.shiftleft.io/download/sl > ${GITHUB_WORKSPACE}/sl && chmod a+rx ${GITHUB_WORKSPACE}/sl

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1: This step executes an unpinned, unverified remote binary with SHIFTLEFT_ACCESS_TOKEN available to the next step. Pin a release artifact and verify its published checksum/signature before making it executable.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At .github/workflows/shiftleft.yml, line 23:

<comment>This step executes an unpinned, unverified remote binary with `SHIFTLEFT_ACCESS_TOKEN` available to the next step. Pin a release artifact and verify its published checksum/signature before making it executable.</comment>

<file context>
@@ -0,0 +1,62 @@
+
+    - name: Download Harness SAST and SCA CLI
+      run: |
+        curl https://cdn.shiftleft.io/download/sl > ${GITHUB_WORKSPACE}/sl && chmod a+rx ${GITHUB_WORKSPACE}/sl
+
+    - name: Static Analysis
</file context>


- name: Static Analysis
run: |

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

"github.head_ref" is potentially untrusted. avoid using it directly in inline scripts. instead, pass it through an environment variable. see https://docs\.github\.com/en/actions/reference/security/secure\-use\#good\-practices\-for\-mitigating\-script\-injection\-attacks for more details [actionlint:expression]

${GITHUB_WORKSPACE}/sl --version
${GITHUB_WORKSPACE}/sl analyze --strict --wait \
--app Tools \
--tag branch=${{ github.head_ref }} \

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

code injection via template expansion [zizmor:zizmor/template-injection]

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Bug: The github.head_ref variable is used for tagging, but it's empty on workflow_dispatch triggers, which will cause the sl analyze step to fail.
Severity: MEDIUM

Suggested Fix

Use a variable that is available for all trigger types, or provide a fallback. For example, you can use github.ref_name as it is populated for both pull_request and workflow_dispatch triggers. A robust expression would be ${{ github.head_ref || github.ref_name }}.

Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.

Location: .github/workflows/shiftleft.yml#L30

Potential issue: The workflow uses `github.head_ref` to tag the analysis branch. This
variable is only populated during `pull_request` events. Since the workflow can also be
triggered manually via `workflow_dispatch`, `github.head_ref` will be an empty string in
that context. This will cause the `sl analyze` command to be run with an empty branch
tag (`--tag branch=`), which will cause the step to fail because `--strict` mode is
enabled.

Did we get this right? 👍 / 👎 to inform future reviews.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1: When this workflow is triggered manually via workflow_dispatch, the branch tag will be empty because github.head_ref is only available for pull_request events. This means --tag branch= will be passed with no value, which can produce untagged/mislabeled analysis results in the Harness platform. Consider using ${{ github.head_ref || github.ref_name }} or splitting the tag assignment into a conditional step to handle both trigger types correctly.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At .github/workflows/shiftleft.yml, line 30:

<comment>When this workflow is triggered manually via `workflow_dispatch`, the branch tag will be empty because `github.head_ref` is only available for `pull_request` events. This means `--tag branch=` will be passed with no value, which can produce untagged/mislabeled analysis results in the Harness platform. Consider using `${{ github.head_ref || github.ref_name }}` or splitting the tag assignment into a conditional step to handle both trigger types correctly.</comment>

<file context>
@@ -0,0 +1,62 @@
+        ${GITHUB_WORKSPACE}/sl --version
+        ${GITHUB_WORKSPACE}/sl analyze --strict --wait \
+          --app Tools \
+          --tag branch=${{ github.head_ref }} \
+          --js $(pwd) -- --ts
+      env:
</file context>

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1: Using ${{ github.head_ref }} directly in a run: step is a script injection vulnerability. An attacker can craft a branch name containing shell metacharacters or injected commands (e.g., '; malicious-command #) which will be interpolated directly into the shell script before execution.

Pass the value through an environment variable instead:

env:
  BRANCH_NAME: ${{ github.head_ref || github.ref_name }}
run: |
  ... --tag branch=${BRANCH_NAME} ...
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At .github/workflows/shiftleft.yml, line 30:

<comment>Using `${{ github.head_ref }}` directly in a `run:` step is a script injection vulnerability. An attacker can craft a branch name containing shell metacharacters or injected commands (e.g., `'; malicious-command #`) which will be interpolated directly into the shell script before execution.

Pass the value through an environment variable instead:
```yaml
env:
  BRANCH_NAME: ${{ github.head_ref || github.ref_name }}
run: |
  ... --tag branch=${BRANCH_NAME} ...
```</comment>

<file context>
@@ -0,0 +1,62 @@
+        ${GITHUB_WORKSPACE}/sl --version
+        ${GITHUB_WORKSPACE}/sl analyze --strict --wait \
+          --app Tools \
+          --tag branch=${{ github.head_ref }} \
+          --js $(pwd) -- --ts
+      env:
</file context>

--js $(pwd) -- --ts
env:
SHIFTLEFT_ACCESS_TOKEN: ${{ secrets.SHIFTLEFT_ACCESS_TOKEN }}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2: Fork-originated PRs run sl analyze with an empty access token, so this required scan/status check will fail for external contributors. Gate this authenticated step for non-fork PRs, or configure a supported unauthenticated fork-scanning path.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At .github/workflows/shiftleft.yml, line 33:

<comment>Fork-originated PRs run `sl analyze` with an empty access token, so this required scan/status check will fail for external contributors. Gate this authenticated step for non-fork PRs, or configure a supported unauthenticated fork-scanning path.</comment>

<file context>
@@ -0,0 +1,62 @@
+          --tag branch=${{ github.head_ref }} \
+          --js $(pwd) -- --ts
+      env:
+        SHIFTLEFT_ACCESS_TOKEN: ${{ secrets.SHIFTLEFT_ACCESS_TOKEN }}
+        SHIFTLEFT_API_HOST: www.shiftleft.io
+        SHIFTLEFT_GRPC_TELEMETRY_HOST: telemetry.shiftleft.io:443
</file context>

SHIFTLEFT_API_HOST: www.shiftleft.io
SHIFTLEFT_GRPC_TELEMETRY_HOST: telemetry.shiftleft.io:443
SHIFTLEFT_GRPC_API_HOST: api.shiftleft.io:443

# Build-Rules:

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2: The Build-Rules job is entirely commented out, which means the security policies defined in shiftleft.yml (blocking critical findings, reachable OSS vulnerabilities) will never be enforced. PRs with critical vulnerabilities can pass CI without any security gate. If this is intentional for initial setup, consider adding a TODO or timeline for enabling it.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At .github/workflows/shiftleft.yml, line 38:

<comment>The `Build-Rules` job is entirely commented out, which means the security policies defined in `shiftleft.yml` (blocking critical findings, reachable OSS vulnerabilities) will never be enforced. PRs with critical vulnerabilities can pass CI without any security gate. If this is intentional for initial setup, consider adding a TODO or timeline for enabling it.</comment>

<file context>
@@ -0,0 +1,62 @@
+        SHIFTLEFT_GRPC_TELEMETRY_HOST: telemetry.shiftleft.io:443
+        SHIFTLEFT_GRPC_API_HOST: api.shiftleft.io:443
+
+#   Build-Rules:
+#     runs-on: ubuntu-latest
+#     permissions: write-all
</file context>

# runs-on: ubuntu-latest
# permissions: write-all
# needs: NextGen-Static-Analysis
# steps:
# - uses: actions/checkout@v3
# - name: Download Harness SAST and SCA CLI
# run: |
# curl https://cdn.shiftleft.io/download/sl > ${GITHUB_WORKSPACE}/sl && chmod a+rx ${GITHUB_WORKSPACE}/sl
# - name: Validate Build Rules
# run: |
# ${GITHUB_WORKSPACE}/sl check-analysis --app Tools \
# --github-pr-number=${{github.event.number}} \
# --github-pr-user=${{ github.repository_owner }} \
# --github-pr-repo=${{ github.event.repository.name }} \
# --github-token=${{ secrets.GITHUB_TOKEN }}
# env:
# # SHIFTLEFT_ACCESS_TOKEN: ${{ secrets.SHIFTLEFT_ACCESS_TOKEN }}
#
# SHIFTLEFT_API_HOST: www.shiftleft.io
# SHIFTLEFT_GRPC_TELEMETRY_HOST: telemetry.shiftleft.io:443
# SHIFTLEFT_GRPC_API_HOST: api.shiftleft.io:443
#
Comment on lines +12 to +60
Comment on lines +50 to +60

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Bug: The Build-Rules job is commented out, which disables all security policy enforcement, allowing PRs with critical vulnerabilities to be merged.
Severity: CRITICAL

Suggested Fix

Uncomment the Build-Rules job (lines 38-60) to re-enable the security policy checks. Additionally, ensure the SHIFTLEFT_ACCESS_TOKEN secret is correctly configured and uncommented within the job's environment variables.

Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.

Location: .github/workflows/shiftleft.yml#L38-L60

Potential issue: The `Build-Rules` job, which is responsible for enforcing security
policies by running `sl check-analysis`, is completely commented out. This means that
security rules defined in the `shiftleft.yml` file, such as blocking critical findings
or reachable OSS vulnerabilities, are never evaluated. As a result, pull requests
containing critical security vulnerabilities will pass CI checks, defeating the purpose
of the security scan.

Did we get this right? 👍 / 👎 to inform future reviews.



Copy link
Copy Markdown

Choose a reason for hiding this comment

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

overly broad permissions [zizmor:zizmor/excessive-permissions]

15 changes: 15 additions & 0 deletions shiftleft.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
version: 2
build_rules:
- id: Allow no critical findings
severities:
- critical
- id: Allow one OSS or container finding
finding_types:
- oss_vuln
- container
threshold: 1
- id: Allow no reachable OSS vulnerability
finding_types:
- oss_vuln
options:
reachable: true
Loading