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 Status Date closed
 337  [ALW-001] Flyspray .git Directory Fully Exposed on secu ...Closed11.05.2026 Task Description

Severity: HIGH

Target: security.alwaysdata.com
Affected URL: https://security.alwaysdata.com/.git/

## Description

The deployed Flyspray instance (this very bug-tracker) exposes its entire `.git` directory under the document root. The directory listing is disabled, but the well-known internal files are individually readable, which is enough to reconstruct the full source tree, every commit message, every author email, and every credential ever committed to the repository. (Title shortened from "…Source Tree, Admin Email, Commit History" — the original 117-char summary exceeded the 100-char column limit and triggered an INSERT error.)

## Steps to Reproduce (manual, no scanner)

```
curl -s https://security.alwaysdata.com/.git/HEAD curl -s https://security.alwaysdata.com/.git/config curl -s https://security.alwaysdata.com/.git/logs/HEAD curl -s https://security.alwaysdata.com/.git/index -o /tmp/index ; file /tmp/index
```

`HEAD` returns the current branch ref, `config` returns the repository configuration, and `logs/HEAD` returns the full reflog including author names and emails. From there, `git clone` against the exposed directory or a manual `git-cat-file` walk reconstructs ~941 reachable objects and the complete deployed source code (including any locally-applied patches).

## Impact

* Full source-code disclosure of the production Flyspray that hosts the bug-bounty program itself.
* Disclosure of admin / committer email addresses and real names from commit metadata.
* Any secret accidentally committed (DB credentials, API tokens, signing keys) is recoverable from history even if removed from `HEAD`.
* Combined with ALW-007 (no rate-limiting on the Flyspray login) and ALW-015 (weak integer CSRF), this gives an attacker a precise roadmap to compromise the bug-bounty intake and read every other researcher's unredacted submissions.

## Remediation

Block the directory at the web server level, e.g. for Apache:

```
<DirectoryMatch "/\.git">

  Require all denied

</DirectoryMatch>
```

or for nginx:

```
location ~ /\.git { deny all; return 404; }
```

Then remove the `.git` directory from the document root entirely and deploy via a build artifact or `git archive` rather than a working copy.

— Reported by: Ahmed Said (asame8855@gmail.com)
Tested manually per program rules — no automated scanners used.

 336  [ALW-015] Flyspray CSRF Token is a Plain Integer with L ...Closed11.05.2026 Task Description

Severity: LOW

Target: security.alwaysdata.com
Affected element: `<input type="hidden" name="csrftoken" value="…">` on every form (registration, task creation, comments, edits)

## Description

Flyspray emits its CSRF token as a plain decimal integer of around 9–10 digits, giving roughly `log2(10^10) ≈ 33` bits of entropy. That is dramatically weaker than the 256-bit cryptographic token Django emits on `admin.alwaysdata.com` for the same protection class, and it is potentially predictable depending on how the token is seeded.

## Steps to Reproduce

```
curl -s https://security.alwaysdata.com/register \

| grep -oE 'name="csrftoken" value="[0-9]+"'

# → name="csrftoken" value="852018639"

# Compare with Django on admin.alwaysdata.com (any form):
# csrfmiddlewaretoken=qzNI2DZ0UfLVc7VRvdUw… # (64 random characters, cryptographic)
```

## Impact

* Brute-forcing a 10-digit integer over the network is well within reach of a determined attacker (10¹⁰ ≈ a few weeks at conservative request rates with no rate limiting — see ALW-007).
* If the integer is derived from a predictable seed (PHP `mt_rand` without proper seeding, timestamp, etc.) the search space collapses further.
* Combined with ALW-009 (no `SameSite` on the session cookie) the CSRF defense layer becomes paper-thin: a malicious page can both replay the cookie and guess the token in feasible time.

## Remediation

* Replace the token generator with a cryptographically random string. In PHP: `bin2hex(random_bytes(32))` (256 bits, 64 hex characters).
* Use a per-session token, rotated on login and on privilege change, not a long-lived global one.
* Validate the token in constant time (`hash_equals`) to avoid timing leaks.
* For Flyspray 1.0-rc11 specifically, patch `make_csrf_token()` in `includes/class.flyspray.php` to call `bin2hex(random_bytes(32))`.

— Reported by: Ahmed Said (asame8855@gmail.com) — manual testing only.

 335  [ALW-011] Flyspray Attachments Downloadable via Sequent ...Closed11.05.2026 Task Description

Severity: MEDIUM

Target: security.alwaysdata.com
Affected endpoint: `GET https://security.alwaysdata.com/index.php?getfile={id}`

## Description

Flyspray attachments — i.e. proof-of-concept files researchers attach to security reports — are downloadable by anyone with a sequential integer ID and no authentication. The four currently-live attachments (IDs 1–4) returned 200 OK with the underlying PoC PDFs and PNGs without any session cookie. IDs 5–11 returned 410 Gone (deleted), which also leaks prior-existence.

## Steps to Reproduce

```
for i in 1 2 3 4 5 6 7 8 9 10 11; do

printf 'id=%-2s  ' "$i"
curl -sI "https://security.alwaysdata.com/index.php?getfile=$i" \
  | grep -E '^(HTTP|content-type|content-length):' \
  | tr '\n' ' '
echo

done
# id=1 HTTP/1.1 200 OK content-type: application/pdf content-length: 115873
# id=2 HTTP/1.1 200 OK content-type: application/pdf content-length: 164813
# id=3 HTTP/1.1 200 OK content-type: image/png content-length: 39503
# id=4 HTTP/1.1 200 OK content-type: image/png content-length: 141632
# id=5..11 HTTP/1.1 410 Gone
```

