Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 094e830

Browse files
committed
fix: prevent path traversal in functions:create command
1 parent 0415e87 commit 094e830

1 file changed

Lines changed: 17 additions & 8 deletions

File tree

src/commands/functions/functions-create.ts

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -394,7 +394,10 @@ const downloadFromURL = async function (command, options, argumentName, function
394394
folderContents.map(async ({ download_url: downloadUrl, name }) => {
395395
try {
396396
const res = await fetch(downloadUrl)
397-
const finalName = path.basename(name, '.js') === functionName ? `${nameToUse}.js` : name
397+
// SAFE:
398+
const finalName = path.basename(name, '.js') === functionName
399+
? `${nameToUse}.js`
400+
: path.basename(name) // ← strip any directory components
398401
const dest = fs.createWriteStream(path.join(fnFolder, finalName))
399402
res.body?.pipe(dest)
400403
} catch (error_) {
@@ -744,14 +747,20 @@ const registerEFInToml = async (funcName, options) => {
744747
* @returns
745748
*/
746749
// @ts-expect-error TS(7006) FIXME: Parameter 'functionsDir' implicitly has an 'any' t... Remove this comment to see the full error message
747-
const ensureFunctionPathIsOk = function (functionsDir, name) {
748-
const functionPath = path.join(functionsDir, name)
749-
if (fs.existsSync(functionPath)) {
750-
log(`${NETLIFYDEVLOG} Function ${functionPath} already exists, cancelling...`)
751-
process.exit(1)
750+
const ensureFunctionPathIsOk = function (functionsDir, name) {
751+
// Prevent path traversal: reject names like "../../evil"
752+
const resolvedFunctionsDir = path.resolve(functionsDir)
753+
const functionPath = path.join(resolvedFunctionsDir, name)
754+
if (!functionPath.startsWith(resolvedFunctionsDir + path.sep)) {
755+
log(`${NETLIFYDEVERR} Invalid function name: "${name}" resolves outside the functions directory.`)
756+
process.exit(1)
757+
}
758+
if (fs.existsSync(functionPath)) {
759+
log(`${NETLIFYDEVLOG} Function ${functionPath} already exists, cancelling...`)
760+
process.exit(1)
761+
}
762+
return functionPath
752763
}
753-
return functionPath
754-
}
755764

756765
// Scans `functions-templates/<lang>` for a template whose `.mjs` metadata
757766
// `name` matches. Returns its `functionType` and the language folder it lives

0 commit comments

Comments
 (0)