Fixed High-severity path traversal vulnerability (CWE-22)#712
Fixed High-severity path traversal vulnerability (CWE-22)#712Aryan-Agarwal-creator wants to merge 2 commits into
Conversation
…project name validation - Add validateProjectName() function to validate project names against path traversal attacks - Prevent usage of '../', '..\', absolute paths, and invalid characters - Only allow lowercase letters, numbers, hyphens, and underscores - Add validateResolvedPath() defensive check to ensure resolved paths stay in cwd - Validate project names in both interactive and non-interactive modes before any filesystem operations - Add comprehensive test suite with 27 test cases covering valid and invalid project names - Fail safely with descriptive error messages Prevents attacks like: - npx create-termui-app ../../../etc/evil - npx create-termui-app ../../malicious-project - npx create-termui-app /etc/passwd Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
⭐ Star this repo before your PR merges. Why? GSSoC 2026 contributors who star get priority review and points credit. After you star, push any commit (or re-run this check). The Thanks for your contribution to TermUI. |
📝 WalkthroughWalkthroughThe PR adds input validation to prevent path traversal attacks in the ChangesProject Name Validation for Security
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related issues
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
🎉 Thanks for your first PR to TermUI, @Aryan-Agarwal-creator.
Before your PR merges:
- ⭐ Star the repo. Required. The
star-checkjob blocks your merge otherwise. - ✅ All checks green:
build,test,typecheck. - 🏷 PR title follows
type: short description. Example:fix: handle empty list. - 🔗 Link your closing issue in the description.
GSSoC 2026 points come from labels after merge:
gssoc:approved. +50 base points.level:beginner/intermediate/advanced/critical. +20 / +35 / +55 / +80.quality:clean/exceptional. x 1.2 / x 1.5.type:*. Stackable bonus.
Your reviewer responds within 48 hours. Ping @Karanjot786 on Discord for urgent help.
🚀 Welcome to the cohort.
|
Already Stared the Repo |
There was a problem hiding this comment.
Actionable comments posted: 3
🧹 Nitpick comments (1)
packages/create-termui-app/src/validate.test.ts (1)
172-183: ⚡ Quick winAdd rejection-path tests for
validateResolvedPath(escape attempts and Windows-style separators).Current coverage is happy-path only; this helper is security-critical and should assert that escape cases throw.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/create-termui-app/src/validate.test.ts` around lines 172 - 183, Add negative tests for validateResolvedPath to assert it throws on path-escaping and Windows-style separator inputs: call validateResolvedPath(cwd, "../evil") and validateResolvedPath(cwd, "..\\evil") and expect them to throw, also test inputs containing backslashes like "some\\name" and absolute/escape variants such as "/absolute/path" and "my-app/../evil" to ensure validateResolvedPath rejects path-traversal and Windows-style separators; place these new it(...) cases alongside the existing describe("validateResolvedPath") tests referencing the validateResolvedPath function.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@packages/create-termui-app/src/index.ts`:
- Line 15: The code calls validateProjectName but never invokes
validateResolvedPath, so add a call to validateResolvedPath(resolvedPath) before
any filesystem writes in both flows (the interactive and non-interactive project
creation paths) to ensure the resolved path is safe; specifically, call
validateResolvedPath immediately after resolving the target directory and before
invoking any functions that write files (e.g., before template copy/write
operations or before writeProject/writeFiles logic), keeping validateProjectName
checks intact.
In `@packages/create-termui-app/src/validate.test.ts`:
- Around line 159-163: Remove the unnecessary "as unknown" casts in the tests
that call validateProjectName (e.g., replace validateProjectName(123 as unknown)
and validateProjectName({} as unknown) with direct calls
validateProjectName(123) and validateProjectName({})) and keep the existing
expect(...).toThrow(/required/) assertions; then add negative-path tests for
validateResolvedPath that assert it throws when the resolved path escapes the
current working directory (e.g., inputs like ".." or a path that resolves
outside cwd) using the existing test patterns so the new tests check for the
expected error/regex.
In `@packages/create-termui-app/src/validate.ts`:
- Around line 71-73: The current containment check in validateResolvedPath uses
resolved.startsWith(cwdNorm + "/") which is separator-specific and breaks on
Windows; replace that startsWith logic with a path.relative-based containment
check: compute const rel = path.relative(cwdNorm, resolved) and treat the path
as inside the cwd when rel === "" (exact match) or when rel does not start with
".." (use ".." + path.sep check to be safe) — update the conditional that
references resolved, cwdNorm, and startsWith to use this path.relative approach
so the function is separator-agnostic and Windows-safe.
---
Nitpick comments:
In `@packages/create-termui-app/src/validate.test.ts`:
- Around line 172-183: Add negative tests for validateResolvedPath to assert it
throws on path-escaping and Windows-style separator inputs: call
validateResolvedPath(cwd, "../evil") and validateResolvedPath(cwd, "..\\evil")
and expect them to throw, also test inputs containing backslashes like
"some\\name" and absolute/escape variants such as "/absolute/path" and
"my-app/../evil" to ensure validateResolvedPath rejects path-traversal and
Windows-style separators; place these new it(...) cases alongside the existing
describe("validateResolvedPath") tests referencing the validateResolvedPath
function.
🪄 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: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 49cf55c4-6526-4f58-be5c-129358a42cc1
⛔ Files ignored due to path filters (1)
bun.lockis excluded by!**/*.lock
📒 Files selected for processing (3)
packages/create-termui-app/src/index.tspackages/create-termui-app/src/validate.test.tspackages/create-termui-app/src/validate.ts
Review: validateResolvedPath not calledIn Add the call immediately after resolving the project directory, before any file writes: const projectDir = resolve(process.cwd(), projectName);
validateResolvedPath(projectDir); // validate before writingDo this in both the interactive and non-interactive flows. |
Description
This PR fixes a high-severity path traversal vulnerability (CWE-22) in the
create-termui-appscaffolding tool. The fix introduces strict project name validation, defensive path validation, and comprehensive test coverage to prevent arbitrary file writes outside the intended project directory while preserving existing functionality.Related Issue
Closes #707
Which package(s)?
packages/create-termui-appType of Change
type:bug)type:testing)type:security)Checklist
needs-starcheck blocks your merge otherwise.bun vitest runbun run buildbun run typecheck[CONTRIBUTING.md](https://chatgpt.com/c/CONTRIBUTING.md).type: short description.markDirty()(if your change affects rendering).anytypes without an inline comment explaining why.GSSoC 2026 Participation
https://gssoc.girlscript.org/profile/____Screenshots / Recordings (UI changes)
N/A – Security and validation changes only.
Notes for the Reviewer
Security Improvements
Added
validateProjectName()to enforce a whitelist-based naming policy.Added
validateResolvedPath()as a defensive check against path traversal attempts.Validation now runs before any filesystem operations are performed.
Prevents directory traversal attacks such as:
../evil../../etc/passwdValidation Rules
Allowed:
my-appproject_1termui-demoRejected:
../evil/etc/passwdMyApphello worldproject$Files Added
validate.tsvalidate.test.tsFiles Modified
packages/create-termui-app/src/index.tsTest Coverage
Verification
Summary by CodeRabbit
Bug Fixes
Tests