Skip to content

Conversation

justin808
Copy link
Member

@justin808 justin808 commented Oct 5, 2025

Summary

This PR addresses the security vulnerability and code quality issues identified in #9:

Security Improvements

  • Fixed command injection vulnerability in pre_flight_checks.rb by replacing unsafe backtick execution with Open3.capture2
  • Added validation for GitHub repo and branch names to prevent command injection attacks
  • Ensured safe command execution patterns throughout the codebase

Code Quality Improvements

  • Extracted duplicated GitHub spec parsing logic into shared GitHubSpecParser module
  • Removed duplicated parse_github_spec, validate_github_repo, and validate_github_branch methods from DemoCreator
  • Improved error handling for npm package building with detailed, actionable error messages
  • Updated specs to use Open3.capture2 mocking for consistency

Changes

New Files

  • lib/demo_scripts/github_spec_parser.rb - Shared utility module for GitHub spec parsing and validation

Modified Files

  • lib/demo_scripts.rb - Added require for new GitHubSpecParser module
  • lib/demo_scripts/pre_flight_checks.rb - Fixed command injection using Open3.capture2, included GitHubSpecParser module
  • lib/demo_scripts/demo_creator.rb - Removed duplicated methods, included GitHubSpecParser module, improved error handling
  • spec/demo_scripts/pre_flight_checks_spec.rb - Updated mocks to use Open3.capture2

Test Results

All tests pass: 111 examples, 0 failures

bundle exec rspec
Finished in 0.07448 seconds
111 examples, 0 failures

RuboCop: 36 files inspected, no offenses detected

Security Impact

High Priority: This fixes a command injection vulnerability where user-controlled input (GitHub repo/branch names) could potentially be used to execute arbitrary commands. The fix:

  1. Replaces backtick execution with Open3.capture2 which safely passes arguments
  2. Validates all input before use to ensure it conforms to expected formats
  3. Uses array-based command execution to prevent shell injection

Fixes #9

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Improved parsing and validation for GitHub repo/branch inputs; parser reused across flows.
    • Dry-run respects early exit during GitHub package builds.
  • Bug Fixes

    • Safer command execution for branch verification and stronger branch-existence checks.
    • Clearer, actionable errors when GitHub-based builds fail; fewer failures from invalid inputs.
  • Refactor

    • Extracted GitHub spec parsing into a reusable component.
  • Tests

    • Expanded tests covering parsing, validation, and command-execution behavior.

Security improvements:
- Replace unsafe backtick command execution with Open3.capture2 in pre_flight_checks.rb
- Add validation for GitHub repo and branch names to prevent command injection
- Use safe command execution patterns throughout

Code quality improvements:
- Extract duplicated GitHub spec parsing logic into shared GitHubSpecParser module
- Remove duplicated parse_github_spec, validate_github_repo, and validate_github_branch methods from DemoCreator
- Improve error handling for npm package building with detailed error messages
- Update specs to use Open3.capture2 mocking instead of backtick mocking

All existing tests pass (111 examples, 0 failures)

Fixes #9

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Copy link

coderabbitai bot commented Oct 5, 2025

Walkthrough

Adds a new DemoScripts::GitHubSpecParser module and integrates it into loader, DemoCreator, and PreFlightChecks. Replaces backtick git calls with Open3.capture2, centralizes repo/branch parsing/validation, and adds targeted error handling around GitHub npm package builds. Tests adjusted and new specs added.

Changes

Cohort / File(s) Summary
Loader update
lib/demo_scripts.rb
Adds require_relative 'demo_scripts/github_spec_parser' to load the new parser module during initialization.
GitHub spec parser
lib/demo_scripts/github_spec_parser.rb
New DemoScripts::GitHubSpecParser module providing parse_github_spec, validate_github_repo, and validate_github_branch with strict validation and error raising.
Demo creation
lib/demo_scripts/demo_creator.rb
DemoCreator now includes GitHubSpecParser; in-file parsing helpers removed; build_github_npm_package gains early return for @dry_run and added rescue blocks (CommandError, IOError, SystemCallError) to surface detailed build errors.
Pre-flight checks
lib/demo_scripts/pre_flight_checks.rb
PreFlightChecks now includes GitHubSpecParser; replaces backtick git ls-remote with Open3.capture2; validates repo/branch before checking remote; treats empty stdout or non-success status as missing branch.
Specs — PreFlightChecks
spec/demo_scripts/pre_flight_checks_spec.rb
Tests adapted to mock Open3.capture2 and check status.success?/stdout behavior instead of mocking backticks; default-branch behavior preserved.
Specs — DemoCreator
spec/demo_scripts/demo_creator_spec.rb
Tests for build_github_npm_package instantiate DemoCreator with dry_run: false for those examples to exercise real build path.
Specs — GitHubSpecParser
spec/demo_scripts/github_spec_parser_spec.rb
New comprehensive test suite covering parsing and validation rules, accepted/rejected repo and branch patterns, and error cases.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant User
  participant PreFlightChecks
  participant GitHubSpecParser as Parser
  participant Open3

  User->>PreFlightChecks: check_github_branch_exists(github_spec)
  PreFlightChecks->>Parser: parse_github_spec(github_spec)
  Parser-->>PreFlightChecks: [repo, branch]
  PreFlightChecks->>Parser: validate_github_repo(repo), validate_github_branch(branch)
  PreFlightChecks->>Open3: capture2("git","ls-remote","--heads", url, ref)
  Open3-->>PreFlightChecks: [stdout, status]
  alt status.success? and stdout not empty
    PreFlightChecks-->>User: branch exists (ok)
  else
    PreFlightChecks-->>User: raise missing branch error
  end
Loading
sequenceDiagram
  autonumber
  participant User
  participant DemoCreator
  participant GitHubSpecParser as Parser
  participant Git as Git/FS

  User->>DemoCreator: build_github_npm_package(gem_name, github_spec)
  DemoCreator->>Parser: parse_github_spec + validate*
  alt @dry_run true
    DemoCreator-->>User: return early (no network/fs)
  else
    DemoCreator->>Git: clone repo, checkout branch, locate package/
    rect rgba(220,245,220,0.3)
      note right of DemoCreator: New rescue handling wraps temp-dir build flow
      alt build succeeds
        DemoCreator-->>User: package built
      else CommandError/IO/SystemCallError
        DemoCreator-->>User: raise Error with guidance
      end
    end
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Poem

I hop through specs both sharp and neat,
Parsing repos in nimble feet.
Open3 hums a safer song,
Backticks gone where they don't belong.
Errors nudged with gentle thump — hooray, demos jump! 🐇✨

Pre-merge checks and finishing touches

❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Linked Issues Check ⚠️ Warning The PR addresses the high priority elimination of backtick-based command execution and implements input validation and dry-run consistency as required by issue #9, but it lacks clear evidence of standardized safe execution patterns across all scripts (such as in demo_creator) and does not introduce the network timeout or retry logic specified in the acceptance criteria. The remaining git operations should be updated to use Open3.capture2 or array-based command execution and network requests should be wrapped with timeout or retry mechanisms to fully satisfy the linked issue requirements.
Docstring Coverage ⚠️ Warning Docstring coverage is 30.77% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The pull request title succinctly highlights both the security fix for command injection and the broader code quality improvements achieved by the changes, making it clear to reviewers what the primary updates are.
Out of Scope Changes Check ✅ Passed All modifications in this pull request directly support the security and code quality objectives outlined in linked issue #9, and no unrelated or extraneous changes are present.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix-security-command-injection

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 32f35ce and 06c1014.

📒 Files selected for processing (5)
  • lib/demo_scripts/demo_creator.rb (3 hunks)
  • lib/demo_scripts/github_spec_parser.rb (1 hunks)
  • lib/demo_scripts/pre_flight_checks.rb (4 hunks)
  • spec/demo_scripts/demo_creator_spec.rb (1 hunks)
  • spec/demo_scripts/github_spec_parser_spec.rb (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • lib/demo_scripts/github_spec_parser.rb
🧰 Additional context used
🧬 Code graph analysis (3)
lib/demo_scripts/pre_flight_checks.rb (1)
lib/demo_scripts/github_spec_parser.rb (3)
  • parse_github_spec (8-18)
  • validate_github_repo (21-34)
  • validate_github_branch (37-50)
spec/demo_scripts/github_spec_parser_spec.rb (1)
lib/demo_scripts/github_spec_parser.rb (3)
  • parse_github_spec (8-18)
  • validate_github_repo (21-34)
  • validate_github_branch (37-50)
lib/demo_scripts/demo_creator.rb (1)
lib/demo_scripts/pre_flight_checks.rb (1)
  • include (7-106)
🪛 Brakeman (7.1.0)
lib/demo_scripts/pre_flight_checks.rb

[medium] 84-84: Possible command injection
Type: Command Injection
Confidence: Medium
More info: https://brakemanscanner.org/docs/warning_types/command_injection/

(Command Injection)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: claude-review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

claude bot commented Oct 5, 2025

Pull Request Review: Fix Command Injection Vulnerability and Improve Code Quality

Summary

This PR successfully addresses the critical security vulnerability identified in #9 and implements several important code quality improvements. The changes are well-structured, properly tested, and follow Ruby best practices.

✅ Strengths

Security Improvements

  • Excellent security fix: Replaced unsafe backtick execution with Open3.capture2 in pre_flight_checks.rb:83-87, eliminating the command injection vulnerability
  • Defense in depth: Added input validation for GitHub repo and branch names before command execution
  • Proper argument passing: Uses array-based arguments with Open3.capture2 which prevents shell injection

Code Quality

  • DRY principle: Successfully extracted duplicated GitHub parsing logic into a shared GitHubSpecParser module
  • Better error handling: Added comprehensive error message in demo_creator.rb:241-254 for npm package build failures
  • Consistent validation: Centralized validation logic ensures consistent security checks across the codebase
  • Maintainability: The new module makes the code easier to understand and maintain

Testing

  • Good test coverage: Updated specs properly mock Open3.capture2 instead of backticks
  • All tests passing: 111 examples with 0 failures
  • RuboCop clean: No offenses detected

🔍 Areas for Improvement

1. Missing Test Coverage for New Module

Severity: Medium

The new GitHubSpecParser module (lib/demo_scripts/github_spec_parser.rb) has no dedicated test file. While the methods are tested indirectly through DemoCreator and PreFlightChecks tests, a dedicated spec file would:

  • Provide explicit documentation of the module behavior
  • Make it easier to add edge cases
  • Improve maintainability

2. Potential Logic Issue in Pre-flight Check

Severity: Low
Location: pre_flight_checks.rb:30-35

The success message "✓ Target directory does not exist" is printed right before raising an error about the directory existing. This is confusing and should be restructured.

3. Enhanced Error Handling Consideration

Severity: Low
Location: demo_creator.rb:240-254

The new error handling for build_github_npm_package is great, but it catches all StandardError exceptions. Consider catching more specific exceptions or preserving the original backtrace for debugging.

4. Branch Name Validation Edge Case

Severity: Low
Location: github_spec_parser.rb:37-45

The branch validation checks for invalid characters, but Git also has other rules:

  • Branch names cannot end with .lock
  • Cannot contain @{
  • Cannot be just @

These are less common, but for completeness, consider adding them or documenting why they are excluded.

5. Dry Run Mode Inconsistency

Severity: Low
Location: demo_creator.rb:237-239

The build_github_npm_package method does not check @dry_run before cloning repositories and building packages. While this was identified in issue #9, it would be good to address.

🔒 Security Review

Command Injection Fix Verified

  • Before: Unsafe string interpolation with backticks
  • After: Safe array-based arguments with Open3.capture2
  • Input validation adds defense-in-depth

No New Security Issues Introduced

  • All user input is validated before use
  • Shellwords.join is used correctly for command building
  • No SQL injection, path traversal, or other common vulnerabilities detected

📊 Performance Considerations

  • ✅ No performance regressions introduced
  • ✅ Open3.capture2 is appropriate for this use case
  • ℹ️ GitHub branch checks add network latency, but this is acceptable for pre-flight validation

✅ Approval Recommendation

This PR is approved with minor suggestions for follow-up improvements.

The critical security vulnerability is properly fixed, code quality is improved, and all tests pass. The suggested improvements are minor and can be addressed in future PRs if desired.

Next Steps (Optional)

  1. Add dedicated tests for GitHubSpecParser module
  2. Fix the confusing success message in check_target_directory!
  3. Consider adding dry-run check to build_github_npm_package

Great work on addressing the security issue thoroughly! 🎉


Review completed by Claude CodeDocs

Test Coverage:
- Add dedicated test file for GitHubSpecParser module (39 tests)
- Ensure all edge cases are covered with explicit documentation
- Update demo_creator_spec to use dry_run: false for npm package tests

Code Quality Improvements:
- Fix confusing success message in pre_flight_checks.rb
- Enhance branch name validation with additional Git ref rules:
  * Reject branches ending with .lock
  * Reject branches containing @{
  * Reject branches that are just @
- Improve error handling in build_github_npm_package:
  * Catch specific exceptions (CommandError, IOError, SystemCallError)
  * Preserve original backtrace for debugging
  * Add early return for dry_run mode

Bug Fixes:
- Fix split behavior to correctly detect empty repo parts (use split('/', -1))
- Restructure check_target_directory! to avoid printing success before error

All tests pass: 150 examples, 0 failures
RuboCop clean: 37 files, no offenses

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Copy link

claude bot commented Oct 5, 2025

Code Review Summary

APPROVE ✅ - Excellent security fix with comprehensive improvements

Security - EXCELLENT ✅

  • Command injection fixed: Properly uses Open3.capture2 with array args instead of backticks
  • Input validation: Comprehensive checks for repo/branch names prevent injection
  • Defense-in-depth: Validates before use, follows Ruby security best practices

Code Quality - VERY GOOD ✅

  • Module extraction: GitHubSpecParser eliminates duplication (DRY principle)
  • Error handling: Specific exceptions, preserves backtraces, actionable messages
  • Testing: 150 tests (up from 111), 39 new tests for parser module
  • RuboCop clean: 36 files, no offenses

Minor Suggestions (Optional)

  1. Logic flow: check_target_directory! success message after raise (pre_flight_checks.rb:30-34)
  2. URL construction: Consider URI encoding for defense-in-depth (pre_flight_checks.rb:84)
  3. Guard clauses: Move @dry_run check to method top (demo_creator.rb:232)
  4. Branch validation: Add checks for branches starting with - or containing //
  5. Network timeout: Add Timeout.timeout(30) for git ls-remote operations

Test Coverage - EXCELLENT ✅

  • Comprehensive edge cases (multiple @ symbols, empty parts, special chars)
  • Both positive and negative test cases
  • Clear descriptions and good RSpec structure
  • Suggested addition: Integration test for command injection prevention

Performance Notes

  • git ls-remote: No timeout (could hang if GitHub slow)
  • Cloning: Uses --depth 1 ✅ but clones full repo
  • Acceptable for use case, could document if intentional

Security Assessment Table

Category Rating Notes
Command Injection ✅ Excellent Open3.capture2 prevents injection
Input Validation ✅ Very Good Comprehensive, minor edge cases noted
Error Handling ✅ Good No info leaks, helpful messages
Dependencies ✅ Good Standard library only (Open3)

Verdict

This PR completely fixes the command injection vulnerability from #9. The implementation is thorough, well-tested, and follows best practices. Going from 111 to 150 passing tests with clean RuboCop shows strong engineering discipline.

Ready to merge! 🚀

Detailed review conducted covering security, code quality, performance, and test coverage

@justin808 justin808 merged commit 6a66844 into main Oct 5, 2025
2 checks passed
@justin808 justin808 deleted the fix-security-command-injection branch October 5, 2025 01:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Security and code quality improvements for GitHub branch support
1 participant