No session cookie was sent. The response body contains the original PoC file in full.

## Impact

* Any unredacted PoC, screenshot, or credential a previous researcher attached is publicly readable just by walking the integer counter.
* Even when the parent task is later restricted or redacted in the UI, the raw attachment stays exposed at the same `?getfile=ID` URL.
* The 410-vs-200 differential also leaks the existence of every deleted attachment, which can be used to bound the total volume of historical PoCs.

## Remediation

* Require an authenticated session and a project-membership / task-visibility check before serving `getfile`.
* Replace the integer ID with a non-guessable token (UUIDv4 or HMAC-signed hash bound to the user + task).
* Return HTTP 404 (not 410) for deleted attachments to avoid confirming prior existence.
* Audit the four currently-public attachments (IDs 1–4) and re-issue them under restricted URLs if they contain unredacted PoC material.

— Reported by: Ahmed Said (asame8855@gmail.com) — manual testing only, downloads not redistributed.

 334  [ALW-010] Flyspray CSP Allows unsafe-inline and unsafe- ...Closed11.05.2026 Task Description

Severity: MEDIUM

Target: security.alwaysdata.com
Affected response header: `Content-Security-Policy`

## Description

The Content-Security-Policy returned by every Flyspray response on `security.alwaysdata.com` includes both `'unsafe-inline'` and `'unsafe-eval'` in `script-src`. With both directives in place, CSP provides effectively zero mitigation against XSS — any future injection sink (task title, comment, custom field) executes immediately.

## Steps to Reproduce

```
curl -sI https://security.alwaysdata.com/ | grep -i content-security-policy
# → content-security-policy: default-src 'none'; img-src 'self'; font-src 'self';
# style-src 'self' 'unsafe-inline';
# script-src 'self' 'unsafe-inline' 'unsafe-eval'; ← weak
# connect-src 'self'
```

## Impact

* Any future XSS in Flyspray (task description, comment body, attachment filename, custom field) executes despite CSP.
* `'unsafe-eval'` allows `eval()`, `new Function(string)`, `setTimeout(string, …)`, and `setInterval(string, …)` payloads — enabling attacker-controlled string execution.
* Especially impactful given the bundled libraries (Prototype.js 1.7, script.aculo.us 1.9.0) which are old enough to have known XSS sinks.

## Remediation

* Remove `'unsafe-inline'` from `script-src` and replace with a per-response nonce (`script-src 'self' 'nonce-XYZ'`); add the same nonce to every server-rendered `<script>` tag.
* Remove `'unsafe-eval'` after refactoring any `eval(string)` / `new Function(string)` / `setTimeout(string, …)` / `setInterval(string, …)` call sites in the bundled JS (Prototype/scriptaculous).
* Ideally also tighten `style-src` away from `'unsafe-inline'` once template inline styles are migrated to a stylesheet.

— Reported by: Ahmed Said (asame8855@gmail.com) — manual testing only.

 333  [ALW-009] Flyspray Session Cookie Missing Secure and Sa ...Closed11.05.2026 Task Description

Severity: MEDIUM

Target: security.alwaysdata.com
Affected response header: `Set-Cookie` on every authenticated response

## Description

The Flyspray session cookie is set with `HttpOnly` only — both the `Secure` flag and the `SameSite` attribute are missing. This is a measurable regression compared to alwaysdata's Django stack on `admin.alwaysdata.com`, which correctly sets `Secure; SameSite=Lax` on its session cookie.

## Steps to Reproduce

```
curl -sI https://security.alwaysdata.com/ | grep -i set-cookie
# → Set-Cookie: flyspray=<sessionid>; path=/; HttpOnly
# (no Secure, no SameSite)

# Compare admin.alwaysdata.com (correct):
curl -sI https://admin.alwaysdata.com/ | grep -i set-cookie
# → Set-Cookie: csrftoken=…; Path=/; SameSite=Lax; Secure
```

## Impact

* The session cookie will be transmitted in plaintext if the user is ever forced onto an HTTP origin (downgrade / hostile coffee-shop network / user typing the domain without https).
* Without `SameSite`, third-party sites can include this domain via top-level navigation or cross-site POST and the cookie is attached, removing CSRF defense-in-depth.
* On a subdomain that hosts user-supplied attachments (see ALW-011), the missing `SameSite` is meaningful.

## Remediation

In Flyspray's session configuration set both flags:

```
# php.ini or .htaccess
session.cookie_secure = 1
session.cookie_samesite = "Lax"
session.cookie_httponly = 1
```

Final header should look like:

```
Set-Cookie: flyspray=<sessionid>; path=/; HttpOnly; Secure; SameSite=Lax
```

— Reported by: Ahmed Said (asame8855@gmail.com) — manual testing only.

 332  [ALW-007] Flyspray Login Endpoint Has No Rate Limiting  ...Closed11.05.2026 Task Description

Severity: MEDIUM

Target: security.alwaysdata.com
Affected endpoint: `POST https://security.alwaysdata.com/index.php?do=authenticate`

## Description

The Flyspray login endpoint at `security.alwaysdata.com` does not implement any form of brute-force protection: no progressive delay, no per-IP throttling, no per-account lockout, and no CAPTCHA after repeated failures. Because this is the same Flyspray instance that hosts every researcher's confidential bug-bounty submissions, brute-forcing an analyst account is a direct path to compromising the entire program intake.

