Summary

Jenkins decides whether a redirect target is safe with isSafeToRedirectTo, which rejects protocol-relative URLs that begin with //. That check runs against the raw value and does not first remove tab or newline characters. A value such as /\t/\t/example.com slips past it, and the browser then strips the tabs while parsing the redirect response and resolves the result as a hostname. The login flow accepts this value, so a crafted link bounces the user to an external site. NVD scores it 4.7 (Medium), vector CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:N/I:L/A:N.

Details

The redirect allow-check lives in hudson/Util.java:

1
2
3
public static boolean isSafeToRedirectTo(@NonNull String uri) {
    return !isAbsoluteUri(uri) && !uri.startsWith("\\") && !uri.replace('\\', '/').startsWith("//");
}

The // test compares the literal string, so it never sees a // that has a tab wedged between the slashes. A value like /%09/%09/example.com (where %09 is a tab) is judged safe.

The gap is a parsing differential. Browsers and the WHATWG URL standard strip the tab and newline bytes (\x09, \x0a, \x0d) out of a URL during parsing, so /\t/\t/example.com collapses to ///example.com. When that value arrives in a 3xx response with a base URL set, the browser reads example.com as the host rather than as a path. Jenkins validated the pre-parse string while the browser acts on the post-parse one.

Source: Util.java#L1653

Proof of Concept

Tested against the official Jenkins Docker image (sha256:01c992ffef29dcf41c7164e8c16285c657c2368c4943dda8d68c93fdf54447d5) set up with the recommended plugins, with the web UI on port 3000. Reproduces deterministically.

A login link carrying the encoded payload redirects off-site:

1
http://localhost:3000/login?next=/%09/%09/example.com

The browser’s own parser shows why the host is honored:

1
2
new URL("/\t/\t/evil.com", "https://jenkins.io")
// => https://evil.com/

Impact

An attacker who controls the redirect parameter in a login or registration link can land the victim on an arbitrary host after they authenticate. The usual payoff is phishing: a convincing Jenkins-branded link that ends on a lookalike page set up to capture credentials or hand over a malicious download.

Remediation

Upgrade to Jenkins weekly 2.568 or LTS 2.555.3, which ignore tab and newline characters when checking for the leading //.

For redirect validation in general, normalize the value the same way the browser will before deciding it is safe, and constrain the accepted input to a tight character set rather than blocking known-bad prefixes.

Disclosure Timeline

  • 2026-05-14: Reported to the Jenkins security team.
  • 2026-06-10: Fix released and advisory published as CVE-2026-53437.

References