Security vulnerabilities

  • Status Closed
  • Assigned To
    cbay
  • Private
Attached to Project: Security vulnerabilities
Opened by zlynv - 25.09.2026
Last edited by cbay - 28.09.2026

FS#504 - Customer-controlled `vhost_additional_directives` enables SSRF to host-local services

Customer-controlled `vhost_additional_directives` enables SSRF from the shared Apache frontend to host-local services (and host file exposure via `Alias`)

Severity suggested: Medium (program tier: "Exposure of internal tools" / SSRF, CVSS 4.0-6.9; no customer data was accessed)

Affected endpoint:

PATCH /v1/site/<id>/

(API v1, token auth) and the Site configuration form in the panel

Summary

A normal hosting account can modify

vhost_additional_directives

, which is
appended verbatim to the shared Apache frontend's vhost configuration. This permits
customer-controlled

ProxyPass

directives, allowing a public customer domain to
act as an SSRF proxy into

127.0.0.1

services on the frontend host. I verified
access to multiple host-local HTTP services, including Monit on port 2812 and an internal
JSON API on port 8300. The customer shell runs on a separate host (

jobs4

)
where these loopback services are not reachable, demonstrating that the issue crosses the
platform's tenant/network isolation boundary. The same configuration primitive also allows

Alias

-based exposure of files readable by the web-tier process, including

/etc/passwd

.

Per the program's SSRF guidance I stopped as soon as the issue was established and am
reporting it without further internal testing.

Background - why this is a security issue even though the feature is documented

The field is documented (API: "Directives qui seront ajoutées à la fin de la
configuration Apache pour ce virtual host"
) and exposed in the panel UI, so customers
are intentionally allowed to add directives. The vulnerability is not that the feature
exists, but that security-sensitive Apache capabilities are exposed across a tenant
isolation boundary
: the customer is not merely configuring their own application, they
are influencing the network and filesystem reachability of the shared web frontend
process. Directives like

Header set

are reasonable for customers;

ProxyPass

,

Alias

,

Include

change the security
boundary of the host itself.

Primary issue: SSRF from the shared web frontend into host-local services

*A. The field is executed, not stored:*

{"vhost_additional_directives":"Header set X-Recon-Directive 1"}

→

204

→ subsequent response to my own site contains

x-recon-directive: 1

.

*B. The frontend itself is the proxy backend:*

{"vhost_additional_directives":"ProxyPass /reconint http://127.0.0.1:80/"}

→

204

→

GET /reconint/nonexist123

(with Host of my own site)
→

404

with the frontend's own response body
(

Site not found + Request ID: ...

). The request was processed by the shared
Apache instance and forwarded to another listener on its own

127.0.0.1

, with
the response relayed back through my public domain.

*C. The proxy reaches host-local services:*

One

ProxyPass

per port,

GET /

only, against a deliberately
limited set of ports taken from the platform's own service inventory (no port scan):

:2812  -> 401  Monit web UI ("You are not authorized to access monit...")
:8083  -> 401  Unauthorized
:8593  -> 401  Unauthorized
:8570  -> 200  HTTP service answering
:8598  -> 401  Python http.server-style error page
:8300  -> 404  {"code":"not_found"}   (internal JSON API)
:5001-5005, :8443, :8568, :10086 -> 503 (no service / non-HTTP)
:8590, :5199, :4949 -> 502

All of these are bound to

127.0.0.1

on the frontend host and respond to
requests made through my public site. I did not attempt to authenticate to any of them
(no credentials tried, no brute force); Monit currently requires authentication (401) and
I stopped there. The security point demonstrated is reachability: customer-controlled
configuration creates a request path from my public domain to host-local management and
API services.

*D. The isolation boundary - this is not "the customer already has SSH":*

- A scheduled job on the account shell reports

hostname = jobs4
(<code>uid=550157</code>). From there, <code>curl http://127.0.0.1/</code> //fails//
outright - there is no port-80 listener at all on <code>jobs4</code>.

- The site is served by

http22

: the same

Alias

primitive reading

<code>/etc/hostname</code> returns <code>http22</code>.

- There is no shell on

http22

for this account. The frontend's loopback

services are therefore unreachable from the account's legitimate environment by any
other means.

```text
Attacker (ordinary tenant)

 |  PATCH /v1/site/<id>/  ->  vhost_additional_directives
 v

Shared Apache on http22

 |  ProxyPass
 v

127.0.0.1:&lt;port&gt; on http22 → Monit / internal HTTP + JSON APIs

 |
 v  response relayed

public customer domain

Account shell: jobs4 → 127.0.0.1 (no relevant services reachable)
```

Without the configuration injection, this request path does not exist.

Secondary issue: host-local file exposure via `Alias`

{"vhost_additional_directives":"Alias /reconlfi \"/etc\""}

→

204

→

GET /reconlfi/passwd

→

200

with the content of

/etc/passwd

;

/reconlfi/hosts

→

200

(

/etc/hosts

);

/reconlfi/hostname

→

200

(

http22

). Directory listing stays

403

.

This is limited to files readable by the web-tier process - Apache does not bypass
filesystem permissions - and independently proves the injected directives execute in the
security context of the shared frontend, not as inert customer metadata.

Impact

- Tenant → frontend network position: any customer site can be turned into an SSRF proxy

to the frontend host's loopback services, including its management interface (Monit) and
internal HTTP/JSON APIs, with responses read through the customer's public domain.

- Host-level information disclosure of files readable by the frontend process

(<code>/etc/passwd</code>, <code>/etc/hosts</code>, <code>/etc/hostname</code>
demonstrated).

- No authentication was attempted against exposed services; no customer data was accessed,

modified, or destroyed.

Remediation

Keep the feature, restrict the directive set: allowlist benign customer directives
(headers, rewrite, limits…) and deny, for customer vhosts at least,

Alias

,

Redirect

,

ProxyPass

,

ProxyPassReverse

,

RewriteRule ... [P]

and

Include

- or run customer vhosts without
those modules and validate the generated configuration (

apachectl -t

) before
reload.

Testing methodology and cleanup

- Only my own account/site; the panel's documented feature and API only.
-

GET /

(read-only) probes; no authentication attempts, no brute force, no

port scan (ports pre-listed from the platform's own inventory), no writes to internal
services, no DoS or load testing, requests kept serial and slow per program rules.

- All changes reverted and verified: probe paths return

404

, injected header

absent, site <code>200</code>; temporary job and files deleted.
Closed by  cbay
28.09.2026 08:16
Reason for closing:  Duplicate
Additional comments about closing:  

https://security.alwaysda ta.com/task/305

Loading...

Available keyboard shortcuts

Tasklist

Task Details

Task Editing