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.
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