-
-
Notifications
You must be signed in to change notification settings - Fork 4.5k
Fix Uncontrolled data used in path expression #3821
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: master
Are you sure you want to change the base?
Conversation
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.
Looking for feedback on comments
.replace(/^(\.\.(\/|\\|$))+/, "") // Remove leading `../` sequences | ||
.replace(/(\.\.(\/|\\|$))+/g, "") // Remove any remaining `../` segments | ||
.trim(); | ||
if (["..", ".", "/"].includes(result)) throw new Error("Invalid path."); | ||
if (!result || result.startsWith("/") || result.includes("..")) { | ||
throw new Error("Invalid or unsafe path."); | ||
} | ||
return result; |
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.
This is a good improvement to apply 👍
try { | ||
const sanitizedFilename = normalizePath(filename); | ||
const filePath = path.resolve(documentsPath, sanitizedFilename); | ||
|
||
if ( | ||
!fs.existsSync(filePath) || | ||
!isWithin(documentsPath, filePath) || | ||
!fs.lstatSync(filePath).isFile() | ||
) | ||
return; | ||
if ( | ||
!filePath.startsWith(documentsPath) || // Ensure the path is within documentsPath | ||
!fs.existsSync(filePath) || | ||
!fs.lstatSync(filePath).isFile() | ||
) { | ||
throw new Error(`Invalid or unsafe file path: ${filename}`); | ||
} | ||
|
||
console.log(`Purging source document of ${filename}.`); | ||
fs.rmSync(filePath); | ||
console.log(`Purging source document of ${filename}.`); | ||
fs.rmSync(filePath); | ||
} catch (error) { | ||
console.error(`Failed to purge source document: ${error.message}`); | ||
} |
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.
const sanitizedFilename = normalizePath(filename);
const filePath = path.resolve(documentsPath, sanitizedFilename);
is the same as
const filePath = path.resolve(documentsPath, normalizePath(filename));
and this block
!filePath.startsWith(documentsPath) || // Ensure the path is within documentsPath
!fs.existsSync(filePath) ||
!fs.lstatSync(filePath).isFile()
filePath.startsWith(documentsPath)
does a similar check of what isWithin
does already, no? So functionally, the logic has not changed here. We could have both or check within before checking existence, maybe?
Pull Request Type
anything-llm/server/utils/files/index.js
Lines 180 to 190 in 388960e
fix the issue need to ensure that the
filename
input is properly sanitized and validated before constructing the file path. Specifically:path.resolve
function to normalize the path and remove any..
segments.documentsPath
to ensure it is confined to the intended directory.The
normalizePath
function should also be updated to provide stricter sanitization, ensuring that the resulting path is safe to use.Developer Validations
yarn lint
from the root of the repo & committed changes