Skip to content

Security: Path traversal vulnerability in functions:create via --name flag #8206

@NiteshCodes7

Description

@NiteshCodes7

Describe the bug

Description

There is a path traversal vulnerability in functions:create. The interactive
prompt correctly validates function names with /^[\w.-]+$/i, but this validation
is completely bypassed when the name is supplied via the --name flag or as a
positional argument.

Affected File

src/commands/functions/functions-create.ts

Reproduction Steps

Run either of the following:

netlify functions:create --name "../../evil"
netlify functions:create "../../evil"

This causes files to be written outside the intended functions directory.

Root Cause

In getNameFromArgs, validation only runs on the interactive prompt:

const { name } = await inquirer.prompt([
{
validate: (val) => Boolean(val) && /^[\w.-]+$/i.test(val), // ✅ validated
},
])

But when --name or a positional arg is passed, the raw unvalidated value goes
directly into:

const functionPath = path.join(functionsDir, name) // ❌ no validation

Impact

An attacker or a malicious script can write files to arbitrary locations on the
filesystem outside the functions directory.

Proposed Fix

Add a containment check in ensureFunctionPathIsOk:

const ensureFunctionPathIsOk = function (functionsDir, name) {
const functionPath = path.join(functionsDir, name)

if (!functionPath.startsWith(path.resolve(functionsDir) + path.sep)) {
log(Invalid function name: "${name}" resolves outside the functions directory.)
process.exit(1)
}

if (fs.existsSync(functionPath)) {
log(Function ${functionPath} already exists, cancelling...)
process.exit(1)
}

return functionPath
}

Additional Note

A second related issue exists in downloadFromURL where filenames from the
GitHub API response are not sanitized before being passed to path.join.
Fix: wrap name with path.basename(name) before use.

Steps to reproduce

Steps to Reproduce

Prerequisites:

Node.js v20.12.2 or above installed
netlify-cli installed globally: npm install netlify-cli -g
A project directory initialized

Step 1 — Create a test project directory

mkdir test-project
cd test-project
netlify login

Step 2 — Create a safe functions directory

mkdir functions
ls
# Expected: only 'functions' folder exists

Step 3 — Trigger the vulnerability using --name flag

netlify functions:create --name "../../evil"

Step 4 — Observe the result

ls ../..
# You will see an 'evil' folder created TWO levels above your project directory
# Files were written OUTSIDE the intended functions directory

Step 5 — Confirm with positional argument (second vector)

netlify functions:create "../../evil2"
ls ../..
# Same result — 'evil2' folder created outside project

Expected Behavior:

Error: Invalid function name. Name must only contain letters, numbers, 
hyphens, underscores, or dots.

Actual Behavior:

Files are written to ../../evil/ — completely outside the 
intended functions directory with no warning or error.

Configuration

No response

Environment

OS: [your OS]
Node version: run node -v
netlify-cli version: run netlify --version

Metadata

Metadata

Assignees

No one assigned

    Labels

    type: bugcode to address defects in shipped code

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions