CVEReports
Reports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Reports
  • Sitemap

Company

  • About
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Powered by Google Gemini & CVE Feed

|
•

GHSA-6mp4-q625-mxjp
CVSS 8.2|EPSS 0.10%

Short Links, Long Scripts: Pwning YOURLS via JSONP

Alon Barad
Alon Barad
Software Engineer•December 30, 2025•4 min read
PoC AvailableNot in KEV

Executive Summary (TL;DR)

The YOURLS API allows JSONP responses via a `callback` parameter. Versions prior to 1.10.3 failed to sanitize this parameter, allowing attackers to inject JavaScript payloads directly into the API response. This results in Reflected XSS, potentially compromising admin accounts.

A deep dive into a Reflected Cross-Site Scripting (XSS) vulnerability in the popular YOURLS URL shortener. By exploiting legacy JSONP implementations in the API, attackers can execute arbitrary JavaScript in the context of the administrator's session.

The Hook: The Ghost of Web 2.0

JSONP (JSON with Padding) is like that one guest at a party who overstays their welcome by about 15 years. Back in the dark ages before Cross-Origin Resource Sharing (CORS) was standardized, developers needed a way to fetch data from different domains. The hacky solution? <script> tags.

Since script tags aren't bound by the Same-Origin Policy, you could load a script from api.example.com. But to make use of the data, the API had to wrap the JSON response in a function call that defined on your page. Hence, callback=myFunction becomes myFunction({...}).

YOURLS (Your Own URL Shortener), a fantastic piece of self-hosted PHP software, supports this feature in its API. Unfortunately, handling JSONP correctly is notoriously difficult. If you blindly trust the function name provided by the user, you aren't just serving data; you're serving an execution context. And that is exactly what happened here.

The Flaw: Concatenation Catastrophe

The vulnerability lived in includes/functions-api.php. The logic was deceptively simple: check if the user wants JSONP, grab the callback name, and slap it onto the front of the JSON output.

Here is the logic found in the vulnerable versions:

// The "Before" code
$callback = isset( $output['callback'] ) ? $output['callback'] : '';
 
// ... later in the output logic ...
 
if ( isset( $output['callback'] ) ) {
    // Direct concatenation of user input
    echo $callback . '(' . json_encode( $output ) . ')';
}

Notice the lack of validation? The code assumes $callback is a benign string like renderData. It doesn't check if it contains parentheses, semicolons, or the collected works of Shakespeare written in JavaScript.

This is a textbook reflection sink. The application takes input from the URL ($_REQUEST), processes it zero percent, and echoes it back with a Content-Type that browsers love to execute.

The Exploit: Bypassing the Nothing

Exploiting this is trivial because there were no filters to bypass. An attacker simply needs to construct a URL that closes the function call syntax and starts a new statement.

In a standard JSONP request, the URL looks like this: http://yourls-site.com/yourls-api.php?action=stats&format=jsonp&callback=myFunc

The server responds with: myFunc({"statusCode":200,...})

However, if we change the callback to a payload: http://yourls-site.com/yourls-api.php?action=stats&format=jsonp&callback=alert(document.cookie);//

The server naively responds with: alert(document.cookie);//({"statusCode":200,...})

When a victim (specifically an admin) visits this link, the browser executes alert(document.cookie). The trailing // comments out the rest of the legitimate JSON, preventing syntax errors. In a real-world scenario, an attacker wouldn't just pop an alert box; they would fetch document.cookie and send it to a C2 server, stealing the admin session.

The Fix: Whitelisting Sanity

The patch, applied in commit b1c6100e0aa6fef58c9c1a394ccc19352c3a480a, introduces the only robust defense against this bug class: Strict Whitelisting.

You cannot sanitize XSS with a blacklist (bad guys always find a new character). You must define exactly what is allowed. The YOURLS team added a new function yourls_validate_jsonp_callback().

function yourls_validate_jsonp_callback( $callback ) {
    // Only allow alphanumeric, underscores, dollars, and dots
    if ( preg_match( '/[^a-zA-Z0-9_$.]/', $callback ) ) {
        return false;
    }
    // ... checks for unicode escapes ...
    return true;
}

This Regex /[^a-zA-Z0-9_$.]/ ensures that no parentheses (), semicolons ;, or spaces can pass through. If you can't open a parenthesis, you can't call a function (mostly). They also explicitly block Unicode escapes (like \u0028 for (), closing the door on obscure encoding bypasses.

The Impact: Why It Matters

Why is XSS in a URL shortener dangerous? It's just redirecting links, right?

Wrong. If an attacker compromises a YOURLS instance, they control the traffic flow. They can:

  1. Modify existing shortlinks: Point your company's "Quarterly Report" link to a malware download.
  2. Traffic Analysis: See exactly who is clicking what, when, and from where.
  3. Phishing: Create credible-looking shortlinks on your trusted domain that lead to credential harvesting sites.

If the YOURLS instance is set to Private (YOURLS_PRIVATE = true), the impact is slightly mitigated because the attacker needs to target an authenticated admin. However, these are often the most valuable targets. If the instance is Public, any user can trigger this reflection, potentially turning the shortener into a launchpad for attacks against the general public.

Official Patches

YOURLSYOURLS 1.10.3 Release Notes

Fix Analysis (1)

Technical Appendix

CVSS Score
8.2/ 10
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:L/A:N
EPSS Probability
0.10%
Top 100% most exploited
15,000
Estimated exposed hosts via Shodan

Affected Systems

YOURLS < 1.10.3

Affected Versions Detail

ProductAffected VersionsFixed Version
YOURLS
YOURLS
< 1.10.31.10.3
AttributeDetail
CWE IDCWE-79
Attack VectorNetwork (API)
CVSS v38.2 (High)
ImpactSession Hijacking, Redirection Manipulation
Fix Commitb1c6100
Exploit StatusPoC Available

MITRE ATT&CK Mapping

MITRE ATT&CK Mapping

T1189Drive-by Compromise
Initial Access
T1059.007Command and Scripting Interpreter: JavaScript
Execution
T1552.001Credentials from Password Stores: Web Cookies
Credential Access
CWE-79
Cross-site Scripting (XSS)

Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')

Exploit Resources

Known Exploits & Detection

GitHub Security AdvisoryAdvisory containing PoC details

Vulnerability Timeline

Vulnerability Timeline

Vulnerability fixed in commit b1c6100
2024-12-16
Advisory GHSA-6mp4-q625-mxjp published
2025-01-19
YOURLS 1.10.3 released
2025-01-19

References & Sources

  • [1]GHSA-6mp4-q625-mxjp Advisory
  • [2]Huntr.com Report

Subscribe to updates

Get the latest CVE analysis reports delivered to your inbox.

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.