CVE-2023-43116
Description
A symbolic link following vulnerability in Buildkite Elastic CI for AWS versions prior to 6.7.1 and 5.22.5 allows the buildkite-agent user to change ownership of arbitrary directories via the PIPELINE_PATH variable in the fix-buildkite-agent-builds-permissions script.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
A symlink following vulnerability in Buildkite Elastic CI for AWS allows the buildkite-agent user to change ownership of arbitrary directories via the PIPELINE_PATH variable.
Root
Cause
A symbolic link following vulnerability in Buildkite Elastic CI for AWS versions prior to 6.7.1 and 5.22.5 allows the buildkite-agent user to change ownership of arbitrary directories via the PIPELINE_PATH variable in the fix-buildkite-agent-builds-permissions script [2]. The script did not properly validate the path, allowing an attacker to create a symlink and trick the ownership change into targeting an unintended directory.
Exploitation
An attacker with access to the buildkite-agent user (e.g., through a malicious build step) could set PIPELINE_PATH to a symlink pointing outside the intended build directory. The fix-buildkite-agent-builds-permissions script would then follow the symlink and change ownership of the linked directory instead of the build directory itself [1][3].
Impact
Successful exploitation allows the attacker to change ownership of arbitrary directories on the system, potentially gaining control over sensitive files or escalating privileges within the CI environment. This could lead to further compromise of the build infrastructure or exfiltration of secrets.
Mitigation
The vulnerability is fixed in versions 6.7.1 and 5.22.5. The commit 8f79882 adds validation to prevent the script from acting on symbolic links [3]. Users should update their Elastic CI Stack to the latest patched version.
AI Insight generated on May 20, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
github.com/buildkite/elastic-ci-stack-for-aws/v6Go | < 6.7.0 | 6.7.0 |
Affected products
2- Buildkite/Elastic CI for AWSdescription
Patches
18f79882b6aa1Prevent permission script acting on symlinks
9 files changed · +70 −28
docker-compose.unit-tests.yml+4 −4 modified@@ -2,8 +2,8 @@ version: '3' services: unit-tests: - image: lucor/bats + image: bats/bats volumes: - - .:/src:ro - working_dir: /src - command: bats /src/unit-tests/ \ No newline at end of file + - .:/code:ro + - ./unit-tests/fixtures:/var/lib/buildkite-agent/builds:ro + command: /code/unit-tests \ No newline at end of file
packer/linux/conf/buildkite-agent/scripts/fix-buildkite-agent-builds-permissions+20 −5 modified@@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # To run the unit tests for this file, run the following command in the root of # the project: @@ -71,15 +71,30 @@ exit_if_blank "${AGENT_DIR}" exit_if_blank "${ORG_DIR}" exit_if_blank "${PIPELINE_DIR}" -# If we make it here, we're safe to go! - # We know the builds path: BUILDS_PATH="/var/lib/buildkite-agent/builds" # And now we can reconstruct the full agent builds path: PIPELINE_PATH="${BUILDS_PATH}/${AGENT_DIR}/${ORG_DIR}/${PIPELINE_DIR}" # => "/var/lib/buildkite-agent/builds/my-agent-1/my-org/my-pipeline" -if [[ -e "${PIPELINE_PATH}" ]]; then - /bin/chown -R buildkite-agent:buildkite-agent "${PIPELINE_PATH}" +# If it doesn't exist, then we won't do anything. +if [[ ! -e "${PIPELINE_PATH}" ]]; then + exit 0 +fi + + +# Check for symlink shenanigans +if [[ "$(realpath "${PIPELINE_PATH}")" != "${PIPELINE_PATH}" ]]; then + exit 4 fi + +# It should be a directory. +if [[ ! -d "${PIPELINE_PATH}" ]]; then + exit 5 +fi + +# If we make it here, we're safe to go! + +/bin/chown -R buildkite-agent:buildkite-agent "${PIPELINE_PATH}" +
unit-tests/fix-buildkite-agent-builds-permissions.bats+43 −19 modified@@ -1,93 +1,93 @@ #!/usr/bin/env bats -FIX_PERMISSIONS_SCRIPT="/src/packer/linux/conf/buildkite-agent/scripts/fix-buildkite-agent-builds-permissions" +FIX_PERMISSIONS_SCRIPT="/code/packer/linux/conf/buildkite-agent/scripts/fix-buildkite-agent-builds-permissions" -@test "Slashes in the agent arg cause an exit 1" { +@test "Slashes in the agent arg cause an exit 1 (A)" { run "$FIX_PERMISSIONS_SCRIPT" "/" "abc" "abc" [ "$status" -eq 1 ] } -@test "Slashes in the agent arg cause an exit 1" { +@test "Slashes in the agent arg cause an exit 1 (B)" { run "$FIX_PERMISSIONS_SCRIPT" "abc/" "abc" "abc" [ "$status" -eq 1 ] } -@test "Slashes in the agent arg cause an exit 1" { +@test "Slashes in the agent arg cause an exit 1 (C)" { run "$FIX_PERMISSIONS_SCRIPT" "/abc" "abc" "abc" [ "$status" -eq 1 ] } -@test "Slashes in the agent arg cause an exit 1" { +@test "Slashes in the agent arg cause an exit 1 (D)" { run "$FIX_PERMISSIONS_SCRIPT" "abc/def" "abc" "abc" [ "$status" -eq 1 ] } -@test "Slashes in the agent arg cause an exit 1" { +@test "Slashes in the agent arg cause an exit 1 (E)" { run "$FIX_PERMISSIONS_SCRIPT" "abc/def/ghi" "abc" "abc" [ "$status" -eq 1 ] } -@test "Slashes in the agent arg cause an exit 1" { +@test "Slashes in the agent arg cause an exit 1 (F)" { run "$FIX_PERMISSIONS_SCRIPT" "/abc/" "abc" "abc" [ "$status" -eq 1 ] } -@test "Slashes in the org arg cause an exit 1" { +@test "Slashes in the org arg cause an exit 1 (A)" { run "$FIX_PERMISSIONS_SCRIPT" "abc" "/" "abc" [ "$status" -eq 1 ] } -@test "Slashes in the org arg cause an exit 1" { +@test "Slashes in the org arg cause an exit 1 (B)" { run "$FIX_PERMISSIONS_SCRIPT" "abc/" "abc" "abc" [ "$status" -eq 1 ] } -@test "Slashes in the org arg cause an exit 1" { +@test "Slashes in the org arg cause an exit 1 (C)" { run "$FIX_PERMISSIONS_SCRIPT" "abc" "/abc" "abc" [ "$status" -eq 1 ] } -@test "Slashes in the org arg cause an exit 1" { +@test "Slashes in the org arg cause an exit 1 (D)" { run "$FIX_PERMISSIONS_SCRIPT" "abc" "abc/def" "abc" [ "$status" -eq 1 ] } -@test "Slashes in the org arg cause an exit 1" { +@test "Slashes in the org arg cause an exit 1 (E)" { run "$FIX_PERMISSIONS_SCRIPT" "abc" "abc/def/ghi" "abc" [ "$status" -eq 1 ] } -@test "Slashes in the org arg cause an exit 1" { +@test "Slashes in the org arg cause an exit 1 (F)" { run "$FIX_PERMISSIONS_SCRIPT" "abc" "/abc/" "abc" [ "$status" -eq 1 ] } -@test "Slashes in the pipeline arg cause an exit 1" { +@test "Slashes in the pipeline arg cause an exit 1 (A)" { run "$FIX_PERMISSIONS_SCRIPT" "abc" "abc" "/" [ "$status" -eq 1 ] } -@test "Slashes in the pipeline arg cause an exit 1" { +@test "Slashes in the pipeline arg cause an exit 1 (B)" { run "$FIX_PERMISSIONS_SCRIPT" "abc" "abc" "abc/" [ "$status" -eq 1 ] } -@test "Slashes in the pipeline arg cause an exit 1" { +@test "Slashes in the pipeline arg cause an exit 1 (C)" { run "$FIX_PERMISSIONS_SCRIPT" "abc" "abc" "/abc" [ "$status" -eq 1 ] } -@test "Slashes in the pipeline arg cause an exit 1" { +@test "Slashes in the pipeline arg cause an exit 1 (D)" { run "$FIX_PERMISSIONS_SCRIPT" "abc" "abc" "abc/def" [ "$status" -eq 1 ] } -@test "Slashes in the pipeline arg cause an exit 1" { +@test "Slashes in the pipeline arg cause an exit 1 (E)" { run "$FIX_PERMISSIONS_SCRIPT" "abc" "abc" "abc/def/ghi" [ "$status" -eq 1 ] } -@test "Slashes in the pipeline arg cause an exit 1" { +@test "Slashes in the pipeline arg cause an exit 1 (F)" { run "$FIX_PERMISSIONS_SCRIPT" "abc" "abc" "/abc/" [ "$status" -eq 1 ] } @@ -136,3 +136,27 @@ FIX_PERMISSIONS_SCRIPT="/src/packer/linux/conf/buildkite-agent/scripts/fix-build run "$FIX_PERMISSIONS_SCRIPT" "abc" "abc" "" [ "$status" -eq 3 ] } + +@test "Non-existing path is skipped" { + "$FIX_PERMISSIONS_SCRIPT" "g" "h" "i" +} + +@test "Symlinks in the args cause an exit 4 (A)" { + run "$FIX_PERMISSIONS_SCRIPT" "link" "b" "c" + [ "$status" -eq 4 ] +} + +@test "Symlinks in the args cause an exit 4 (B)" { + run "$FIX_PERMISSIONS_SCRIPT" "a" "link" "c" + [ "$status" -eq 4 ] +} + +@test "Symlinks in the args cause an exit 4 (C)" { + run "$FIX_PERMISSIONS_SCRIPT" "a" "b" "link" + [ "$status" -eq 4 ] +} + +@test "Path not a directory causes an exit 5" { + run "$FIX_PERMISSIONS_SCRIPT" "d" "e" "f" + [ "$status" -eq 5 ] +}
unit-tests/fixtures/a/b/c/.gitkeep+0 −0 addedunit-tests/fixtures/a/b/link+1 −0 added@@ -0,0 +1 @@ +c \ No newline at end of file
unit-tests/fixtures/a/link+1 −0 added@@ -0,0 +1 @@ +b \ No newline at end of file
unit-tests/fixtures/d/e/f+0 −0 addedunit-tests/fixtures/g/.gitkeep+0 −0 addedunit-tests/fixtures/link+1 −0 added@@ -0,0 +1 @@ +a \ No newline at end of file
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
4News mentions
0No linked articles in our index yet.