CVE-2014-4172
Description
URL parameter injection in Jasig CAS clients allows remote attackers to inject arbitrary web script or HTML via service or pgtUrl parameters.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
URL parameter injection in Jasig CAS clients allows remote attackers to inject arbitrary web script or HTML via service or pgtUrl parameters.
Vulnerability
Overview
CVE-2014-4172 is a URL parameter injection vulnerability in the back-channel ticket validation step of the CAS protocol in Jasig Java CAS Client before 3.3.2, .NET CAS Client before 1.0.2, and phpCAS before 1.3.3 [1][2]. The flaw occurs because the service parameter in AbstractUrlBasedTicketValidator.java and the pgtUrl parameter in Cas20ServiceTicketValidator.java are not properly URL-encoded before being appended to the validation URL [3][4]. This allows an attacker to inject arbitrary web script or HTML into the validation request.
Exploitation
An attacker can craft a malicious URL containing encoded characters (e.g., %26 for &) in the service or pgtUrl parameters. When the CAS client constructs the back-channel validation URL, the injected parameters are passed to the CAS server without proper encoding, enabling the attacker to manipulate the validation process [2]. The attack requires network access to the CAS client and the ability to obtain a valid service ticket, but no authentication is needed beyond that [2].
Impact
Successful exploitation can lead to two primary attack scenarios: (1) a malicious service that obtains a valid ticket can use it to access another service, violating the CAS protocol's ticket-service binding (illicit proxy); (2) a malicious user can request a ticket for service A and use it to access service B with the privileges of service A, resulting in privilege escalation [2]. These scenarios could lead to unauthorized data disclosure or privilege escalation [2].
Mitigation
The vulnerability is fixed in Jasig Java CAS Client 3.3.2, .NET CAS Client 1.0.2, and phpCAS 1.3.3 [2]. The fix ensures that parameter values are URL-encoded before being placed in the validation URL [3][4]. Users should upgrade to the patched versions immediately. If upgrading is not possible, the CAS Service Management facility can be used to restrict allowed services as a mitigation [2].
AI Insight generated on May 21, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
DotNetCasClientNuGet | < 1.0.2 | 1.0.2 |
org.jasig.cas:cas-clientMaven | < 3.3.2 | 3.3.2 |
jasig/phpcasPackagist | < 1.3.3 | 1.3.3 |
Affected products
4- Jasig/Java CAS Client, .NET CAS Client, and phpCASdescription
- ghsa-coords3 versions
< 1.3.3+ 2 more
- (no CPE)range: < 1.3.3
- (no CPE)range: < 3.3.2
- (no CPE)range: < 1.0.2
Patches
3266eba7c2d87Merge pull request #73 from battags/CASC-228
3 files changed · +16 −5
cas-client-core/src/main/java/org/jasig/cas/client/validation/AbstractUrlBasedTicketValidator.java+3 −2 modified@@ -110,7 +110,7 @@ protected final String constructValidationUrl(final String ticket, final String logger.debug("Placing URL parameters in map."); urlParameters.put("ticket", ticket); - urlParameters.put("service", encodeUrl(serviceUrl)); + urlParameters.put("service", serviceUrl); if (this.renew) { urlParameters.put("renew", "true"); @@ -144,7 +144,8 @@ protected final String constructValidationUrl(final String ticket, final String buffer.append(i++ == 0 ? "?" : "&"); buffer.append(key); buffer.append("="); - buffer.append(value); + final String encodedValue = encodeUrl(value); + buffer.append(encodedValue); } }
cas-client-core/src/main/java/org/jasig/cas/client/validation/Cas20ServiceTicketValidator.java+1 −1 modified@@ -70,7 +70,7 @@ public Cas20ServiceTicketValidator(final String casServerUrlPrefix) { * @param urlParameters the Map containing the existing parameters to send to the server. */ protected final void populateUrlAttributeMap(final Map<String, String> urlParameters) { - urlParameters.put("pgtUrl", encodeUrl(this.proxyCallbackUrl)); + urlParameters.put("pgtUrl", this.proxyCallbackUrl); } protected String getUrlSuffix() {
cas-client-core/src/test/java/org/jasig/cas/client/validation/Cas10TicketValidatorTests.java+12 −2 modified@@ -18,8 +18,7 @@ */ package org.jasig.cas.client.validation; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.fail; +import static org.junit.Assert.*; import java.io.UnsupportedEncodingException; import org.jasig.cas.client.PublicTestHttpServer; import org.junit.Before; @@ -80,4 +79,15 @@ public void testBadResponse() throws UnsupportedEncodingException { // expected } } + + @Test + public void urlEncodedValues() { + final String ticket = "ST-1-owKEOtYJjg77iHcCQpkl-cas01.example.org%26%73%65%72%76%69%63%65%3d%68%74%74%70%25%33%41%25%32%46%25%32%46%31%32%37%2e%30%2e%30%2e%31%25%32%46%62%6f%72%69%6e%67%25%32%46%23"; + final String service = "foobar"; + final String url = this.ticketValidator.constructValidationUrl(ticket, service); + + final String encodedValue = this.ticketValidator.encodeUrl(ticket); + assertTrue(url.contains(encodedValue)); + assertFalse(url.contains(ticket)); + } }
ae37092100c8CASC-228 URL Encode Paramaters Passed to Server via Validate
3 files changed · +16 −5
cas-client-core/src/main/java/org/jasig/cas/client/validation/AbstractUrlBasedTicketValidator.java+3 −2 modified@@ -110,7 +110,7 @@ protected final String constructValidationUrl(final String ticket, final String logger.debug("Placing URL parameters in map."); urlParameters.put("ticket", ticket); - urlParameters.put("service", encodeUrl(serviceUrl)); + urlParameters.put("service", serviceUrl); if (this.renew) { urlParameters.put("renew", "true"); @@ -144,7 +144,8 @@ protected final String constructValidationUrl(final String ticket, final String buffer.append(i++ == 0 ? "?" : "&"); buffer.append(key); buffer.append("="); - buffer.append(value); + final String encodedValue = encodeUrl(value); + buffer.append(encodedValue); } }
cas-client-core/src/main/java/org/jasig/cas/client/validation/Cas20ServiceTicketValidator.java+1 −1 modified@@ -70,7 +70,7 @@ public Cas20ServiceTicketValidator(final String casServerUrlPrefix) { * @param urlParameters the Map containing the existing parameters to send to the server. */ protected final void populateUrlAttributeMap(final Map<String, String> urlParameters) { - urlParameters.put("pgtUrl", encodeUrl(this.proxyCallbackUrl)); + urlParameters.put("pgtUrl", this.proxyCallbackUrl); } protected String getUrlSuffix() {
cas-client-core/src/test/java/org/jasig/cas/client/validation/Cas10TicketValidatorTests.java+12 −2 modified@@ -18,8 +18,7 @@ */ package org.jasig.cas.client.validation; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.fail; +import static org.junit.Assert.*; import java.io.UnsupportedEncodingException; import org.jasig.cas.client.PublicTestHttpServer; import org.junit.Before; @@ -80,4 +79,15 @@ public void testBadResponse() throws UnsupportedEncodingException { // expected } } + + @Test + public void urlEncodedValues() { + final String ticket = "ST-1-owKEOtYJjg77iHcCQpkl-cas01.example.org%26%73%65%72%76%69%63%65%3d%68%74%74%70%25%33%41%25%32%46%25%32%46%31%32%37%2e%30%2e%30%2e%31%25%32%46%62%6f%72%69%6e%67%25%32%46%23"; + final String service = "foobar"; + final String url = this.ticketValidator.constructValidationUrl(ticket, service); + + final String encodedValue = this.ticketValidator.encodeUrl(ticket); + assertTrue(url.contains(encodedValue)); + assertFalse(url.contains(ticket)); + } }
f0e030014fb7NETC-60 URL encode ticket parameter value.
1 file changed · +1 −1
DotNetCasClient/Utils/UrlUtil.cs+1 −1 modified@@ -139,7 +139,7 @@ public static string ConstructValidateUrl(string serviceTicket, bool gateway, bo EnhancedUriBuilder ub = new EnhancedUriBuilder(EnhancedUriBuilder.Combine(CasAuthentication.CasServerUrlPrefix, CasAuthentication.TicketValidator.UrlSuffix)); ub.QueryItems.Add(CasAuthentication.TicketValidator.ServiceParameterName, HttpUtility.UrlEncode(ConstructServiceUrl(gateway))); - ub.QueryItems.Add(CasAuthentication.TicketValidator.ArtifactParameterName, serviceTicket); + ub.QueryItems.Add(CasAuthentication.TicketValidator.ArtifactParameterName, HttpUtility.UrlEncode(serviceTicket)); if (renew) {
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
15- github.com/advisories/GHSA-9fc5-q25c-r2wrghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2014-4172ghsaADVISORY
- lists.fedoraproject.org/pipermail/package-announce/2014-August/137182.htmlghsax_refsource_MISCWEB
- bugs.debian.org/cgi-bin/bugreport.cgighsax_refsource_MISCWEB
- bugzilla.redhat.com/show_bug.cgighsax_refsource_MISCWEB
- exchange.xforce.ibmcloud.com/vulnerabilities/95673ghsax_refsource_MISCWEB
- github.com/Jasig/dotnet-cas-client/commit/f0e030014fb7a39e5f38469f43199dc590fd0e8dghsax_refsource_MISCWEB
- github.com/Jasig/java-cas-client/commit/ae37092100c8eaec610dab6d83e5e05a8ee58814ghsax_refsource_MISCWEB
- github.com/Jasig/phpCAS/blob/master/docs/ChangeLogghsax_refsource_MISCWEB
- github.com/Jasig/phpCAS/pull/125ghsax_refsource_MISCWEB
- github.com/apereo/java-cas-client/commit/266eba7c2d870d70caba6f41576d19f2fcc869b1ghsaWEB
- issues.jasig.org/browse/CASC-228ghsax_refsource_MISCWEB
- www.debian.org/security/2014/dsa-3017.en.htmlghsax_refsource_MISCWEB
- www.mail-archive.com/cas-user%40lists.jasig.org/msg17338.htmlmitrex_refsource_MISC
- www.mail-archive.com/cas-user@lists.jasig.org/msg17338.htmlghsaWEB
News mentions
0No linked articles in our index yet.