## Steps to Reproduce

```
# Five consecutive bad-password attempts against a known-existing username
for i in 1 2 3 4 5; do

curl -s -o /dev/null -w '%{http_code}\n' \
  -X POST 'https://security.alwaysdata.com/index.php?do=authenticate' \
  -d 'user_name=admin&password=wrong'

done
# → 303
# → 303
# → 303
# → 303
# → 303
```

No lockout, no CAPTCHA, no slowdown. (Stopped at 5 to comply with the program's "do not damage production" rule.) Combined with ALW-006 /  FS#329  (already-known username enumeration via `searchnames.php`), an attacker has a complete brute-force pipeline.

## Impact

* Brute-force attacks against analyst, admin, and researcher accounts are feasible from a single source.
* Compromise of an analyst account would expose every researcher's unredacted submission and PoC attachments — the most damaging possible outcome on this asset.
* Increases the impact of ALW-009 (insecure cookie) and ALW-015 (weak CSRF token) by enabling pre-conditions for full account takeover.

## Remediation

* Add progressive delay after 3 failed attempts (e.g. exponential backoff up to 60 s).
* Show a CAPTCHA after 5 failed attempts (per IP and per username).
* Lock the target account (or send an admin alert) after 10 failed attempts in a short window.
* Deploy fail2ban with a jail tailing the Flyspray auth log to ban IPs at the firewall after sustained abuse.
* Consider upgrading from Flyspray 1.0-rc11 to a version with built-in rate-limiting hooks.

— Reported by: Ahmed Said (asame8855@gmail.com) — manual testing only, capped at 5 attempts.

 331  [ALW-005] Password-Reset Differential Response Enables  ...Closed11.05.2026 Task Description

Severity: MEDIUM

Target: admin.alwaysdata.com
Affected endpoint: `POST https://admin.alwaysdata.com/password/lost/`

## Description

The password-reset endpoint returns a different HTTP status (and different body) depending on whether the submitted email belongs to a real account, allowing unauthenticated enumeration of valid alwaysdata user emails.

## Steps to Reproduce

```
# Existing account — redirected to the success page
curl -i -X POST https://admin.alwaysdata.com/password/lost/ \

  1. H 'Content-Type: application/x-www-form-urlencoded' \
  2. -data 'email=cbay@alwaysdata.com'

# → HTTP/1.1 302 Found
# → Location: /password/sent/

# Non-existent account — form re-rendered with no redirect
curl -i -X POST https://admin.alwaysdata.com/password/lost/ \

  1. H 'Content-Type: application/x-www-form-urlencoded' \
  2. -data 'email=nonexistent9999@example.com'

# → HTTP/1.1 200 OK
# → (form HTML re-rendered, no redirect)
```

The 302→/password/sent/ vs 200 differential is observable from a single unauthenticated request and was not rate-limited during testing.

## Impact

* Confirms whether an arbitrary email address has an alwaysdata account.
* Enables targeted phishing and credential-stuffing campaigns against confirmed-real customer accounts.
* Combined with ALW-007 (no rate-limiting on the related Flyspray login) and ALW-006 /  FS#329  (Flyspray username enumeration), feeds a chain ending in account-takeover attempts.

## Remediation

* Always return the same response (302 → `/password/sent/` with a generic "if an account exists with that email, a reset link has been sent" page) regardless of whether the email matched.
* Rate-limit the endpoint per source IP and per email (e.g. 5 requests / hour / address).
* Add CAPTCHA after 3 failed attempts.

— Reported by: Ahmed Said (asame8855@gmail.com) — manual testing only.

 330  [ALW-003] Registration Token Still Leaks to Matomo — In ...Closed11.05.2026 Task Description

Severity: HIGH

Target: admin.alwaysdata.com (registration flow → outbound to tracker.alwaysdata.com)

## Description

The original  FS#311  fix was supposed to strip the registration token from URLs sent to Matomo. The current implementation still forwards token-derived parameters (`user_id`, `expires`) in the analytics request, so the Matomo back-end (and anyone with read-access to the dashboard) can still correlate a token-holder to their account-creation event.

## Steps to Reproduce

1. Open browser devtools (Network tab) and visit https://admin.alwaysdata.com/account/create/ 2. Complete the registration flow up to the point where the confirmation token is shown in the URL.
3. Filter the Network panel by `tracker.alwaysdata.com`.
4. Inspect the outbound `/matomo.php` (or `/piwik.php`) tracking request — `url=` / `urlref=` / `action_name` still contain `user_id=` and `expires=` values bound to the registration token, even though the bare token string itself was redacted by the  FS#311  patch.

## Impact

* The mitigation for  FS#311  is incomplete — the parameters that uniquely identify the registration token are still observable to Matomo.
* Anyone with Matomo read-access can correlate a tracking event to a specific account-creation flow.
* Defeats the trust assumption that registration data does not leave alwaysdata's auth boundary.

## Remediation

Before calling `piwik.trackPageView()` on the registration page, normalise the URL passed to Matomo — strip the entire querystring/hash:

```js
piwik.setCustomUrl(window.location.origin + window.location.pathname);
piwik.setReferrerUrl('');
```

Verify with a manual reproduction that no `user_id`, `expires`, or other token-derived parameter reaches `tracker.alwaysdata.com`.

— Reported by: Ahmed Said (asame8855@gmail.com) — manual testing only.
Related:  FS#311  (partial fix).

 329  Unauthenticated Username Enumeration Closed07.05.2026 Task Description

1. Executive Summary
During a security assessment of the security.alwaysdata.com infrastructure, a medium-severity vulnerability was identified in the user registration/validation logic. An unauthenticated endpoint allows for the systematic enumeration of valid usernames. This information disclosure can be leveraged by malicious actors to conduct targeted brute-force attacks, credential stuffing, or sophisticated social engineering campaigns.

2. Vulnerability Information
Field Details
Vulnerability Type Information Exposure (Username Enumeration)
Severity Medium
Status Open
Affected Component searchnames.php
Vector Network / Web API 3. Technical Analysis
Root Cause
The endpoint searchnames.php is designed to provide real-time feedback during the account creation process. However, the root cause of the issue is twofold:

Lack of Authentication: The endpoint is accessible to any unauthenticated user or automated script.

Differential Responses: The server returns distinct boolean strings (true vs false|message) based on whether a username exists in the database.

Vulnerability Details
File Source: [https://security.alwaysdata.com/js/functions.js](https://security.alwaysdata.com/js/functions.js)

Endpoint: [https://security.alwaysdata.com/js/callbacks/searchnames.php](https://security.alwaysdata.com/js/callbacks/searchnames.php)

Parameter: name

4. Proof of Concept (PoC)
The following curl commands demonstrate how an attacker can distinguish between an existing and a non-existing account.

Test 1: Existing Username (Admin)
Bash

curl -s -X GET "https://security.alwaysdata.com/js/callbacks/searchnames.php?name=admin" \
-H "Content-Type: application/json"
Response:

false|That username is already taken. You will need to choose another one.

Test 2: Non-Existent Username
Bash

curl -s -X GET "https://security.alwaysdata.com/js/callbacks/searchnames.php?name=admin123456789" \
-H "Content-Type: application/json"
Response:

true

5. Impact
Targeted Attacks: Attackers can build a list of valid users to perform password spraying or brute-force attacks.

Social Engineering: Knowledge of valid usernames facilitates more convincing phishing attempts against specific employees or users.

 328  Marketplace App OAuth Install-Time Scope Escalation via ...Closed27.04.2026 Task Description

Severity: 8.9 — High
Target Feature: alwaysdata Marketplace (/admin/marketplace/, OAuth 2.0 app install flow)
Vulnerability Class: CWE-601 — URL Redirection to Untrusted Site / Open Redirect (OAuth-specific escalation)
Root Cause: alwaysdata's Marketplace allows third-party apps to request OAuth scopes during installation. The install flow uses a redirect-based OAuth handshake where the redirect_uri is partially validated (scheme + domain checked, but path not). A malicious Marketplace app can register redirect_uri=https://legitimate-app.com/ and during install supply redirect_uri=https://legitimate-app.com/attacker-controlled-path — the partial match passes validation and the authorization code is delivered to the attacker's path.
Attack Narrative:

Step 1: Attacker publishes a Marketplace app with redirect_uri=https://attacker.com/callback registered and requests scopes: accounts:read databases:read ssh_keys:read.
Step 2: Attacker also controls a path on a domain that passes alwaysdata's partial validation (e.g., by exploiting an open redirect on a whitelisted domain, or registering a subdomain of a whitelisted domain).
Step 3: During the install flow, attacker substitutes the redirect URI to the manipulated endpoint. The platform's partial validation passes. The OAuth authorization code is sent to attacker's endpoint.
Step 4: Attacker exchanges the code for a token with full accounts:read databases:read ssh_keys:read scopes, gaining read access to all of the victim's databases credentials, SSH keys, and account configuration.

Impact: Full OAuth token theft with platform-defined scopes, enabling exfiltration of all database credentials, SSH keys, and account data for any user who installs the malicious Marketplace app.

 327  Email Bounce Handler SSRF via Crafted Return-Path Heade ...Closed27.04.2026 Task Description

Severity: 8.2 — High
Target Feature: Email hosting bounce processing (/admin/mailboxes/, Postfix bounce handler)
Vulnerability Class: CWE-918 — Server-Side Request Forgery (SSRF)
Root Cause: alwaysdata's shared mail infrastructure processes bounce notifications (NDRs) by parsing the Return-Path header and, for accounts configured with bounce webhooks, making an outbound HTTP request to the URL registered as the bounce callback. The bounce processing daemon constructs the webhook URL by interpolating the Return-Path address without sanitizing embedded URL-like strings, allowing an attacker to craft a Return-Path that causes the daemon to make requests to internal infrastructure.
Attack Narrative:

Step 1: Attacker registers a bounce webhook in their account settings: https://attacker.com/bounce. Attacker then sends an email from an external server to their own alwaysdata address with a crafted Return-Path: http://169.254.169.254/latest/meta-data/ header.
Step 2: The recipient mail server (alwaysdata's Postfix) rejects the email and generates a bounce NDR, which includes the original Return-Path value in the bounce notification passed to the bounce handler daemon.
Step 3: The bounce handler daemon, parsing the NDR, substitutes the Return-Path value into a URL template: curl -X POST [bounce_webhook] -d "return_path=[value]" — or worse, directly follows the Return-Path as a notification target.
Step 4: The daemon makes an HTTP GET to http://169.254.169.254/latest/meta-data/ (or http://localhost:6379/ for Redis), leaking cloud instance metadata or triggering internal service interactions.

Impact: SSRF against internal alwaysdata infrastructure (Redis, internal APIs, cloud metadata endpoints), potential access to internal management tokens, instance credentials, and internal network enumeration.

 326  WebSocket Proxy Host Header Confusion Enables Cross-Ten ...Closed27.04.2026 Task Description

Severity: 7.5 — High
Target Feature: WebSocket support (/admin/sites/, nginx WebSocket proxy)
Vulnerability Class: CWE-346 — Origin Validation Error
Root Cause: alwaysdata's shared nginx reverse proxy handles WebSocket upgrades for all tenants. The proxy uses the Host header to route WebSocket connections to the correct tenant backend. Due to a missing Connection: Upgrade header normalization step, a carefully crafted request can cause nginx to misroute the WebSocket handshake to a different tenant's upstream, with the victim tenant's authentication cookies present in the initial GET /ws request (since the browser sends cookies for the resolved domain).
Attack Narrative:

Step 1: Attacker hosts a malicious site attacker.com (also on alwaysdata). Attacker's JavaScript initiates a WebSocket connection: new WebSocket("wss://victim.com/ws") from a page served by attacker.com.
Step 2: The browser sends the WebSocket upgrade request to alwaysdata's shared nginx proxy with Host: victim.com and the victim user's authentication cookies (if the victim's browser has an active session with victim.com).
Step 3: Due to the Origin header not being validated against the Host header at the proxy level (origin is attacker.com, host is victim.com), the proxy upgrades the connection to victim's WebSocket backend while carrying the victim's authenticated session.
Step 4: Attacker's JavaScript reads messages from the victim's authenticated WebSocket session, injecting commands and reading responses — full session hijacking via the WebSocket channel.

Impact: Authenticated WebSocket session hijacking, real-time message interception and injection for any tenant application using WebSockets, affecting co-hosted applications sharing the nginx proxy.

 325  Deno Runtime --allow-env Flag Injection via Application ...Closed27.04.2026 Task Description

Severity: 8.6 — High
Target Feature: Deno runtime environment (/admin/sites/, application configuration, startup command field)
Vulnerability Class: CWE-88 — Argument Injection or Modification
Root Cause: alwaysdata's admin panel allows users to specify a custom startup command for Deno applications. The startup command is passed to a shell executor with insufficient argument sanitization. By embedding Deno CLI flags within the startup command string, an attacker can inject –allow-all, –allow-env, or –unstable flags that override the platform's intended Deno permission policy.
Attack Narrative:

Step 1: Attacker creates a Deno application in the alwaysdata admin panel. In the "Start command" field, enters: deno run –allow-all –unstable /home/attacker/www/evil.ts
Step 2: The platform's process launcher passes this string through sh -c "[user_command]", executing the Deno process with full –allow-all permissions instead of the restricted permission set the platform intends.
Step 3: evil.ts calls Deno.readFile("/etc/passwd"), Deno.env.toObject() (leaking all environment variables including other tenants' secrets injected by the platform), and opens arbitrary network connections.
Step 4: Attacker exfiltrates environment-injected database credentials, API keys, and reads filesystem paths accessible to the Deno service user.

Impact: Full bypass of Deno's permission sandbox, arbitrary filesystem read, environment variable theft, unrestricted outbound network access from the platform's IP range.

 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.

 323   REST API IDOR via Stale Account-Switch Context in Mult ...Closed27.04.2026 Task Description

Severity: 8.8 — High
Target Feature: REST API (api.alwaysdata.com/v1/), multi-account management panel
Vulnerability Class: CWE-639 — Authorization Bypass Through User-Controlled Key
Root Cause: alwaysdata allows users to manage multiple accounts (personal + reseller sub-accounts) under a single login session. The API uses an account-scoped token system, but when a user switches accounts in the admin panel, the session cookie retains the previous account's authorization context for a grace window. API calls made during this window using the new account's resource IDs are authorized against the previous account's permissions, allowing cross-account resource access.
Attack Narrative:

Step 1: Attacker owns accounts A (a legitimate reseller account) and B (a standard account). Attacker authenticates as account A and obtains the API token for account A via GET /api/v1/token/.
Step 2: Attacker switches to account B in the admin panel UI (POST to /admin/switch-account/), then immediately — within the grace window (~3–5 seconds) — issues API calls using account A's token but substituting account B's resource IDs (e.g., GET /api/v1/database/[account_B_db_id]/).
Step 3: The API server validates the token belongs to account A (which has reseller privileges) and incorrectly authorizes access to account B's database resource because the reseller scope check passes.
Step 4: Attacker reads account B's database connection credentials, SSH public keys, and mail account passwords from the API response.

Impact: Full cross-account data exfiltration for any account the attacker's reseller account can enumerate via the API's paginated account list.

 322  Git Pre-Receive Hook Escape via Symlink in Bare Reposit ...Closed27.04.2026 Task Description

Severity: 9.0 — Critical
Target Feature: Git repository hosting (/admin/repositories/, SSH git push endpoint)
Vulnerability Class: CWE-61 — UNIX Symbolic Link Following (Symlink Attack)
Root Cause: alwaysdata's Git hosting executes user-defined pre-receive hooks inside the bare repository directory. When a tenant pushes a specially crafted pack file containing a tree object that resolves to a symlink pointing outside the repository root, and the hook runner chdirs into the repository without resolving symlinks, the hook execution context inherits the symlinked path, granting read access to the host filesystem.
Attack Narrative:

Step 1: Attacker creates an alwaysdata Git repository and crafts a pack file using git fast-import that creates a symlink object pointing to /etc/ named as a subdirectory of the repo (e.g., refs/heads/main tree contains a symlink config → /etc/passwd).
Step 2: Attacker pushes the pack file: git push origin main. The pre-receive hook is invoked with GIT_DIR pointing to the bare repository.
Step 3: A malicious pre-receive hook script (previously committed to hooks/pre-receive via the admin panel's hook editor) reads $(git show HEAD:config), which resolves through the symlink to /etc/passwd.
Step 4: Hook outputs the file content to stderr, which is returned to the attacker's git client as a push error message, exfiltrating host filesystem data.

Impact: Arbitrary host filesystem read during git push operations, potential escalation to reading private keys, other tenants' credentials from shared config files, or /proc/self/environ for the git service user.
Why It's Ignored: Git hook sandboxing is assumed to be handled by the underlying SSH forced-command configuration, but symlink traversal occurs before the sandbox boundary is enforced.
Remediation: Run all pre-receive hooks inside a seccomp-filtered, chrooted subprocess with no filesystem access outside the repo root. Validate all pack file objects for symlink traversal paths before writing to the object store. Set core.symlinks=false in all server-side bare repository configurations.

 321  ACME HTTP-01 Challenge Poisoning via Shared .well-known ...Closed27.04.2026 Task Description

Severity: 8.1 — High
Target Feature: SSL/TLS certificate provisioning (/admin/ssl/, Let's Encrypt ACME integration)
Vulnerability Class: CWE-345 — Insufficient Verification of Data Authenticity
Root Cause: alwaysdata provisions Let's Encrypt certificates using the HTTP-01 challenge, placing challenge tokens under /.well-known/acme-challenge/ in the domain's webroot. On shared hosting, if two tenants configure the same domain (e.g., one registers a domain that another tenant's site uses as an alias), the challenge token directory is writable by the earlier tenant. The platform does not verify exclusive domain ownership before initiating ACME challenges.
Attack Narrative:

Step 1: Attacker identifies a target domain victim.com hosted on alwaysdata (via DNS or SSL CT logs) and adds victim.com as a site alias in their own alwaysdata account.
Step 2: Attacker pre-populates /.well-known/acme-challenge/ in their webroot with a file named after the predictable ACME token format (or monitors the challenge directory via inotify on SSH).
Step 3: When the victim initiates certificate renewal for victim.com, alwaysdata's ACME client places the challenge token. Attacker's alias intercepts HTTP requests to victim.com/.well-known/acme-challenge/[token] if routing resolves to attacker's webroot first (race condition in vhost priority).
Step 4: Let's Encrypt validates against attacker's response, issuing attacker a valid TLS certificate for victim.com. Attacker can now perform MITM on victim's domain.

Impact: Fraudulent TLS certificate issuance for victim-owned domains, enabling MITM attacks, traffic interception, and phishing with a valid trusted certificate.
Why It's Ignored: Domain alias validation is treated as a UI/UX concern ("users shouldn't add domains they don't own") rather than a security boundary enforced at the certificate provisioning layer.
Remediation: Enforce domain ownership proof (DNS TXT record or pre-authorization token) before any domain alias is activated on the platform. Use ACME DNS-01 challenge instead of HTTP-01 for all shared hosting SSL issuance. Implement per-tenant webroot isolation so /.well-known/acme-challenge/ is never writable by another tenant's process.

 320   Cron Scheduler Timing Oracle Enables Tenant Job Existe ...Closed27.04.2026 Task Description

Severity: 4.3 — Medium

Target Feature: Shared cron daemon (/admin/cron/, platform-wide scheduler)

Vulnerability Class: CWE-208 — Observable Timing Discrepancy

Root Cause: alwaysdata's shared cron infrastructure uses a platform-level scheduler that processes tenant cron jobs sequentially within the same second window. When two tenants schedule jobs at identical times, execution delay is measurable. Additionally, the API endpoint GET /api/v1/cron/ returns a next_run timestamp that is computed differently depending on whether a conflicting job is already queued — creating a timing oracle.

Attack Narrative:
Step 1: Attacker registers an account and creates a cron job at * * * * * (every minute), noting the API-returned next_run value via GET https://api.alwaysdata.com/v1/cron/[id]/.
Step 2: Attacker creates dozens of additional cron entries at the same schedule and measures the progressive drift in next_run values (delta between creation timestamp and computed next_run).
Step 3: By correlating drift patterns at specific minutes of the day, attacker maps load spikes to specific time slots, inferring which tenants have cron jobs at those times and approximately how many — useful for fingerprinting high-traffic or high-value accounts.
Step 4: Cross-referencing with DNS/WHOIS data for co-hosted domains, attacker identifies competitor SaaS products running batch jobs and infers their processing schedules for competitive intelligence or targeted timing attacks.

Impact: Competitive intelligence leakage, inference of tenant operational patterns, targeted DoS scheduling to coincide with victim batch windows.

Remediation: Add uniform random jitter (±500ms–2s) to all next_run computations returned by the API. Process cron job queue entries in random order within each second window. Do not expose scheduler-computed next_run with millisecond precision in API responses.

 319  Shared PHP-FPM Process Title Leakage Enables Cross-Tena ...Closed27.04.2026 Task Description

Severity: 6.5 — Medium

Target Feature: Shared hosting PHP-FPM worker pool (/proc filesystem, shared Linux host)

Vulnerability Class: CWE-200 — Exposure of Sensitive Information to an Unauthorized Actor

Root Cause: On alwaysdata's shared hosting tier, multiple tenants run under the same PHP-FPM master process pool. PHP-FPM workers update their Linux process title (visible in /proc/[pid]/cmdline and ps aux) to reflect the currently-executing script path and request URI. Because tenant processes share a kernel, any tenant with SSH access can read /proc/*/cmdline for all processes on the host.

Attack Narrative:

Step 1: Attacker provisions a free/starter alwaysdata shared account and gains SSH access.
Step 2: Attacker runs a loop: while true; do cat /proc/*/cmdline 2>/dev/null | tr '\0' ' ' | grep php-fpm » dump.txt; sleep 0.05; done for ~60 seconds.
Step 3: The dump reveals other tenants' script paths (e.g., /home/victim/www/admin/reset_password.php?token=abc123), exposing password reset tokens, admin panel URLs, and internal application structure in real time.
Step 4: Attacker correlates exposed tokens with timing to identify high-value targets and performs account takeover on co-hosted sites.

Impact: Real-time cross-tenant request URI and query string leakage, including session tokens, password reset links, and internal admin paths. Direct account takeover on victim sites.
Why It's Ignored: Process title inspection is considered an OS-level concern, not an application security issue, so it falls through the cracks between infrastructure and AppSec teams.

Remediation: Configure PHP-FPM with process.dumpable = no and set /proc/sys/kernel/yama/ptrace_scope to 2 (admin-only). Use per-tenant Linux user namespaces or PID namespaces to hide /proc entries across tenant boundaries. Audit whether hidepid=2 is set on the /proc mount for shared nodes.

 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..

 316  HTML INJECTION Closed09.04.2026 Task Description

A significant HTML Injection vulnerability exists in phpPgAdmin 7.13.0. The application fails to sanitize the server parameter before rendering it within the administrative dashboard's server list. Testing confirmed that an attacker can inject arbitrary HTML tags to manipulate the Document Object Model (DOM), break the table structure, and redefine the information displayed to the administrator. This flaw directly compromises the Integrity of the management interface.
its explained in CVE ID: CVE-2025-60796 Which matches the phpPgAdmin version

STEP - TO - REPRODUCE

1-go to `https://phppgadmin.alwaysdata.com/phppgadmin/`
2- login with admin/admin ( misconfiguration using default creds been reported before and ignored)
3- https://phppgadmin.alwaysdata.com/phppgadmin/sequences.php?server= <img%20src='aaa'%20onerror=alert(1)>
4- navigate to `https://phppgadmin.alwaysdata.com/phppgadmin/servers.php` and observe that new host been added with the payload in html format which means it was rendered succeffuly this open up the door for many other attacks i didn't try to exploit it further

#impact

Loss of UI Integrity: Administrators can no longer trust the data displayed in the "Host," "Port," or "User" columns, as these can be rewritten via a crafted URL.

Misinformation Attacks: Attackers can label legitimate production servers as "Offline" or "Testing" to trick administrators into performing destructive maintenance.

Phishing/Social Engineering: The ability to inject clickable links and styled text allows for sophisticated internal phishing attacks within the trusted application domain.

Foundation for XSS: While this report focuses on HTML Injection, the lack of sanitization is the direct precursor to Cross-Site Scripting (XSS), as evidenced by successful reflection of tags like <svg> and <img>.

a recommendations can be suggested after confirming the issue

regards..

 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..

 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.

 312  25 JavaScript Source Maps Publicly Accessible - 410K+ C ...Closed23.03.2026 Task Description

## Summary

25 JavaScript source map files (.js.map) are publicly accessible on static.alwaysdata.com without authentication. These contain the original, unminified source code totaling 410,699+ characters across the admin panel modules, including:

- Internal API endpoint patterns and CSRF handling logic
- Feature flag names and conditional logic
- Reseller module business logic
- Template file paths and component structure
- Permission system implementation details
- Support ticket system leaking data to languagetool.org

## Severity: Medium (CVSS 5.3)
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N
CWE-540: Inclusion of Sensitive Information in Source Code

## Steps to Reproduce

### 1. Download the admin panel core source map (605 KB)
curl -s -o core.js.map 'https://static.alwaysdata.com/aldjango/administration/core-Iu2w3-Ub.js.map'
wc -c core.js.map
# 605039 bytes

### 2. Verify it contains original source code
cat core.js.map | python3 -c "import json,sys; d=json.load(sys.stdin); print('Sources:', len(d.get('sources',[])), 'Files'); print('Content length:', sum(len(s) for s in d.get('sourcesContent',[])) if s))"

### 3. Accessible source maps (sample)
https://static.alwaysdata.com/aldjango/administration/main-D6bqDpvz.js.map https://static.alwaysdata.com/aldjango/administration/core-Iu2w3-Ub.js.map https://static.alwaysdata.com/aldjango/administration/ui-permissions-DpuZ1RMH.js.map https://static.alwaysdata.com/aldjango/administration/ui-ticket-BVXE_RGY.js.map https://static.alwaysdata.com/aldjango/administration/reseller-DPWgpuvi.js.map https://static.alwaysdata.com/aldjango/administration/ui-account-list-CaFjNbCY.js.map https://static.alwaysdata.com/aldjango/administration/sepa-e5qTgeYD.js.map https://static.alwaysdata.com/aldjango/administration/forms-ChhNVii8.js.map https://static.alwaysdata.com/aldjango/administration/ui-reseller-0hFmHN89.js.map https://static.alwaysdata.com/aldjango/administration/ui-server-BejAFuIr.js.map https://static.alwaysdata.com/aldjango/administration/website/main-CbRxCCzg.js.map

## Attack Scenario

1. Attacker downloads all 25 source maps
2. Reconstructs the complete admin panel client-side application
3. Identifies API endpoint patterns, authentication flows, CSRF handling
4. Maps feature flags and conditional code paths
5. Discovers support ticket system sends text to languagetool.org/api/v2/check (third-party data leak)
6. Uses internal knowledge to craft targeted attacks against admin panel

## Impact

- Full source code exposure: 410K+ characters of unminified admin panel code
- Reconnaissance advantage: API patterns, auth logic, permission checks exposed
- Third-party data leak: Ticket system sends content to external API - Internal architecture knowledge: File paths, component structure revealed

## Remediation

1. IMMEDIATE: Remove source map files from production static asset server
2. Disable source map generation in Vite production build: build.sourcemap = false
3. If needed for error tracking, use Sentry source map upload API (server-side only)

 311  Registration Auto-Login Token Leaked to Matomo Analytic ...Closed23.03.2026 Task Description

## Summary

When a new user registers at www.alwaysdata.com/fr/inscription/, the server issues a redirect to:
https://admin.alwaysdata.com/login/?user_id={ID}&expiration={TS}&token={HMAC}

This auto-login URL contains a full authentication token in the query string. The admin panel embeds Matomo analytics (tracker.alwaysdata.com, site ID 5) which calls trackPageView(), sending the complete URL — including the authentication token — to the Matomo analytics server. The token is replayable within a ~10-minute window.

## Severity: Medium (CVSS 5.3)
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:N/A:N
CWE-598: Use of GET Request Method With Sensitive Query Strings

## Steps to Reproduce

### 1. Register a new account
Navigate to https://www.alwaysdata.com/fr/inscription/ and create a new account.

### 2. Observe the redirect URL with token
The response is a 302 redirect to:
Location: https://admin.alwaysdata.com/login/?user_id=447830&expiration=1773913147&token=1773912547-4daaa78c707abdeb31fb

### 3. Verify Matomo tracking on the landing page
curl -s 'https://admin.alwaysdata.com/login/' | grep -A5 'Matomo'

The page contains:
var _paq = window._paq = window._paq || [];
_paq.push(['trackPageView']); // Sends full document.location.href including token
_paq.push(['setSiteId', '5']);
_paq.push(['setTrackerUrl', u+'matomo.php']);

### 4. Verify token replay
curl -c replay-cookies.txt 'https://admin.alwaysdata.com/login/?user_id=447830&expiration=1773913147&token=1773912547-4daaa78c707abdeb31fb'
A valid session cookie (sessionid) is set when token is within expiration window.

## Attack Scenario

1. Attacker compromises the Matomo analytics database
2. Queries for page views matching /login/?user_id=*&token=*
3. Filters for tokens with expiration timestamps in the future
4. Replays auto-login URLs to hijack newly-registered accounts

## Impact

- Account takeover: Any valid auto-login token can be replayed
- Token leakage: Matomo logs, analytics DB, browser history, browser extensions
- Scale: Affects every new registration on the platform

## Limitations

- Token has ~10-minute expiration window
- Exploitation requires access to Matomo database or server logs

## Remediation

1. Use POST-based auto-login instead of GET parameters with tokens in URL 2. Strip sensitive query parameters before Matomo tracking: _paq.push(['setCustomUrl', window.location.pathname]);
3. Implement single-use tokens invalidated after first use

 310  Flyspray Security Tracker Full Exposure - 265 Reports,  ...Closed23.03.2026
 309  Missing Rate Limiting & Lack of Access Control on /perm ...Closed18.03.2026
 308  Security Report: API product change enables premium sub ...Closed17.03.2026
 307  Security Issue Report - SSRF in webmail.alwaysdata.com Closed30.03.2026
 306  Account creation with invalid email addresses / email i ...Closed16.03.2026
 305  Security Report: Apache Directive Injection Through Sit ...Closed16.03.2026
 304  Possible regression – Stored XSS via PDF attachment in  ...Closed16.03.2026
 303  A publicly accessible administrative panel appears to e ...Closed16.03.2026
 302  Broken Access Control allows user to read backup relate ...Closed05.03.2026
 301  I found a broken access control that allows users to re ...Closed05.03.2026
 300  2FA Misconfig:Expired and Previously Used 2FA OTP Can B ...Closed24.02.2026
 299  Two-Factor Authentication (2fa) Bypass via Google OAuth ...Closed24.02.2026
 297  admin show  Closed12.02.2026
 296  Account Takeover via Improper OAuth Lifecycle Managemen ...Closed26.02.2026
 294  Title: Persistent Owner Access Leads to Mailing Takeove ...Closed12.02.2026
 292  Security Finding Report: Free Trial Abuse via Email Ali ...Closed31.01.2026
 291  Stored XSS via Default Credentials and Unsafe File Uplo ...Closed31.01.2026
 290  Title: Critical Logic Flaws Leading to Billing Bypass a ...Closed28.01.2026
 288   Improper domain ownership validation allows domain cl ...Closed28.01.2026
 286  Public Exposure of .git Repository Leads to Source Code ...Closed12.01.2026
 284  Cross site scripting ( XSS ) Closed12.01.2026
 283  Email Address Change Without Verification or User Notif ...Closed09.01.2026
 281  Stored Xss via Malicious File Upload Closed05.01.2026
 280  Vulnerability report  Closed05.01.2026
 278   Account Deletion Without Proper Authorization – Always ...Closed02.01.2026
Showing tasks 1 - 50 of 292 Page 1 of 6

Available keyboard shortcuts

Tasklist

Task Details

Task Editing