20

TL;DR:

Is there a valid reason to demand a software vendor to stop using HTTP PUT and DELETE methods in a web application and use only GET and POST? The application uses frameworks to whitelist allowed request paths and methods.

In other words, is there any difference from the security standpoint in allowing the deletion of a record via either DELETE or POST methods without changing the code and security checks in it?

Full question

Our customer configured their Tomcat instance with the following, according to their corporate standard:

<security-constraint> 
    <web-resource-collection> 
        <web-resource-name>restricted methods</web-resource-name> 
        <url-pattern>/*</url-pattern> 
        <http-method>CONNECT</http-method> 
        <http-method>PUT</http-method> 
        <http-method>DELETE</http-method> 
        <http-method>OPTIONS</http-method> 
        <http-method>TRACE</http-method> 
    </web-resource-collection> 
    <user-data-constraint> 
        <transport-guarantee>CONFIDENTIAL</transport-guarantee> 
    </user-data-constraint> 
    <auth-constraint /> 
</security-constraint> 

This, among the Http Header Security Filter configuration, made our application break.

Our application provides the same HTTP Header security features in Spring Security. Also, our application is RESTful, so we widely use PUT and DELETE methods for file upload. In future releases, we are also planning to use websockets (but from a search, they don't use CONNECT, which is for proxying).

Our customer said that they will have to raise a policy exception in production in order remove the offending lines from Tomcat configuration and make the application work.

The security exception policy is triggered when vendor applications do not comply with security requirement in a way that 1) fixing the issue cannot be done within the schedules and 2) no evident vulnerability is found. Exception policies require senior management approval.

However, security policy exceptions require our customer to engage the vendor within 6 months in "fixing the security issue". Within 6 months, vendor has to provide costs and deadlines to meet the security policy.

This means that they will return to me asking for a quotation to make the application work with enabled HTTP method filtering and HTTP Header Security filter.

I don't want to do them a favour and change all Ajax calls from RESTful patterns to GET/POST only, not even for money if possible. I would like instead to prove that their security implementation is not only incompatible, but redundant, with regards to the security implementations within the application.

If we set a precedent in doing this customer a favour with PUT and DELETE requests, we will have to face requests like "be compatible with my framework/policy/environment" from a large customer base (all banks and financial institutions). In the future, that may turn against our cost management.

Question is, as in the TLDR, could using PUT and DELETE methods alone, regardless of the security features of the application, pose a security risk?

If proven that the sole HTTP verb does not pose a security risk, I will be able to raise a permanent exception policy and confront the IT staff with solid argumentation.

Edit

I work in a software factory that deploys the same product instance to a large number of customers and our cloud. We are fully using all the tools we have on board, including the REST pattern. We are planning to employ HATEOAS, WebSockets, resumable file downloads, and everything the web technology can offer us to deliver better experience. Yes, sounds like a marketing line. Anyway, security is still a concern in our products.

usr-local-ΕΨΗΕΛΩΝ
  • 5,310
  • 2
  • 17
  • 35
  • 4
    I had some similar circumstances happen with clients. The result until now has been, either they give up and accept the changes required to make the application work, or they pay $$$ for supporting a special branch for them. If they pay enough to outset the cost and make a profit of that situation I don't see why you shouldn't do that. – Bakuriu Dec 14 '18 at 19:39
  • 4
    Me saying this doesn't help with your problem, but your customer is stupid. – user253751 Dec 14 '18 at 23:35

5 Answers5

27

I suspect this is a case of someone zealously applying "best practices" that they don't understand.

HTTP Verb Tampering Attack

The reason this best practice exists is because of the HTTP Verb Tampering Attack. From this article:

Many Web server authentication mechanisms use verb-based authentication and access controls. For example, an administrator can configure a Web server to allow unrestricted access to a Web page using HTTP GET requests, but restrict POSTs to administrators only. However, many implementations of verb-based security mechanisms enforce the security rules in an unsecure manner, allowing access to restricted resources by using alternative HTTP methods (such as HEAD) or even arbitrary character strings.

So someone decided that because some apps are badly-written, all apps should be banned from accepting HTTP verbs other than GET or POST, because ... you know ... mumble mumble SECURITY!!


My opinion (possibly incomplete / incorrect, please post comments) :

  • Pure HTML / CSS / js content should be restricted to GET and POST because these are the only verbs allowed in the HTML spec.
  • APIs (AJAX, REST) should be allowed to use any verb from the HTTP spec, that said:
    • Be aware that even if your application-layer correctly enforces verb-based access controls, your webserver front-end may not, so you owe it to your customers to do some security testing and make sure your app enforces proper authentication and access controls on all verbs that you support. I recommend following the OWASP testing guide.

It sounds like your app is fine and your customer has an overly-zealous security policy.


As an aside, HEAD is an interesting example; some security scanners seem to complain if your app responds to HEAD requests, because some apps will return valid headers without invoking the proper auth checks. However, most properly designed apps will process a full GET and then only return the headers, including the correct content-length:. So for apps using modern frameworks, there is probably no way to bypass auth logic on your GET controller. Do some quick tests though! (Thanks @usr-local-ΕΨΗΕΛΩΝ for pointing this out in comments. See this Stack Overflow post for detail on how Spring MVC handles this.)

Mike Ounsworth
  • 57,707
  • 21
  • 150
  • 207
  • 2
    I just noticed there's a more thorough answer to this question here: https://security.stackexchange.com/q/21413/61443 – Mike Ounsworth Dec 14 '18 at 18:06
  • 1
    I think it's a good idea to allow HEAD when GET and POST are allowed. Lots of clients will see if a path exists by using HEAD. – forest Dec 15 '18 at 02:49
  • @forest Ah, good point! It does put extra onus on the developer to make sure that HEAD returns appropriate results for URLs that should be auth-protected, so it should be "allow HEAD if you know what you're doing" ? – Mike Ounsworth Dec 15 '18 at 02:58
  • Often the only difference between HEAD and GET is that the payload is not sent. – forest Dec 15 '18 at 02:59
  • I'm definitely out of my expertise here, but I can imagine that some implementations don't actually compute the payload for a HEAD request, esp if the payload needs lots of backend queries. Like, the situation I'm imagining is that the front-end responds to a HEAD with the cached headers from the last time that URL was accessed, but I have no idea if that's common, which would be a problem if there's data in those readers which should be auth-protected. – Mike Ounsworth Dec 15 '18 at 03:01
  • 1
    ...what this boils down to is, "protect the resource first, then the action". Especially since so many apps are written to only use GET/POST anyways.... – Clockwork-Muse Dec 15 '18 at 06:40
  • 1
    @MikeOunsworth see https://stackoverflow.com/questions/45074013/why-headmapping-unavailable-in-spring-mvc. Of course if you are writing IHttpHandler/HttpServlet code directly, you **can** decide not to do queries on HEAD method, because that is **your** code – usr-local-ΕΨΗΕΛΩΝ Dec 15 '18 at 12:45
  • @usr-local-ΕΨΗΕΛΩΝ So if I'm understanding correctly the Spring MVC framework responds to HEAD requests by fully computing the GET, and then dropping part of it? – Mike Ounsworth Dec 17 '18 at 13:14
  • 1
    Yes, that is my *understanding* too. I haven't inspected the code, but the comment on the linked answer provides full clarification (HEAD requests must generate the correct content length). I would likely continue the discussion out of this topic. – usr-local-ΕΨΗΕΛΩΝ Dec 17 '18 at 14:17
  • @usr-local-ΕΨΗΕΛΩΝ Very interesting. I've edited that into my answer. Thanks! – Mike Ounsworth Dec 17 '18 at 15:33
  • 1
    Personal comment after edit: I think that a properly designed framework could still allow HEAD processing, but requires **additional** care by the implementor. Consider a permissioned file download. As soon as the implementor uses proper security checks, and depending on implementation, a HEAD of a file download can be implemented by a simple database lookup of file name, size, hash and last modification, without having to physically transfer the file to the response `Stream`. At least I would enjoy of a @HeadMapping annotation. – usr-local-ΕΨΗΕΛΩΝ Dec 17 '18 at 17:07
1

Arguably, DELETE and PUT are safer than GET/POST because they cannot be used in CSRF attacks. Also arguably, DELETE and PUT should be protected against CSRF anyway, because it is bad to base your application's security on the assumption that every browser implementation out there follows the standards. But it's not uncommon for applications to not have that protection, so maybe that's the thinking behind the ban, although I'm reaching here a bit.

Or maybe they just disabled all methods they did not need (which is a good practice) and over time that turned from a default into an unviolable rule.

Tgr
  • 668
  • 3
  • 11
  • If you implement CSRF using a good framework (e.g. Spring Security in my case, but can also be [AntiForgeryTokenAttribute]), that will be applied to all verbs than GET. In my case I happened to configure Angularjs to send the token header also on GET requests. Has no effect but is shorter configuration – usr-local-ΕΨΗΕΛΩΝ Dec 15 '18 at 13:17
  • "Or maybe they just disabled all methods they did not need". That is a very good point, but not applicable to my case. I mean, if you are a software company you can reasonably take such decision. But if you are a bank running your supplier's code, it's not you who decide which methods to use. Thanks for the opinion! – usr-local-ΕΨΗΕΛΩΝ Dec 17 '18 at 14:53
0

I recommend engaging your corporate legal team soon, in order to have someone focusing on the business aspects of the discussions to come.

As part of the security exception policy, our customer's staff is obligated to engage the vendor in "fixing the security issue" within 6 months.

This means that they will return to me asking to make the application work with enabled HTTP method filtering and HTTP Header Security filter.

I don't want to do them a favour and change all Ajax calls from RESTful patterns to GET/POST only, not even for money.

Your client is obviously running their own bureaucracy, enforcing an inflexible policy. You believe you have three possible paths:

  1. Convince them to change their policy.
  2. Make the undesirable change.
  3. Risk losing them as a customer.

Even though it appears to you to be a logical, technical decision, getting policies changed requires a fair amount of political wrangling. The person you are dealing with on the other side of the discussion may or may not have the standing in his company needed to successfully make such a request. He may not want to waste his time fighting his own bureaucracy for the change. His life might be considerably easier if he changes vendors and uses someone else’s product that already complies with their policies. Worse for you, his boss’ life will almost certainly be easier if he just changes vendors.

It would be irresponsible of you to think that you can succeed at getting them to change their policy without doing some serious planning for the other outcomes.

Good customers are hard enough to come by. You owe it to your company to carefully weigh the risk of losing one over this.

John Deters
  • 33,650
  • 3
  • 57
  • 110
  • "It would be irresponsible of you to think that you can succeed at getting them to change their policy without doing some serious planning for the other outcomes." > Personally, I can use the outcome of this discussion to prove the customer that the application is already enforcing what they are expecting and request a permanent policy exception for that. Let me edit – usr-local-ΕΨΗΕΛΩΝ Dec 17 '18 at 16:51
0

The remote API may be designed this way, so any other http methods except GET or POST are not used, for example:

DELETE /item/123

may be:

GET /delete/item/123

Anyway, you will have to read an API spec and figure out how to add or delete items, so it's 50/50 argument that one is better than another. I prefer having only GET and POST.

  • So, I guess you're trying to say security risks can be the same, because same functionality will be implemented with GET and POST? – domen Feb 06 '20 at 08:46
  • @domen Not only security. Browsers are made to be more restrictive to PUT/DELETE methods, so more lines of code will be involved into implementation of PUT/DELETE. More tests should be made. Besides GET/POST, OPTIONS should also be taken into account, if you like to create public accessible API. For example Telegram Bot API doesnt have PUT/DELETE. Check out other services! – Michael Quad Feb 06 '20 at 10:42
  • In context of this question - security aspect answers something, I'm not sure other parts do. – domen Feb 06 '20 at 11:13
0

OWASP recommends to lock down unused routes in the way described in the question.

Restrict HTTP methods

  • Apply a whitelist of permitted HTTP Methods e.g. GET, POST, PUT.
  • Reject all requests not matching the whitelist with HTTP response code 405 Method not allowed.
  • Make sure the caller is authorised to use the incoming HTTP method on the resource collection, action, and record
mentallurg
  • 8,536
  • 4
  • 26
  • 41
GreenAsJade
  • 1,031
  • 1
  • 9
  • 10
  • OWASP does not specify the scope where to whitelist the methods. If you use for example spring MVC, this can be done using `@RequestMapping`. It totally makes sense to not let endpoints respond to *any* verb. But they don't mandate that you block this on a web server level. – Scolytus Apr 01 '21 at 10:03