fix: validate reviewAgentLogPath to prevent path injection#1134
fix: validate reviewAgentLogPath to prevent path injection#1134
Conversation
Add path validation to invokeDiffReviewLlm to ensure the log path stays within the expected DATA_CACHE_DIR/review-agent directory. This addresses CodeQL alert #19 (js/path-injection) by resolving the path and verifying it does not escape the log directory. The validation is performed before each fs.appendFileSync call to prevent path traversal attacks even if the call chain changes in the future. Co-authored-by: Michael Sukkarieh <msukkari@users.noreply.github.com>
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
✅ Files skipped from review due to trivial changes (1)
WalkthroughLog path handling for the review agent was hardened: log directory resolution was centralized via Changes
Sequence Diagram(s)sequenceDiagram
autonumber
participant Proc as processGitHubPullRequest
participant App as app.ts
participant Agent as invokeDiffReviewLlm
participant FS as Filesystem
participant LLM as OpenAI
Proc->>App: start processing PR
App->>Agent: call process with PR data
Agent->>Agent: dir = getReviewAgentLogDir()
Agent->>FS: resolve(proposedLogPath)
Agent->>Agent: validateLogPath(resolvedPath, dir)
Agent->>FS: write prompt file (validated path)
Agent->>LLM: send prompt -> await response
LLM-->>Agent: response
Agent->>FS: resolve(responseLogPath)
Agent->>Agent: validateLogPath(resolvedResponsePath, dir)
Agent->>FS: write response file (validated path)
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes 🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
Co-authored-by: Michael Sukkarieh <msukkari@users.noreply.github.com>
…keDiffReviewLlm.ts Export the log directory constant from invokeDiffReviewLlm.ts and import it in app.ts to ensure a single source of truth for the review agent log directory path. Co-authored-by: Michael Sukkarieh <msukkari@users.noreply.github.com>
Co-authored-by: Michael Sukkarieh <msukkari@users.noreply.github.com>
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
packages/web/src/features/agents/review-agent/nodes/invokeDiffReviewLlm.ts (1)
31-48: Minor: redundant double validation.
reviewAgentLogPathis a function parameter (a string) that doesn't change between the twovalidateLogPathcalls, so the second invocation on Line 46 is redundant. Validating once near the top ofinvokeDiffReviewLlm(whenreviewAgentLogPathis defined) would be simpler and still safe — there's no TOCTOU benefit here since the check is purely string-based.♻️ Proposed refactor
if (!env.OPENAI_API_KEY) { logger.error("OPENAI_API_KEY is not set, skipping review agent"); throw new Error("OPENAI_API_KEY is not set, skipping review agent"); } + + if (reviewAgentLogPath) { + validateLogPath(reviewAgentLogPath); + } const openai = new OpenAI({ apiKey: env.OPENAI_API_KEY, }); if (reviewAgentLogPath) { - validateLogPath(reviewAgentLogPath); fs.appendFileSync(reviewAgentLogPath, `\n\nPrompt:\n${prompt}`); } @@ if (reviewAgentLogPath) { - validateLogPath(reviewAgentLogPath); fs.appendFileSync(reviewAgentLogPath, `\n\nResponse:\n${openaiResponse}`); }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/web/src/features/agents/review-agent/nodes/invokeDiffReviewLlm.ts` around lines 31 - 48, The code calls validateLogPath(reviewAgentLogPath) twice inside invokeDiffReviewLlm — once before appending the prompt and again before appending the response — which is redundant because reviewAgentLogPath is an immutable parameter; remove the second call. Update invokeDiffReviewLlm to validate reviewAgentLogPath once (when reviewAgentLogPath is truthy) before the first fs.appendFileSync, and keep the subsequent fs.appendFileSync(reviewAgentLogPath, `\n\nResponse:\n${openaiResponse}`) without re-validating; reference validateLogPath, reviewAgentLogPath, invokeDiffReviewLlm, and fs.appendFileSync to locate the lines to change.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@packages/web/src/features/agents/review-agent/nodes/invokeDiffReviewLlm.ts`:
- Around line 10-17: Make REVIEW_AGENT_LOG_DIR an absolute canonical path by
using path.resolve on env.DATA_CACHE_DIR (e.g., REVIEW_AGENT_LOG_DIR =
path.resolve(env.DATA_CACHE_DIR, 'review-agent')), and update validateLogPath to
canonicalize both the base and the incoming logPath (use path.resolve) then
compute const rel = path.relative(REVIEW_AGENT_LOG_DIR, resolved); reject the
path when rel is empty, is absolute (path.isAbsolute(rel)), or startsWith('..')
and throw the existing error; reference symbols: REVIEW_AGENT_LOG_DIR and
validateLogPath.
---
Nitpick comments:
In `@packages/web/src/features/agents/review-agent/nodes/invokeDiffReviewLlm.ts`:
- Around line 31-48: The code calls validateLogPath(reviewAgentLogPath) twice
inside invokeDiffReviewLlm — once before appending the prompt and again before
appending the response — which is redundant because reviewAgentLogPath is an
immutable parameter; remove the second call. Update invokeDiffReviewLlm to
validate reviewAgentLogPath once (when reviewAgentLogPath is truthy) before the
first fs.appendFileSync, and keep the subsequent
fs.appendFileSync(reviewAgentLogPath, `\n\nResponse:\n${openaiResponse}`)
without re-validating; reference validateLogPath, reviewAgentLogPath,
invokeDiffReviewLlm, and fs.appendFileSync to locate the lines to change.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: d34658fd-f05a-4b07-abcf-0440067a55bf
📒 Files selected for processing (3)
CHANGELOG.mdpackages/web/src/features/agents/review-agent/app.tspackages/web/src/features/agents/review-agent/nodes/invokeDiffReviewLlm.ts
|
test |
Change REVIEW_AGENT_LOG_DIR from a top-level constant to a getReviewAgentLogDir() function to avoid evaluating env.DATA_CACHE_DIR at module load time, which fails during Next.js build when environment variables are not yet available. Co-authored-by: Michael Sukkarieh <msukkari@users.noreply.github.com>
Co-authored-by: Michael Sukkarieh <msukkari@users.noreply.github.com>
This reverts commit 476081e.
Fixes SOU-930
Summary
This PR addresses CodeQL alert #19 (js/path-injection) by adding path validation to the
invokeDiffReviewLlmfunction in the review agent.Problem
The
reviewAgentLogPathparameter was passed tofs.appendFileSyncwithout validation, creating a latent path injection vulnerability. While the current code constructs the path safely usingpullRequest.number(which is always an integer from the GitHub API), the function itself did not validate the path, meaning any future changes to the call chain could introduce a security issue.Solution
Added a
validateLogPathhelper function that:DATA_CACHE_DIR/review-agent/)The validation is performed before each
fs.appendFileSynccall to ensure defense-in-depth.Additionally, the log directory constant is now exported from
invokeDiffReviewLlm.tsand shared withapp.tsto ensure a single source of truth.Changes
pathimport toinvokeDiffReviewLlm.tsREVIEW_AGENT_LOG_DIRconstant for the expected log directoryvalidateLogPath()helper function that validates paths are within the expected directoryfs.appendFileSynccalls (prompt and response logging)app.tsto import and useREVIEW_AGENT_LOG_DIRinstead of defining it locallyTesting
References
Linear Issue: SOU-930
Summary by CodeRabbit
Bug Fixes
Documentation