Go · github.com/zhenorzz/goploy
Goploy: Arbitrary File Read via Path Traversal in /deploy/fileDiff allows Remote Server Compromise
Click here to jump to the Simplified Chinese version (点击跳转到简体中文版本)
Goploy is an open-source automation deployment system. A severe path traversal vulnerability exists in its backend API endpoints, specifically /deploy/fileDiff (File Compare), when handling file paths provided by the client.
The original logic of this endpoint is to read a local project file and compare it with a file on a remote target server. However, due to insufficient validation and sanitization of the filePath parameter, and the lack of security constraints on the final absolute file path, malicious paths containing ../ are directly executed within the system.
This leads to a dual arbitrary file read issue:
os.ReadFile is tricked by the directory traversal payload to read any file via its absolute path on the Goploy local host (returned in the srcText field of the response body).serverID. Influenced similarly by the directory traversal, it reads any file on the configured remote server (returned in the distText field of the response body).The threshold for exploiting this vulnerability is extremely low, and the conditions are very easily met. The system comes with a built-in member role upon default installation, which is granted the "File Compare" permission by default. This means that as long as a normal low-privileged user is added to the system, they inherently possess the basic privileges required to call the vulnerable endpoint. The only prerequisite for the attack is that at least one project and one associated server are configured in the system.
An attacker only needs to specify the correct namespace header (e.g., G-N-ID: 1) via a packet capture tool to bypass simple restrictions. By enumerating available serverId parameters, the attacker can successfully execute path traversal via this endpoint, reading arbitrary files on both the local Goploy host and all remote target servers managed by Goploy.
Obtain Normal User Privileges Log in to the system using any registered low-privileged account to obtain valid authentication credentials (Cookie/Token) and its corresponding authorized Namespace ID.
Construct Malicious Request
Send a POST request containing the directory traversal characters ../ to the target endpoint /deploy/fileDiff, while including the G-N-ID header.
PoC Example (Reading /etc/passwd and enumerating serverId):
curl -s -X POST -b "goploy_token=<valid_cookie>" \
-H "Content-Type: application/json" \
-H "G-N-ID: 1" \
-d '{"projectId":1,"serverId":1,"filePath":"../../../../../../../../../../etc/passwd"}' \
"http://<target-host>/deploy/fileDiff"
Reproduction Result
The server will return the complete contents of the /etc/passwd file from both the host and the remote server.
Environment Setup Published an arbitrary project using the super admin account:
Configured two managed remote servers:
Created a normal user and assigned the member role (which includes File Compare permission):
Obtain Normal User Privileges
Log in to the system using the registered test account to obtain valid authentication credentials (Cookie/Token).
Execute poc.py (See below)
Parameter Explanation:
-u : Target URL
-t : Target Cookie/Token to use
-f : File to read
-s : ID of the managed server to read from
Reading from the first managed server (Server ID: 1):
python poc.py -u http://192.168.x.x:8080 -t eyJhbGxxxxxxxxxx... -f /etc/passwd -s 1
python poc.py -u http://192.168.x.x:8080 -t eyJhbGxxxxxxxxxx... -f /etc/passwd -s 2
Reproduction Result
The server successfully returns the full contents of the /etc/passwd file from both the Goploy host and the designated remote servers.
Through this vulnerability, an attacker can bypass authorization to read any sensitive files on the host machine as well as all managed target servers. For example:
/etc/passwd or /etc/shadow on the local or remote target servers to obtain host system user information.~/.ssh/id_rsa) across different systems, enabling passwordless SSH access to the host or cross-network connections to other servers to steal administrative control, achieving the equivalent of Remote Code Execution (RCE).serverID, an attacker can use Goploy as a jump server (bastion host) to conduct large-scale information theft against all bound deployment target systems.../, ..\, and %00 that can cause directory traversal and truncation when receiving and processing file paths provided by clients.filepath.Clean to format the path. Before executing system file read/write operations, strictly verify whether the parsed absolute path prefix is within the legitimate restricted directory scope allowed by the application (such as a preset sandbox directory or project workspace).#!/usr/bin/env python3
import requests
import argparse
import sys
import urllib3
import json
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
def banner():
print(r"""
____ _ ____ ____
/ ___| ___ _
Is your project exposed to this? Stateward checks every dependency on every pull request and flags it only if your code actually reaches it.
Check my repoSources: CISA KEV (public domain), OSV.dev & GitHub Advisory Database (CC-BY-4.0), FIRST EPSS, NVD/CWE (public domain). Served live from the Stateward advisory database.