Vendor: PAC4j
Vendor URL: http://www.pac4j.org/
Versions affected: All versions through 3.0.0 (latest at time of writing)
Author: James Chambers
Advisory URL / CVE Identifier: TBD
Risk: High (an attacker can bypass path-based authentication rules)
Summary
Regular expressions used for path-based authentication by the play-pac4j library are evaluated against the full URI provided in a user’s HTTP request. If a requested URI matches one of these expressions, the associated authentication rule will be applied. These rules are only intended to validate the path and query string section of a URL. If a request URI contains a scheme and authority section, the requested URI will not match these path-based rules, even if the resolved relative path used for routing does. This may allow an attacker to bypass certain path-based authentication rules.
Location
SecurityFilter
path-based authentication rules in the Play application configuration file (e.g. conf/application.conf
).
Impact
An unauthenticated attacker may be able to access restricted paths in a Play web application, such as an administrator interface.
Details
Consider the following authentication configuration:
pac4j.security.rules = [
{"/admin(?.*)?" = {
authorizers = "_authenticated_",
clients = "SAML2Client"
}},
{".*" = {
authorizers = "_anonymous_"
}}
]
A typical HTTP request line has the following form:
GET /admin HTTP/1.1
The resulting request.uri
checked by the play-pac4j library will be /admin
, which will trigger the SAML2 authentication rule.
However, another valid way to specify URLs on the request line is:
GET https://example.com/admin HTTP/1.1
In this case, the request.uri
will be https://example.com/admin
, while request.path
will be /admin
. The authentication rule for /admin(?.*)?
will be bypassed, while the application still routes the user to /admin
.
Another valid way to perform this bypass in the browser is by adding two extra slashes to the path, such as https://example.com///admin
. The request looks like:
GET ///admin HTTP/1.1
This URI is interpreted as having a relative scheme, empty authority, and path of /admin
. The value of request.uri
will be ///admin
, while the value of request.path
is /admin
.
Recommendation
As a temporary mitigation, use a catch-all, high privilege authentication rule to catch all unrecognized paths. This will ensure that any rule bypass does not result in privilege escalation, as the highest level of privilege will be required for access.
Alternatively, replace all SecurityFilter
path-based rules with per-action Secure
annotations.
Vendor Communication
2017-07-28 - NCC Group sends initial email to vendor asking for security contact
2017-07-28 - Vendor responds and provides a security related email address
2017-08-01 - NCC Group asks for a PGP public key to send the advisory encrypted
2017-08-01 - Vendor provides a PGP public key
2017-08-16 - NCC Group sends a draft of the advisory to the vendor
2017-08-17 - Vendor acknowledges receipt of advisory
2017-08-18 - Vendor confirms vulnerability and asks whom to credit
2017-08-31 - NCC Group asks for bug discoverer to be credited
2017-09-01 - Vendor notes that disclosure to Google groups list was made already
and that the name will be added to that disclosure
2017-09-01 - NCC Group thanks the vendor and informs them that public disclosure
will move forward
Thanks to
Jérôme Leleu
Published date: 18 September 2017