Revive Adserver · Report #3400506
Stored XSS in Conversion Statistics via Tracker Name
How it was found
I found stored XSS on the conversion statistics page. Advertisers can inject malicious JavaScript through tracker names, which executes when admins view conversion reports (www/admin/stats-conversions.php:356). I was able to steal admin session cookies using this vulnerability. This is a privilege escalation problem: low-privilege advertiser accounts can compromise high-privilege admin accounts.
--
Affected System
- Product: Revive Adserver
- Version Tested: 6.0.1
- Component: Statistics / Conversion Reports
- File:
www/admin/stats-conversions.php:356 - URL:
http://[host]/www/admin/stats-conversions.php?clientid=[id]
Vulnerable Code
// www/admin/stats-conversions.php:356
echo "<td align='$phpAds_TextAlignLeft' style='padding: 0 4px'>{$conversion['trackername']}</td>
<td align='$phpAds_TextAlignLeft' style='padding: 0 4px'>{$conversion['campaignid']}</td>
<td align='$phpAds_TextAlignLeft' style='padding: 0 4px'>{$conversion['campaignname']}</td>";
The Problem:
- Tracker names are output directly without
htmlspecialchars()escaping - The data comes from advertiser-controlled input (tracker creation form)
- No input validation strips HTML tags at storage time
- Admins viewing conversion reports execute the payload in their browser context
How I Reproduced It
Prerequisites:
- Advertiser account (low privileges)
- Admin account to view the report (for testing impact)
Steps:
- Login as advertiser and create a malicious tracker:
- Navigate to: Inventory → Advertisers → Click your advertiser name (e.g., "Test Advertiser") → Trackers tab
- Click Add new tracker
- Set tracker name to:
<img src=x onerror="alert('XSS: ' + document.cookie)"> - Set tracker type to "Sale" and status to "Active"
- Click Save Changes
- The tracker is now saved (tracker ID 1)
{F4935037}
-
Create conversion records (via normal tracking or database):
-- Link conversion to malicious tracker INSERT INTO rv_data_intermediate_ad_connection ( tracker_id, ad_id, inside_window, tracker_date_time, connection_date_time, connection_action, connection_status, updated ) VALUES (1, 1, 1, NOW(), NOW(), 1, 4, NOW()); -
Login as admin and navigate to:
http://[host]/www/admin/stats-conversions.php?clientid=1Note: This page may not be accessible via the menu in default/fresh installations. See "Menu Configuration Note" in the Notes section below for details.
-
Result: JavaScript alert fires immediately:
XSS: sessionID=abc123; ox_install_session_id=def456
{F4935020}
I confirmed the XSS executes in the admin's browser context with full cookie access. The payload persists - it fires every time any admin views conversion statistics for that advertiser.
Notes
Additional Findings:
While investigating this issue, I noticed:
- Lines 357-358 also lack
htmlspecialchars()oncampaignidandcampaignname - Campaign names are also user-controlled (by advertisers) and suffer from the same vulnerability
- Other
stats-*.phpfiles may have similar issues - I haven't audited them all yet
Testing Scope:
I tested this vulnerability in an isolated Docker environment using accounts I created. I did not:
- Test against production/public Revive Adserver installations
- Attempt actual exploitation beyond controlled PoC
- Exfiltrate or access any real user data
Menu Configuration Note:
Important: The stats-conversions.php page is not included in the default menu system on fresh Revive Adserver installations. During testing, I had to manually enable it by modifying lib/OA/Admin/Menu/config.php to add the menu entry:
$oMenu->addTo("2.1", new OA_Admin_Menu_Section("stats-conversions",
'Conversions', "stats-conversions.php?clientid={clientid}",
false, "statistics/conversions"));
This is likely a configuration issue rather than a security control, as:
- The code-level permission check (
OA_Permission::enforceAccount) allows advertiser/manager access - Other statistics pages with similar data are accessible
- The vulnerable code exists regardless of menu visibility
Impact
An advertiser (or compromised advertiser account) can inject persistent XSS that executes when admins view conversion statistics. I successfully captured admin session cookies, which enable full account takeover. The attacker can then create admin accounts, modify campaigns, access all advertiser data, or inject code affecting all users. This works because advertisers routinely create trackers, and admins routinely review conversion statistics - no unusual behavior required.