VYPR
High severityNVD Advisory· Published Dec 22, 2023· Updated Aug 2, 2024

CVE-2023-43116

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.

PackageAffected versionsPatched versions
github.com/buildkite/elastic-ci-stack-for-aws/v6Go
< 6.7.06.7.0

Affected products

2

Patches

1
8f79882b6aa1

Prevent 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 added
  • unit-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 added
  • unit-tests/fixtures/g/.gitkeep+0 0 added
  • unit-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

4

News mentions

0

No linked articles in our index yet.