Skip to content
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
8272d13
Planning: AIML-337 - Command allowlist validation
Dec 23, 2025
30262c5
AIML-337: Complete command validation module implementation
Dec 23, 2025
56cf0fa
AIML-337: Document learnings from bead contrast-ai-smartfix-action-gad
Dec 23, 2025
2d2c626
AIML-337: Integrate command validation into Config class
Dec 23, 2025
2cc7843
AIML-337: Document learnings from bead contrast-ai-smartfix-action-8re
Dec 23, 2025
00adcd1
AIML-337: Add command allowlist security documentation
Dec 23, 2025
321146a
AIML-337: Document learnings from bead wuv
Dec 23, 2025
68147f0
AIML-337: Fix linting - remove unused import
Dec 23, 2025
d5720a9
fix: resolve critical security vulnerabilities in command validation
Dec 23, 2025
7e73ebf
feat(test): add LLM-as-judge prompt for SmartFix PR reviews
Dec 23, 2025
0a390b2
chore: ignore local development artifacts
Dec 23, 2025
f25622c
chore: update beads and remove learnings from tracking
Dec 23, 2025
ad82cdc
chore: remove docs/plans from tracking per .gitignore
Dec 23, 2025
04ebcf3
AIML-337: Add beads for command allowlist updates
Jan 7, 2026
1ff9f39
AIML-337: Add source parameter to _validate_command
Jan 8, 2026
2c1d67a
chore: close bead ue9 - source parameter implementation complete
Jan 8, 2026
95d9eaa
AIML-337: Add comprehensive tests for source parameter
Jan 8, 2026
5ebd95a
chore: close bead ix3 - test coverage complete
Jan 8, 2026
f3533ea
AIML-337: Add sbt to command allowlist
Jan 8, 2026
33d6dc3
chore: close bead t5c - sbt added to allowlist
Jan 8, 2026
5f44752
AIML-337: Add error logging to command validation
Jan 8, 2026
f649c83
chore: close bead 6t4 - error logging complete
Jan 8, 2026
0d167ad
chore: sync final bead state for AIML-337
Jan 8, 2026
cf21d97
chore: sync beads state - removed completed AIML-337 beads
Jan 8, 2026
e296d84
AIML-337 Revise documentation since we changed this to trust commands…
Jan 8, 2026
be16c69
Merge branch 'main' into AIML-337_command-allowlist-validation
JacobMagesHaskinsContrast Jan 8, 2026
32560de
AIML-337: Update beads state for completed work
Jan 8, 2026
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
32 changes: 32 additions & 0 deletions .beads/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# SQLite databases
*.db
*.db?*
*.db-journal
*.db-wal
*.db-shm

# Daemon runtime files
daemon.lock
daemon.log
daemon.pid
bd.sock

# Local version tracking (prevents upgrade notification spam after git ops)
.local_version

# Legacy database files
db.sqlite
bd.db

# Merge artifacts (temporary files from 3-way merge)
beads.base.jsonl
beads.base.meta.json
beads.left.jsonl
beads.left.meta.json
beads.right.jsonl
beads.right.meta.json

# Keep JSONL exports and config (source of truth for git)
!issues.jsonl
!metadata.json
!config.json
81 changes: 81 additions & 0 deletions .beads/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# Beads - AI-Native Issue Tracking

Welcome to Beads! This repository uses **Beads** for issue tracking - a modern, AI-native tool designed to live directly in your codebase alongside your code.

## What is Beads?

Beads is issue tracking that lives in your repo, making it perfect for AI coding agents and developers who want their issues close to their code. No web UI required - everything works through the CLI and integrates seamlessly with git.

**Learn more:** [github.com/steveyegge/beads](https://github.com/steveyegge/beads)

## Quick Start

### Essential Commands

```bash
# Create new issues
bd create "Add user authentication"

# View all issues
bd list

# View issue details
bd show <issue-id>

# Update issue status
bd update <issue-id> --status in_progress
bd update <issue-id> --status done

# Sync with git remote
bd sync
```

### Working with Issues

Issues in Beads are:
- **Git-native**: Stored in `.beads/issues.jsonl` and synced like code
- **AI-friendly**: CLI-first design works perfectly with AI coding agents
- **Branch-aware**: Issues can follow your branch workflow
- **Always in sync**: Auto-syncs with your commits

## Why Beads?

**AI-Native Design**
- Built specifically for AI-assisted development workflows
- CLI-first interface works seamlessly with AI coding agents
- No context switching to web UIs

🚀 **Developer Focused**
- Issues live in your repo, right next to your code
- Works offline, syncs when you push
- Fast, lightweight, and stays out of your way

🔧 **Git Integration**
- Automatic sync with git commits
- Branch-aware issue tracking
- Intelligent JSONL merge resolution

## Get Started with Beads

Try Beads in your own projects:

```bash
# Install Beads
curl -sSL https://raw.githubusercontent.com/steveyegge/beads/main/scripts/install.sh | bash

# Initialize in your repo
bd init

# Create your first issue
bd create "Try out Beads"
```

## Learn More

- **Documentation**: [github.com/steveyegge/beads/docs](https://github.com/steveyegge/beads/tree/main/docs)
- **Quick Start Guide**: Run `bd quickstart`
- **Examples**: [github.com/steveyegge/beads/examples](https://github.com/steveyegge/beads/tree/main/examples)

---

*Beads: Issue tracking that moves at the speed of thought*
62 changes: 62 additions & 0 deletions .beads/config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# Beads Configuration File
# This file configures default behavior for all bd commands in this repository
# All settings can also be set via environment variables (BD_* prefix)
# or overridden with command-line flags

# Issue prefix for this repository (used by bd init)
# If not set, bd init will auto-detect from directory name
# Example: issue-prefix: "myproject" creates issues like "myproject-1", "myproject-2", etc.
# issue-prefix: ""

# Use no-db mode: load from JSONL, no SQLite, write back after each command
# When true, bd will use .beads/issues.jsonl as the source of truth
# instead of SQLite database
# no-db: false

# Disable daemon for RPC communication (forces direct database access)
# no-daemon: false

# Disable auto-flush of database to JSONL after mutations
# no-auto-flush: false

# Disable auto-import from JSONL when it's newer than database
# no-auto-import: false

# Enable JSON output by default
# json: false

# Default actor for audit trails (overridden by BD_ACTOR or --actor)
# actor: ""

# Path to database (overridden by BEADS_DB or --db)
# db: ""

# Auto-start daemon if not running (can also use BEADS_AUTO_START_DAEMON)
# auto-start-daemon: true

# Debounce interval for auto-flush (can also use BEADS_FLUSH_DEBOUNCE)
# flush-debounce: "5s"

# Git branch for beads commits (bd sync will commit to this branch)
# IMPORTANT: Set this for team projects so all clones use the same sync branch.
# This setting persists across clones (unlike database config which is gitignored).
# Can also use BEADS_SYNC_BRANCH env var for local override.
# If not set, bd sync will require you to run 'bd config set sync.branch <branch>'.
# sync-branch: "beads-sync"

# Multi-repo configuration (experimental - bd-307)
# Allows hydrating from multiple repositories and routing writes to the correct JSONL
# repos:
# primary: "." # Primary repo (where this database lives)
# additional: # Additional repos to hydrate from (read-only)
# - ~/beads-planning # Personal planning repo
# - ~/work-planning # Work planning repo

# Integration settings (access with 'bd config get/set')
# These are stored in the database, not in this file:
# - jira.url
# - jira.project
# - linear.url
# - linear.api-key
# - github.org
# - github.repo
5 changes: 5 additions & 0 deletions .beads/issues.jsonl
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{"id":"contrast-ai-smartfix-action-8re","title":"Integrate validation into Config class","description":"Integrate command validation into src/config.py Config.__init__():\n- Import command_validator module\n- Add _validate_command() method to Config class\n- Call validation for BUILD_COMMAND after reading from environment (line ~82)\n- Call validation for FORMATTING_COMMAND after reading from environment (line ~84)\n- Ensure CommandValidationError is caught and converted to ConfigurationError\n- Follow existing config validation patterns (similar to _check_contrast_config_values_exist)\n- Maintain fail-fast behavior with clear error messages\n\nRelated to JIRA: AIML-337","status":"closed","priority":1,"issue_type":"task","created_at":"2025-12-23T09:50:37.859629-05:00","updated_at":"2025-12-23T10:34:27.5546-05:00","closed_at":"2025-12-23T10:34:27.5546-05:00","dependencies":[{"issue_id":"contrast-ai-smartfix-action-8re","depends_on_id":"contrast-ai-smartfix-action-gad","type":"blocks","created_at":"2025-12-23T09:51:11.594923-05:00","created_by":"daemon"}]}
{"id":"contrast-ai-smartfix-action-gad","title":"Create command validation module","description":"Create src/smartfix/config/command_validator.py with:\n- ALLOWED_COMMANDS constant (full allowlist for Java, .NET, Python, PHP, NodeJS, build tools, shell utilities)\n- BLOCKED_PATTERNS regex list (command substitution, eval, exec, dangerous operations)\n- validate_shell_command() - ensures sh/bash only execute .sh files, blocks -c flag\n- validate_redirect() - allows relative paths only, blocks absolute paths and .. traversal\n- contains_dangerous_patterns() - checks command against blocked patterns\n- split_command_chain() - parses commands by operators (\u0026\u0026, ||, ;, |)\n- parse_command_segment() - extracts executable and arguments from command segment\n- extract_redirects() - finds file redirects in command\n- validate_command() - main validation function that orchestrates all checks\n- CommandValidationError exception class\n\nRelated to JIRA: AIML-337","status":"closed","priority":1,"issue_type":"task","created_at":"2025-12-23T09:49:50.169966-05:00","updated_at":"2025-12-23T10:28:03.234049-05:00","closed_at":"2025-12-23T10:28:03.234049-05:00"}
{"id":"contrast-ai-smartfix-action-q9y","title":"Create comprehensive test suite for command validation","description":"Create test/test_command_validation.py with comprehensive test coverage:\n- Test all allowed commands validate successfully (Java, .NET, Python, PHP, NodeJS, build tools)\n- Test blocked executables are rejected with proper error messages\n- Test command chaining with operators (\u0026\u0026, ||, ;, |)\n- Test shell script execution: sh/bash with .sh files allowed, -c flag blocked\n- Test redirect validation: relative paths pass, absolute paths and .. traversal fail\n- Test dangerous pattern detection: command substitution, eval, exec, piping to shell\n- Test edge cases: empty commands, whitespace, special characters, complex chains\n- Test error messages are clear and actionable\n- Ensure all tests pass and maintain existing test coverage (165+ tests)\n\nRelated to JIRA: AIML-337","status":"closed","priority":2,"issue_type":"task","created_at":"2025-12-23T09:51:20.598647-05:00","updated_at":"2025-12-23T10:35:10.53909-05:00","closed_at":"2025-12-23T10:35:10.53909-05:00","dependencies":[{"issue_id":"contrast-ai-smartfix-action-q9y","depends_on_id":"contrast-ai-smartfix-action-gad","type":"blocks","created_at":"2025-12-23T09:51:56.723262-05:00","created_by":"daemon"},{"issue_id":"contrast-ai-smartfix-action-q9y","depends_on_id":"contrast-ai-smartfix-action-8re","type":"blocks","created_at":"2025-12-23T09:51:56.843412-05:00","created_by":"daemon"}]}
{"id":"contrast-ai-smartfix-action-wuv","title":"Update documentation for command allowlist","description":"Update README.md and related documentation:\n- Add new section explaining command allowlist security feature\n- Document all allowed commands organized by language/ecosystem\n- Document allowed operators for chaining (\u0026\u0026, ||, ;, |)\n- Document allowed redirect patterns (relative paths only)\n- Provide examples of valid commands for each language\n- Provide examples of blocked commands and why they fail\n- Document error messages users might encounter\n- Add troubleshooting section for common validation failures\n- Update security.md if present to mention this security feature\n\nRelated to JIRA: AIML-337","status":"closed","priority":3,"issue_type":"task","created_at":"2025-12-23T09:52:22.925762-05:00","updated_at":"2025-12-23T10:40:22.502328-05:00","closed_at":"2025-12-23T10:40:22.502328-05:00","dependencies":[{"issue_id":"contrast-ai-smartfix-action-wuv","depends_on_id":"contrast-ai-smartfix-action-q9y","type":"blocks","created_at":"2025-12-23T09:52:26.450395-05:00","created_by":"daemon"}]}
{"id":"contrast-ai-smartfix-action-z4l","title":"Create LLM-as-judge prompt for E2E test repo PR reviews","description":"Create a reusable code review prompt for evaluating SmartFix's cybersecurity fixes in E2E test repos.\n\nPROMPT STRUCTURE:\n1. **Discovery Phase**\n - Fetch open PRs using gh CLI\n - Identify PRs created by SmartFix\n - Extract vulnerability description from PR body\n - Identify vulnerability type (SQL injection, XSS, path traversal, etc.)\n\n2. **Evaluation Criteria (Vulnerability-Agnostic)**\n - Does the fix address the specific vulnerability described in PR body?\n - Are all attack vectors for that vulnerability type blocked?\n - Input validation appropriate for the vulnerability type\n - Output encoding/sanitization where needed\n - No introduction of new vulnerabilities\n - Test coverage for the specific vulnerability\n\n3. **Review Process**\n - Parse PR body to understand the vulnerability\n - Fetch PR diff and files changed\n - Analyze if code changes eliminate the vulnerability\n - Check for incomplete fixes or edge cases\n - **CRITICAL: If any problems are flagged:**\n - Read surrounding code context (not just the diff)\n - Trace the data flow to confirm the vulnerability path\n - Verify the issue truly exists before reporting it\n - Check if existing code already handles the concern\n - Avoid false positives by validating assumptions\n - Verify test cases cover the vulnerability scenario\n - Assess if fix follows security best practices for that vuln type\n\n4. **Report Format**\n - Vulnerability type and description (from PR)\n - Fix effectiveness assessment\n - Does fix address the vulnerability? (YES/NO/PARTIAL)\n - Strengths of the fix\n - Gaps or weaknesses in the fix (ONLY if confirmed by reading surrounding code)\n - Attack vectors still exploitable (if any, with code evidence)\n - Test coverage assessment\n - Recommendations for improvement\n\nLOCATION:\ntest/prompts/smartfix-security-review.md\n\nUSAGE:\nUser runs Claude Code in E2E test repo and provides the prompt, which instructs Claude to review all open SmartFix PRs by matching code changes against the vulnerability described in each PR body.","status":"closed","priority":2,"issue_type":"task","created_at":"2025-12-23T13:12:19.227567-05:00","updated_at":"2025-12-23T13:52:04.993954-05:00","closed_at":"2025-12-23T13:52:04.993954-05:00"}
4 changes: 4 additions & 0 deletions .beads/metadata.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"database": "beads.db",
"jsonl_export": "issues.jsonl"
}
3 changes: 3 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@

# Use bd merge for beads JSONL files
.beads/issues.jsonl merge=beads
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -178,3 +178,10 @@ cython_debug/

# PyPI configuration file
.pypirc

# bv (beads viewer) local config and caches
.bv/

# Local development and planning artifacts
docs/plans/
.claude/learnings/
139 changes: 139 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,145 @@ Please follow the specific setup instructions link for the coding agent of your
* **Configurable PR Throttling:** Control the volume of automated PRs using `max_open_prs`.
* **Debug Mode:** Enable `debug_mode: 'true'` for verbose logging in the GitHub Action output.

## Security

### Command Allowlist

SmartFix validates all build and format commands against a security allowlist to prevent arbitrary command execution in GitHub Actions workflows. This protection applies to the `BUILD_COMMAND` and `FORMATTING_COMMAND` configuration parameters.

#### Allowed Commands

Commands are organized by language ecosystem:

**Java:**
- `mvn`, `gradle`, `ant`, `junit`, `testng`
- `./gradlew`, `./mvnw`, `gradlew`, `mvnw`
- `google-java-format`, `checkstyle`

**.NET:**
- `dotnet`, `msbuild`, `nuget`
- `nunit-console`, `nunit3-console`, `xunit.console`, `vstest.console`, `mstest`
- `csharpier`

**Python:**
- `pip`, `pip3`, `python`, `python3`
- `pytest`, `nose2`, `unittest`, `coverage`
- `poetry`, `pipenv`, `uv`, `tox`, `virtualenv`
- `black`, `autopep8`, `yapf`, `isort`, `ruff`, `flake8`, `pylint`

**Node.js/JavaScript/TypeScript:**
- `npm`, `npx`, `yarn`, `node`, `pnpm`, `bun`
- `jest`, `mocha`, `jasmine`, `karma`, `ava`, `vitest`, `nyc`
- `prettier`, `eslint`, `standard`

**PHP:**
- `composer`, `php`, `phpunit`, `pest`, `codeception`
- `php-cs-fixer`, `phpcbf`

**Build Tools & Utilities:**
- `make`, `cmake`, `ninja`, `bazel`, `ctest`
- `echo`, `sh`, `bash`, `grep`, `sed`, `awk`, `cat`, `tee`
- `clang-format` (multi-language)

#### Allowed Operators

Commands can be chained using these operators:
- `&&` (sequential execution)
- `||` (fallback execution)
- `;` (command separator)
- `|` (pipe)

#### File Redirects

File redirects are allowed with these restrictions:
- ✅ Relative paths: `npm test > build.log`
- ✅ Append mode: `npm test >> output.txt`
- ✅ Error redirect: `npm test 2> error.log`
- ❌ Absolute paths: `npm test > /etc/passwd`
- ❌ Parent traversal: `npm test > ../../sensitive.txt`
- ❌ Home directory: `npm test > ~/secrets.txt`

#### Shell Command Restrictions

Shell commands (`sh`/`bash`) have special restrictions:
- ✅ Allowed: `sh ./build.sh`, `bash ./scripts/test.sh`
- ❌ Blocked: `sh -c "command"`, `bash -c 'code'`
- Must execute `.sh` files only

#### Blocked Patterns

These dangerous patterns are automatically blocked:
- Command substitution: `$(...)` or `` `...` ``
- Variable expansion: `${...}`
- Execution commands: `eval`, `exec`
- Dangerous operations: `rm -rf`
- Piping to shell: `curl ... | sh`, `wget ... | bash`
- Device access: `> /dev/...`

#### Examples

**Valid Commands:**
```bash
# Java
BUILD_COMMAND="mvn clean install && mvn test"

# Python
BUILD_COMMAND="pip install -r requirements.txt && pytest tests/"
FORMATTING_COMMAND="black . && isort ."

# Node.js
BUILD_COMMAND="npm install && npm test"
FORMATTING_COMMAND="prettier --write ."

# With output redirect
BUILD_COMMAND="npm test > test-results.log 2>&1"
```

**Invalid Commands (Will Be Rejected):**
```bash
# Disallowed executable
BUILD_COMMAND="wget https://example.com/script.sh"
# Error: uses disallowed command: wget

# Dangerous pattern
BUILD_COMMAND="npm install && rm -rf node_modules"
# Error: contains dangerous pattern: \brm\s+-rf

# Command substitution
BUILD_COMMAND="echo $(whoami)"
# Error: contains dangerous pattern: \$\(

# Shell inline execution
BUILD_COMMAND="sh -c 'npm install'"
# Error: shell commands can only execute .sh files

# Unsafe redirect
BUILD_COMMAND="npm test > /etc/passwd"
# Error: unsafe file redirect: /etc/passwd
```

#### Troubleshooting

**Error: "uses disallowed command"**
- Verify the command is in the allowed list above
- Check for typos in command names
- Ensure you're using standard build/test/format tools

**Error: "contains dangerous pattern"**
- Remove command substitution (`$(...)` or `` `...` ``)
- Avoid `eval`, `exec`, or `rm -rf`
- Don't pipe downloads to shell interpreters

**Error: "shell command incorrectly"**
- Shell commands must execute `.sh` files: `sh ./script.sh`
- Don't use `-c` flag for inline execution
- Create a shell script file if needed

**Error: "unsafe file redirect"**
- Use relative paths only: `> build.log` not `> /tmp/build.log`
- Avoid parent directory traversal: `../` patterns
- Don't redirect to home directory: `~/`

## FAQ

* **Q: Can I use SmartFix if I don't use Contrast Assess?**
Expand Down
19 changes: 19 additions & 0 deletions security.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,25 @@ Contrast will send a response indicating the next steps in handling your report.

Report security bugs in third-party modules to the person or team maintaining the module.

## Security Features

### Command Allowlist Validation

SmartFix includes built-in security controls to prevent arbitrary command execution in GitHub Actions workflows. All build and format commands are validated against a strict allowlist before execution.

**Protected Configuration:**
- `BUILD_COMMAND` - Validated against allowed build tools and test frameworks
- `FORMATTING_COMMAND` - Validated against allowed code formatters

**Security Controls:**
- ✅ Allowlist of approved executables (build tools, test frameworks, formatters)
- ✅ Dangerous pattern detection (command substitution, eval, exec, rm -rf)
- ✅ Shell command restrictions (no inline execution via -c flag)
- ✅ File redirect validation (relative paths only, no traversal attacks)
- ✅ Operator validation (only safe command chaining)

For detailed information about allowed commands and security restrictions, see the [Command Allowlist section in the README](README.md#command-allowlist).

## Learning More About Security

To learn more about securing your applications with Contrast, please see the [our docs](https://docs.contrastsecurity.com/?lang=en).
Loading