-
Notifications
You must be signed in to change notification settings - Fork 1.7k
[Security] Fix MEDIUM vulnerability: javascript.lang.security.audit.path-traversal.path-join-resolve-traversal.path-join-resolve-traversal #8149
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -4,6 +4,16 @@ import path from 'path'; | |||||||||||||||||||
| import { toKebabCase } from '../src/app/strings.mjs'; | ||||||||||||||||||||
| import { parseConfig } from '../utils/utils.mjs'; | ||||||||||||||||||||
|
|
||||||||||||||||||||
| /** | ||||||||||||||||||||
| * Sanitizes a file or directory name to prevent path traversal attacks | ||||||||||||||||||||
| * @param {string} name - The file or directory name to sanitize | ||||||||||||||||||||
| * @returns {string} - The sanitized name | ||||||||||||||||||||
| */ | ||||||||||||||||||||
| const sanitizeName = (name) => { | ||||||||||||||||||||
| // Remove any path traversal sequences and null bytes | ||||||||||||||||||||
| return name.replace(/\.\./g, '').replace(/\0/g, '').replace(/[/\\]/g, ''); | ||||||||||||||||||||
| }; | ||||||||||||||||||||
|
|
||||||||||||||||||||
| /** | ||||||||||||||||||||
| * @type {{ | ||||||||||||||||||||
| * path: string, | ||||||||||||||||||||
|
|
@@ -42,15 +52,17 @@ const main = () => { | |||||||||||||||||||
| const categories = getDirFiles(rootPath); | ||||||||||||||||||||
kpal81xd marked this conversation as resolved.
Show resolved
Hide resolved
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since we want to use this for example names to I would just move this reduce up to |
||||||||||||||||||||
|
|
||||||||||||||||||||
| categories.forEach((category) => { | ||||||||||||||||||||
| const categoryPath = path.resolve(`${rootPath}/${category}`); | ||||||||||||||||||||
| const sanitizedCategory = sanitizeName(category); | ||||||||||||||||||||
| const categoryPath = path.resolve(rootPath, sanitizedCategory); | ||||||||||||||||||||
kpal81xd marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||
| const examplesFiles = getDirFiles(categoryPath); | ||||||||||||||||||||
| const categoryKebab = toKebabCase(category); | ||||||||||||||||||||
|
||||||||||||||||||||
| const categoryKebab = toKebabCase(category); | |
| const categoryKebab = toKebabCase(sanitizedCategory); |
Copilot
AI
Nov 20, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The sanitization is applied to exampleFile, but line 66 still uses the original unsanitized exampleFile variable to extract the example name. This inconsistency means that if exampleFile contained path traversal sequences, they would be preserved in exampleName and subsequently in exampleNameKebab at line 67, potentially storing malicious paths in the metadata output.
For consistency and security, use the sanitized version:
const exampleName = sanitizedExampleFile.split('.').shift() ?? '';| const exampleName = exampleFile.split('.').shift() ?? ''; | |
| const exampleName = sanitizedExampleFile.split('.').shift() ?? ''; |
Uh oh!
There was an error while loading. Please reload this page.