Skip to content

Java: add query to detect web.xml auth bypass through verb tampering#3944

Closed
ghost wants to merge 2 commits intomainfrom
unknown repository
Closed

Java: add query to detect web.xml auth bypass through verb tampering#3944
ghost wants to merge 2 commits intomainfrom
unknown repository

Conversation

@ghost
Copy link

@ghost ghost commented Jul 12, 2020

This query detects the case where an auth-constraint is present for a particular HTTP verb but does not include some other verb.

The most common example for this case is CVE-2018-1306, the Apache Pluto 3.0.0 RCE.

Consider the config as shown below

  <security-constraint>
    <web-resource-collection>
      <web-resource-name>portal</web-resource-name>
      <url-pattern>/portal</url-pattern>
      <url-pattern>/portal/*</url-pattern>
      <http-method>GET</http-method>
      <http-method>POST</http-method>
      <http-method>PUT</http-method>
    </web-resource-collection>
    <auth-constraint>
      <role-name>pluto</role-name>
    </auth-constraint>
  </security-constraint>

In this case, the auth-constraint check for GET,POST and PUT methods but not for the HEAD method. Essentially resulting in a full authentication bypass and eventually RCE.

@ghost ghost self-requested a review as a code owner July 12, 2020 18:18
@ghost
Copy link
Author

ghost commented Jul 12, 2020

The output of this query against Apache Pluto 3.0.0 can be found at this link. Please note the query runs against my fork of Pluto as I couldn't get LGTM to run this against version 3.0.0 isntead of the current master.

Copy link
Contributor

@Marcono1234 Marcono1234 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might be good to call them "HTTP method" instead of "verb" since that naming seems to be more common and is also the one used by https://tools.ietf.org/html/rfc1945.

It would probably also be good to rename plutoRce.ql (and the other files) because it appears the query files usually have the name of the vulnerability they detect and not the name of a previously vulnerable application.

import semmle.code.xml.WebXML

class ValidHTTPMethods extends string {
ValidHTTPMethods() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this cover PATCH as well?
If so, maybe this class could possibly be renamed to HTTPMethod instead (though it might not matter).

Copy link
Author

@ghost ghost Jul 12, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is named ValidHttpMethods as the other getHttpMethods calls returns the values preset in the databse. This returns hardcoded predefined strings. HttpMethod is quite similar to the getHttpMethods call. Hence, to prevent confusion, I named it as such.

I am including PATCH in the list. I may have missed that earlier. Thanks for pointing it out.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interestingly, PATCHis not a default method, it is considered as an extension to the actual standard and is part of a eparate RFC. I have incldued it nevertheless. But I am concerned with the number of false positives this may cause.

@@ -0,0 +1 @@
public class Test{} No newline at end of file
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this file included on purpose?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, XML extractor can only be called from a parent language extractor. In this case, seeing the Test.java file, the java extractor is invoked which in turn recognizes xml and includes it in the db. Without it, there won't be any xml included in the generated db.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ghost
Copy link
Author

ghost commented Jul 12, 2020

@Marcono1234

I have squashed the commits and included some suggestions from the review.

RE: "verb" vs "methods": I can see that the standard calls it a method but the attack is called "HTTP Verb tampering". Hence, to avoid confusion, I have simply included a minor change to the initial line. So that it is now HTTP verbs(or methods)

@aibaars aibaars added the Java label Jul 13, 2020
<qhelp>

<overview>
<p>An authentication check on a few HTTP verbs(or methods) and not others may allow an attacker to bypass the authentication by tampering the HTTP verb.</p>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
<p>An authentication check on a few HTTP verbs(or methods) and not others may allow an attacker to bypass the authentication by tampering the HTTP verb.</p>
<p>An authentication check on a few HTTP verbs (or methods) and not others may allow an attacker to bypass the authentication by tampering the HTTP verb.</p>

</example>
<example>
<p>This can be corrected easily by including other HTTP methods in the list.</p>
<sample src="plutoRceGood.xml" />
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
<sample src="plutoRceGood.xml" />
<sample src="verbTamperingGood.xml" />


<example>
<p>Consider the example below, the constraint applies to HTTP `GET`, `POST` and `PUT` methods but not for `HEAD` method. This results in an authentication bypass.</p>
<sample src="plutoRceBad.xml" />
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
<sample src="plutoRceBad.xml" />
<sample src="verbTamperingBad.xml" />

/** Gets the security constraint to which this belongs */
SecurityConstraint getDeclaringConstraint() { result = getParent() }

/** Returns all HTTP methods listed in this collection */
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/** Returns all HTTP methods listed in this collection */
/** Returns a HTTP method listed in this collection */

@luchua-bc
Copy link
Contributor

luchua-bc commented Jul 20, 2020

This is an interesting area. As not all Servlet implementations take all HTTP verbs, for example, a lot of servlets only take the GET and/or POST verb while denying the rest. E.g.

   public void doPost(HttpServletRequest request, HttpServletResponse response) {
        throw new HTTPException(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
    }

    public void doDelete(HttpServletRequest request, HttpServletResponse response) {
        throw new HTTPException(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
    }

    public void doPut(HttpServletRequest req, HttpServletResponse res) {
        throw new HTTPException(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
    }

    public void doInfo(HttpServletRequest req, HttpServletResponse res) {
        throw new HTTPException(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
    }

    public void doHead(HttpServletRequest request, HttpServletResponse response) {
        throw new HTTPException(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
    }

    public void doOptions(HttpServletRequest req, HttpServletResponse res) {
        throw new HTTPException(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
    }

To reduce false positives, will it be a good idea to at least amend the query to check that the Java code does handle additional verbs? Thanks.

@Marcono1234
Copy link
Contributor

To add to @luchua-bc's comment by default you have to override the HttpServlet methods to make your application support them (except doGet which when overridden then also supports doHead unless that is overridden as well).

@adityasharad adityasharad changed the base branch from master to main August 14, 2020 18:33
@smowton
Copy link
Contributor

smowton commented Oct 20, 2020

@porcupineyhairs as per comments above, I'd expect a very high false-positive rate from this because many of the methods are very uncommon (e.g. DELETE, PATCH, CONNECT are commonly left in their default reject-bad-method state).

In order from least to most false positives (and true positives of course), you could go for:

  • GET is checked, but HEAD is not
  • Any method is checked but [GET, HEAD] is not (FP if only POST/PUT requests require auth? Might apply to some APIs with public read-only / authenticated read-write access)
  • Any method is checked but [GET, HEAD, POST] is not
  • Any method is checked but [GET, HEAD, POST, PUT] is not

The later ones could be improved by looking for a doPost or other web frameworks' equivalent handlers for evidence that POST or PUT aren't just rejected.

Let me know which way you want to go and I'll start an evaluation.

@smowton smowton self-assigned this Oct 20, 2020
@smowton
Copy link
Contributor

smowton commented Oct 20, 2020

Also am I right thinking there's no bounty application associated with this query at present?

@ghost
Copy link
Author

ghost commented Nov 9, 2020

@smowton Your ideas woud reduce the FP's. but I am still concerned with the number of results. Hence, I am keeping this one on hold for a while. Please give me some time to see what can be done to reduce the FP's here.

Also, this was meant to be a bug bounty submission but now that I am keeping it on hold, I am not opening a new issue.

@ghost ghost marked this pull request as draft November 12, 2020 19:13
@ghsecuritylab ghsecuritylab marked this pull request as ready for review July 1, 2024 11:22
@ghost ghost closed this Oct 20, 2024
@ghost ghost deleted the ApachePlutoRCE branch October 20, 2024 21:59
This pull request was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants