Skip to content

CRITICAL: Fix JavaScript code injection in Jest config generation (Issue #17)#2008

Open
mohammedahmed18 wants to merge 1 commit intomainfrom
fix/javascript-injection-issue-17
Open

CRITICAL: Fix JavaScript code injection in Jest config generation (Issue #17)#2008
mohammedahmed18 wants to merge 1 commit intomainfrom
fix/javascript-injection-issue-17

Conversation

@mohammedahmed18
Copy link
Copy Markdown
Contributor

CRITICAL Security Fix: JavaScript Code Injection

Severity: 🔴 CRITICAL
Impact: Arbitrary JavaScript execution
CVE: Not assigned (fixed before public disclosure)


Vulnerability Description

Unsanitized file paths in f-string interpolation allow injection of arbitrary JavaScript code into generated Jest config files. If a test directory path or monorepo path contains a single quote ('), it breaks out of the string context and executes code.

Proof of Concept

Malicious path:

/tmp/test']; console.log('INJECTED'); roots=['

Vulnerable output (before fix):

// jest.codeflash.runtime.config.js
module.exports = {
  roots: ['/project', '/tmp/test']; console.log('INJECTED'); roots=[''],
  //                              ^-- string closed, code executes!
};

When Jest loads this config, console.log('INJECTED') executes.


Root Cause

Three locations in test_runner.py used f-strings to embed paths without escaping:

  1. Line 516 - Test directories:

    test_dirs_js = ", ".join(f"'{d}'" for d in sorted(test_dirs))
  2. Line 524 - Monorepo node_modules:

    module_dirs_line = f"  moduleDirectories: [..., '{monorepo_node_modules}'],"
  3. Line 565 - Project root:

    f"roots: ['{project_root}', {test_dirs_js}],"

Fix

Replace f-string interpolation with json.dumps() which properly escapes special characters:

# Before (VULNERABLE):
test_dirs_js = ", ".join(f"'{d}'" for d in sorted(test_dirs))

# After (SAFE):
test_dirs_js = ", ".join(json.dumps(d) for d in sorted(test_dirs))

After fix:

module.exports = {
  roots: ["/project", "/tmp/test']; console.log('INJECTED'); roots=['"],
  //                 ^-- double quotes, single quotes are string content (safe)
};

Attack Vectors

  1. User-controlled paths: If Codeflash processes repositories where test directory names can be influenced
  2. Symlink attacks: Malicious symlinks with special chars in names
  3. Monorepo paths: Projects in directories with quotes in path
  4. CI/CD: Automated systems processing untrusted repositories

Testing

New tests:

  • test_single_quote_in_test_dir_path_no_injection - Verifies test dirs are escaped
  • test_monorepo_path_with_quote_no_injection - Verifies monorepo paths are escaped

Existing tests:

  • test_create_codeflash_tsconfig - Still passes
  • test_create_codeflash_jest_config - Still passes

Manual verification:

# Before fix: generated config contains executable code
roots: ['/project', '/tmp/test']; console.log('INJECTED'); roots=[''],

# After fix: path is JSON-escaped (double-quoted)
roots: ["/project", "/tmp/test']; console.log('INJECTED'); roots=['"],

Files Changed

  • codeflash/languages/javascript/test_runner.py - Fixed 3 injection points
  • tests/test_languages/test_javascript_injection_bug.py - New test file (2 tests)

Security Disclosure

This vulnerability was discovered through proactive code review using autoresearch:debug. No known exploits in the wild. Fixed before public disclosure to minimize risk.

Recommendation: Merge and release immediately due to CRITICAL severity.


Related Issues

This vulnerability was found alongside 11 other bugs during code review:

…eneration

**Issue #17:** Unsanitized file paths in f-string interpolation can inject
arbitrary JavaScript code into the generated Jest config file.

**Severity:** CRITICAL

**Root Cause:**
File: /opt/codeflash/codeflash/languages/javascript/test_runner.py:516, 524, 565

Three locations used f-string interpolation to embed paths into JavaScript code
without escaping:

1. Line 516: `test_dirs_js = ", ".join(f"'{d}'" for d in sorted(test_dirs))`
2. Line 524: `f"moduleDirectories: [..., '{monorepo_node_modules}'],"`
3. Line 565: `f"roots: ['{project_root}', {test_dirs_js}],"`

If any path contains a single quote (`'`), it breaks out of the string and
executes arbitrary JavaScript. Example:

**Malicious path:** `/tmp/test']; console.log('INJECTED'); roots=['`

**Vulnerable output:**
```javascript
roots: ['/project', '/tmp/test']; console.log('INJECTED'); roots=[''],
                                ^-- breaks string, executes code
```

**Impact:**
- **Code injection:** Arbitrary JavaScript execution when Jest loads config
- **Attack vector:** User-controlled paths (test directories, monorepo paths)
- **Scope:** Any project where test dirs or project root contains quote char
- **Risk:** HIGH - While uncommon, paths can be influenced via symlinks,
  mount points, or malicious repository names

**Fix:**
Use `json.dumps()` to properly escape all paths before embedding in JavaScript:

1. Line 516: `json.dumps(d)` instead of `f"'{d}'"`
2. Line 524: `json.dumps(monorepo_node_modules)` instead of f-string
3. Line 565: `json.dumps(str(project_root))` instead of f-string

`json.dumps()` wraps strings in double quotes and properly escapes special
characters, preventing injection.

**After fix:**
```javascript
roots: ["/project", "/tmp/test']; console.log('INJECTED'); roots=['"],
                   ^-- double quoted, single quotes are string content (safe)
```

**Files Changed:**
- codeflash/languages/javascript/test_runner.py (3 injection points fixed)
- tests/test_languages/test_javascript_injection_bug.py (new test file, 2 tests)

**Testing:**
- 2 new tests specifically for injection vulnerability (both pass)
- 2 existing test_runner tests pass
- All tests verify paths are JSON-escaped (double-quoted)

**Security Note:**
This vulnerability was found through proactive code review (autoresearch:debug).
No known exploits in the wild. Fixed before public disclosure.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
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.

1 participant