CVE-2026-63135
YOURLS: Stored XSS in referrer statistics chart via crafted Referer header
YOURLS is a self-hosted, customizable URL shortener written in PHP. From 1.5.1 until 1.10.4, YOURLS stores the HTTP Referer header through yourls_get_referrer(), yourls_sanitize_url_safe(), and yourls_log_redirect(), then aggregates the value in yourls-infos.php and passes the derived domain through yourls_get_domain(), yourls_stats_pie(), and yourls_google_array_to_data_table(). The chart builder concatenates labels into inline JavaScript without JavaScript-string escaping, so an unauthenticated attacker can poison the statistics of an existing short URL with a crafted referrer. When an administrator or public stats-page viewer opens the affected statistics page, attacker-controlled JavaScript executes in the YOURLS origin and can access admin-visible data, the API signature token, and privileged same-origin actions. This issue is fixed in version 1.10.4.
Attack profile
How easy it is to exploit
- Attack vector
- Network
- Complexity
- Low
- Privileges needed
- None
- User interaction
- Required
What an attacker can affect
- Confidentiality
- Low
- Integrity
- High
- Availability
- None
Exploit likelihood
What each source reports
CVE List Score used
8.2
YOURLS: Stored XSS in referrer statistics chart via crafted Referer header
YOURLS is a self-hosted, customizable URL shortener written in PHP. From 1.5.1 until 1.10.4, YOURLS stores the HTTP Referer header through yourls_get_referrer(), yourls_sanitize_url_safe(), and yourls_log_redirect(), then aggregates the value in yourls-infos.php and passes the derived domain through yourls_get_domain(), yourls_stats_pie(), and yourls_google_array_to_data_table(). The chart builder concatenates labels into inline JavaScript without JavaScript-string escaping, so an unauthenticated attacker can poison the statistics of an existing short URL with a crafted referrer. When an administrator or public stats-page viewer opens the affected statistics page, attacker-controlled JavaScript executes in the YOURLS origin and can access admin-visible data, the API signature token, and privileged same-origin actions. This issue is fixed in version 1.10.4.
- Record
CVE-2026-63135- CVSS 3.1
- 8.2 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:H/A:N - Weakness
- CWE-79
- Updated
- 2026-11-02
EUVDEUVD-2026-64149
8.2
YOURLS is a self-hosted, customizable URL shortener written in PHP. From 1.5.1 until 1.10.4, YOURLS stores the HTTP Referer header through yourls_get_referrer(), yourls_sanitize_url_safe(), and yourls_log_redirect(), then aggregates the value in yourls-infos.php and passes the derived domain through yourls_get_domain(), yourls_stats_pie(), and yourls_google_array_to_data_table(). The chart builder concatenates labels into inline JavaScript without JavaScript-string escaping, so an unauthenticated attacker can poison the statistics of an existing short URL with a crafted referrer. When an administrator or public stats-page viewer opens the affected statistics page, attacker-controlled JavaScript executes in the YOURLS origin and can access admin-visible data, the API signature token, and privileged same-origin actions. This issue is fixed in version 1.10.4.
- Record
EUVD-2026-64149- CVSS 3.1
- 8.2 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:H/A:N - Updated
- 2026-11-02
GitHub AdvisoriesGHSA-5h77-88j3-r659
8.2
YOURLS has stored XSS in referrer statistics chart via crafted Referer header
Summary
YOURLS stores the HTTP Referer header for short URL redirects and later renders aggregated referrer domains in the per-link statistics page. An unauthenticated attacker can send a crafted Referer header to any existing short URL. When an authenticated administrator or stats-page viewer opens that short URL's statistics page, the crafted referrer is embedded into Google Charts JavaScript without JavaScript-string escaping, causing stored cross-site scripting.
This is reachable in default private installations when authenticated users view stats, and in documented configurations where YOURLS_PRIVATE_INFOS is set to false to make statistics pages public.
Details
The vulnerable source-to-sink path is:
HTTP Referer header
-> yourls_get_referrer()
-> yourls_sanitize_url_safe()
-> yourls_log_redirect()
-> log table referrer column
-> yourls-infos.php referrer aggregation
-> yourls_get_domain()
-> yourls_stats_pie()
-> yourls_google_array_to_data_table()
-> inline JavaScript
Relevant code:
includes/functions.php:240-243:yourls_get_referrer()reads$_SERVER['HTTP_REFERER'], callsyourls_sanitize_url_safe(), and truncates the result to 200 bytes.includes/functions.php:294-307:yourls_redirect_shorturl()callsyourls_log_redirect()before redirecting the visitor.includes/functions.php:516-545:yourls_log_redirect()stores the sanitized referrer in the log table.yourls-infos.php:60-82: the statistics page reads logged referrers and groups them byyourls_get_domain($row->referrer).yourls-infos.php:493-498: the statistics page passes referrer domains toyourls_stats_pie().includes/functions-infos.php:338-355:yourls_google_array_to_data_table()manually concatenates labels into JavaScript as['$label', ...]without escaping single quotes, backslashes, or other JavaScript string metacharacters.includes/functions-formatting.php:141-143andincludes/functions-formatting.php:555-609:yourls_sanitize_url_safe()removes some unsafe characters and CRLF sequences, but still permits the characters needed for JavaScript-string breakout, including',[,],,, and parentheses.
A crafted referrer host such as:
x',1],['marker',alert(1)],['z.tld
survives sanitization when used in a URL like:
http://x',1],['marker',alert(1)],['z.tld/path
It is then rendered into chart JavaScript like:
var data = google.visualization.arrayToDataTable([
['x',1],['marker',alert(1)],['z.tld',1]
]);
The alert(1) call is only a benign proof marker. An attacker could execute arbitrary JavaScript in the stats viewer's browser context.
PoC
The following local harness was run against commit c3fc8e2370d240403c17c2e4a70e1e234759a5b3. It exercises YOURLS' real URL sanitizer, domain extraction, and yourls_stats_pie() chart rendering path, then executes the generated chart script in Node with stubs for Google Charts and alert().
docker run --rm --network none -v "$PWD:/repo:ro" -w /repo phpmyadmin:5.2.1 php -d display_startup_errors=0 -r '
define("IDNA_DEFAULT",0);
define("INTL_IDNA_VARIANT_UTS46",1);
function yourls_add_action(){ }
function yourls_do_action(){ }
function yourls_apply_filter($tag,$value){ return $value; }
function yourls_get_protocol($url){ preg_match("!^[a-zA-Z][a-zA-Z0-9+.-]+:(//)?!", $url, $m); return isset($m[0]) ? $m[0] : ""; }
function yourls_is_allowed_protocol($url,$protocols=[]){ if(!$protocols){ global $yourls_allowedprotocols; $protocols=$yourls_allowedprotocols; } return in_array(yourls_get_protocol($url), $protocols); }
if(!function_exists("idn_to_utf8")){ function idn_to_utf8($domain,$flags=0,$variant=0){ return $domain; } }
require "includes/vendor/autoload.php";
require "includes/functions-kses.php";
yourls_kses_init();
require "includes/functions-formatting.php";
require "includes/functions-infos.php";…
- Record
GHSA-5h77-88j3-r659- CVSS 3.1
- 8.2 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:H/A:N - Weakness
- CWE-79
- Updated
- 2026-11-02
NVD
8.2
YOURLS is a self-hosted, customizable URL shortener written in PHP. From 1.5.1 until 1.10.4, YOURLS stores the HTTP Referer header through yourls_get_referrer(), yourls_sanitize_url_safe(), and yourls_log_redirect(), then aggregates the value in yourls-infos.php and passes the derived domain through yourls_get_domain(), yourls_stats_pie(), and yourls_google_array_to_data_table(). The chart builder concatenates labels into inline JavaScript without JavaScript-string escaping, so an unauthenticated attacker can poison the statistics of an existing short URL with a crafted referrer. When an administrator or public stats-page viewer opens the affected statistics page, attacker-controlled JavaScript executes in the YOURLS origin and can access admin-visible data, the API signature token, and privileged same-origin actions. This issue is fixed in version 1.10.4.
- Record
CVE-2026-63135- CVSS 3.1
- 8.2 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:H/A:N - Weakness
- CWE-79
- Updated
- 2026-11-02
OSV
8.2
YOURLS: Stored XSS in referrer statistics chart via crafted Referer header
YOURLS is a self-hosted, customizable URL shortener written in PHP. From 1.5.1 until 1.10.4, YOURLS stores the HTTP Referer header through yourls_get_referrer(), yourls_sanitize_url_safe(), and yourls_log_redirect(), then aggregates the value in yourls-infos.php and passes the derived domain through yourls_get_domain(), yourls_stats_pie(), and yourls_google_array_to_data_table(). The chart builder concatenates labels into inline JavaScript without JavaScript-string escaping, so an unauthenticated attacker can poison the statistics of an existing short URL with a crafted referrer. When an administrator or public stats-page viewer opens the affected statistics page, attacker-controlled JavaScript executes in the YOURLS origin and can access admin-visible data, the API signature token, and privileged same-origin actions. This issue is fixed in version 1.10.4.
- Record
CVE-2026-63135- CVSS 3.1
- 8.2 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:H/A:N - Weakness
- CWE-79
- Updated
- 2026-11-02
OSVGHSA-5h77-88j3-r659
8.2
YOURLS has stored XSS in referrer statistics chart via crafted Referer header
Summary
YOURLS stores the HTTP Referer header for short URL redirects and later renders aggregated referrer domains in the per-link statistics page. An unauthenticated attacker can send a crafted Referer header to any existing short URL. When an authenticated administrator or stats-page viewer opens that short URL's statistics page, the crafted referrer is embedded into Google Charts JavaScript without JavaScript-string escaping, causing stored cross-site scripting.
This is reachable in default private installations when authenticated users view stats, and in documented configurations where YOURLS_PRIVATE_INFOS is set to false to make statistics pages public.
Details
The vulnerable source-to-sink path is:
HTTP Referer header
-> yourls_get_referrer()
-> yourls_sanitize_url_safe()
-> yourls_log_redirect()
-> log table referrer column
-> yourls-infos.php referrer aggregation
-> yourls_get_domain()
-> yourls_stats_pie()
-> yourls_google_array_to_data_table()
-> inline JavaScript
Relevant code:
includes/functions.php:240-243:yourls_get_referrer()reads$_SERVER['HTTP_REFERER'], callsyourls_sanitize_url_safe(), and truncates the result to 200 bytes.includes/functions.php:294-307:yourls_redirect_shorturl()callsyourls_log_redirect()before redirecting the visitor.includes/functions.php:516-545:yourls_log_redirect()stores the sanitized referrer in the log table.yourls-infos.php:60-82: the statistics page reads logged referrers and groups them byyourls_get_domain($row->referrer).yourls-infos.php:493-498: the statistics page passes referrer domains toyourls_stats_pie().includes/functions-infos.php:338-355:yourls_google_array_to_data_table()manually concatenates labels into JavaScript as['$label', ...]without escaping single quotes, backslashes, or other JavaScript string metacharacters.includes/functions-formatting.php:141-143andincludes/functions-formatting.php:555-609:yourls_sanitize_url_safe()removes some unsafe characters and CRLF sequences, but still permits the characters needed for JavaScript-string breakout, including',[,],,, and parentheses.
A crafted referrer host such as:
x',1],['marker',alert(1)],['z.tld
survives sanitization when used in a URL like:
http://x',1],['marker',alert(1)],['z.tld/path
It is then rendered into chart JavaScript like:
var data = google.visualization.arrayToDataTable([
['x',1],['marker',alert(1)],['z.tld',1]
]);
The alert(1) call is only a benign proof marker. An attacker could execute arbitrary JavaScript in the stats viewer's browser context.
PoC
The following local harness was run against commit c3fc8e2370d240403c17c2e4a70e1e234759a5b3. It exercises YOURLS' real URL sanitizer, domain extraction, and yourls_stats_pie() chart rendering path, then executes the generated chart script in Node with stubs for Google Charts and alert().
docker run --rm --network none -v "$PWD:/repo:ro" -w /repo phpmyadmin:5.2.1 php -d display_startup_errors=0 -r '
define("IDNA_DEFAULT",0);
define("INTL_IDNA_VARIANT_UTS46",1);
function yourls_add_action(){ }
function yourls_do_action(){ }
function yourls_apply_filter($tag,$value){ return $value; }
function yourls_get_protocol($url){ preg_match("!^[a-zA-Z][a-zA-Z0-9+.-]+:(//)?!", $url, $m); return isset($m[0]) ? $m[0] : ""; }
function yourls_is_allowed_protocol($url,$protocols=[]){ if(!$protocols){ global $yourls_allowedprotocols; $protocols=$yourls_allowedprotocols; } return in_array(yourls_get_protocol($url), $protocols); }
if(!function_exists("idn_to_utf8")){ function idn_to_utf8($domain,$flags=0,$variant=0){ return $domain; } }
require "includes/vendor/autoload.php";
require "includes/functions-kses.php";
yourls_kses_init();
require "includes/functions-formatting.php";
require "includes/functions-infos.php";…
- Record
GHSA-5h77-88j3-r659- CVSS 3.1
- 8.2 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:H/A:N - Weakness
- CWE-79
- Updated
- 2026-11-02
Affected products
Affected packages
| Package | Affected | Fixed |
|---|---|---|
yourls/yourlsPackagist |
1.5.1 to 1.10.3 | 1.10.4 |
yourls/yourlsPackagist |
1.5.1 up to 1.10.4, plus listed versions 1.10.01.10.11.10.21.10.31.7.1 Show 12 moreShow less1.7.21.7.31.7.41.7.51.7.61.7.91.81.8.11.8.21.91.9.11.9.2 |
1.10.4 |
History
| Recorded | Changed | Sources |
|---|---|---|
| first indexed | CVE List, EUVD, GitHub Advisories, NVD, OSV |
Dates are when Every CVE recorded each change. Upstream dates may differ.
In short
CVE-2026-63135 is a high vulnerability (CVSS 8.2) in Yourls, published August 21, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.43%, the 36th percentile. Fixed in yourls/yourls 1.10.4.
References
github.com/YOURLS/YOURLS/security/advisories/GHSA-5h77-88j3-r659
github.com/YOURLS/YOURLS/pull/4107
github.com/YOURLS/YOURLS/commit/e1e93476655107e6caab34e52259eb1c91079ec7
github.com/YOURLS/YOURLS/releases/tag/1.10.4
github.com/advisories/GHSA-5h77-88j3-r659
github.com/CVEProject/cvelistV5/tree/main/cves/2026/63xxx/CVE-2026-63135.json
nvd.nist.gov/vuln/detail/CVE-2026-63135
github.com/YOURLS/YOURLS
Left out here: the rest of 2 source descriptions. The JSON record has them.