24

We have recently developed a web application with a RESTful API backend. This web app need to have a certain security certification (something called PCI-DSS), and thus it is being scanned occasionally to identify potential vulnerabilities that must be fixed in order to be certified. These scans have found a few things that indeed needed to be corrected.

There is, however, one weird reported flaw. We have a few methods in our API which sometimes return nothing, and so these return a HTTP 204 response code. Since there is no content, we do not specify a Content-Type header. The security scan have flagged this absence as a vulnerability, albeit a low one.

This makes no sense to me. As I understand it, if there is no content there is no point in declaring a content type, since the browsers will simply ignore it anyway. There isn't even an appropriate content type for empty content. I searched on the web, and couldn't find what type to use in that case. In fact all I found essentially said that the content type should indeed be left out in that case. So, I don't know what to do to adress this particular issue.

So, why is omitting the Content-Type header with a HTTP 204 response a potential security risk? What are we supposed to do about it?

7
  • Note that <No Content> is not valid data for some content types. For example, the 0-byte file is not valid HTML, XML, nor JSON code. I can see why explicitly declaring a content type might be helpful.
    – Nayuki
    Commented Nov 22, 2023 at 5:23
  • 7
    Re: "There isn't even an appropriate content type for empty content": Pedantic note: there are multiple MIME types that can be appropriate for empty content (Content-Length 0); for example, both text/plain and application/octet-stream allow empty content. But HTTP 204 specifies no content, which makes it a bit icky (though harmless) to specify a Content-Type.
    – ruakh
    Commented Nov 22, 2023 at 8:52
  • 7
    @jcaron for successful POST/PUT/DELETE requests, a 204 response is common enough if there is no need to include any details. Commented Nov 22, 2023 at 21:42
  • 1
    There is a flaw in the scanner, not your code
    – Bakuriu
    Commented Nov 23, 2023 at 7:11
  • 1
    @Nayuki Empty files are not valid JPEG, PNG, ZIP, ... - anything which requires a header, be it binary or text - either. Commented Nov 23, 2023 at 10:59

3 Answers 3

41

Automated scanning tools are fairly crude, and don't tend to take that kind of nuance into account - the scanner is most likely flagging any HTTP response that doesn't have the Content-Type header, regardless of the content.

If you believe that this is a false positive, then you should go back to whoever is performing the scanning, explain why you think it's not an issue, and ask them to justify why it's a security issue in the context of your environment. If this is PCI ASV scanning, then they probably have processes in place for this.

But given that you may end up having this argument with them every three months when they have a scan, it might be worth considering whether it's going to be easier to just set a (technically incorrect) Content-Type header to save yourself some hassle.

10
  • 4
    It may not even be that it’s the automated scan being naive, the original spec may have been written to require this. A status of 204 (as well as 205, 208, and possibly 201 and 202 in some cases) is unusual among HTTP status codes in that it involves no response body if used correctly, and it’s not used very often in my experience, so it would not surprise me if the PCI DSS requirements were written in complete ignorance of this situation being possible in HTTP. I’ve come across similarly ‘obviously ignorant’ cases in both PCI DSS and other security standards before. Commented Nov 22, 2023 at 1:24
  • 21
    PCI DSS itself lays out high-level requirements and does not even approach the level of detail of particular HTTP status codes or headers. This "flaw" report is a particular scanning vendor's interpretation of the requirements, and it's a bad one. Status 204 dates back to the original HTTP/1.0 drafts from 1992, so if this is the result of ignorance, it's pretty bad ignorance, and has little to do with the original spec.
    – josh3736
    Commented Nov 22, 2023 at 4:05
  • 7
    @josh3736 Long may the cargo cults live!
    – mishan
    Commented Nov 22, 2023 at 6:49
  • 19
    "it might be worth considering whether it's going to be easier to just set a Content-Type header to save yourself some hassle." - While that is certainly practical, it makes me sad. If no one pushes back on a bullshit test, the bullshit will never go away :(
    – marcelm
    Commented Nov 22, 2023 at 12:31
  • 11
    @Dantre: It's always worth it to raise this to your own management, if only to raise a question as to the competence of the auditor. Vulnerability scanners being crude, an auditor is expected to manually validate the findings to ensure they are, in fact, vulnerabilities. Similarly if they don't filter out previously debunked findings in the next round. If they don't filter there's a risk that they'll spam many teams with many dubious findings and cost a lot of time... and that's something management should be sensitive to. Commented Nov 22, 2023 at 16:15
12

Automated security scans are notoriously prone to false positives.

In general I agree with the other answer to pick your battles with the security team. If a false finding can be "remediated" quickly and with no issues then just do it and save your energy for when the requested change is difficult or causes technical problems, there will be plenty of these.

That said, you should watch out in case this specific change falls into the second category. For example, Atlassian reports a bug in IBM's Axis library where it will wait forever if there is a content-type header with no content, even with a 204 status.

Atlassian also comes to the conclusion that content-type on a 204 is permitted as per the RFC, but I don't see anything explicitly saying that in the RFC so I can only conclude that it is permitted by default by not being explicitly banned. Given that, I'm not that surprised to hear about inconsistent/buggy implementations since it does seem nonsensical--much like the issues with a body on a GET request before the spec was updated to be clearer. If your API is expected to be used by external teams who may be using such libraries you may want to push back.

At very least, if your API is internal and you can test sufficiently to confirm that there will be no problems, this is a perfect example of where comments are necessary.

/* Adding a content-type despite no content to appease PCI-DSS security scan. */

2
  • Yeah the body on a GET request is a real thing. I considered using it once (where any request with the same path and body would definitely return the same result so browser caching it is fine) before I thought better of it.
    – Joshua
    Commented Nov 22, 2023 at 23:15
  • @Joshua Have wanted it frequently for bulk requests, since the size limit on URLs is a real problem. We have to disable most caching anyway because we're dealing with very time-sensitive data. Commented Nov 24, 2023 at 13:24
4

I want to throw in some alternative view points here.
I do not necessarily support the given requirement , I am only giving a Possible Justification for why it is the way it is.


(1) When the scan is reporting a "Security Vulnerability" , we have to consider for whom it is a vulnerability.
It is not that this missing header will somehow allow hacking into the web server or even hacking into the web client or will somehow reveal Confidential Data.

It is actually the whole "Payment Network" here , and the vulnerability is the Possibility of unintentional false tampering.

(2) Thanks to user "josh3736" for sharing https://docs-prv.pcisecuritystandards.org/PCI%20DSS/Standard/PCI-DSS-v4_0.pdf , where I got some idea about what the Issue is supposed to be.
It is requirement "11.6 Unauthorized changes on payment pages are detected and responded to"

When the web browser ( user wants to make a Payment ) is accessing the web server ( Payment Network wants to authenticate that Payment ) , things will go smooth even when that header for HTTP 204 is rightly missing.

In case there are Server Proxies , Client Web Access Proxies , Payment gateways , ISP filters , or Cloud Servers involved in the network transaction , there are chances that some overly-enthusiastic Proxy ( or Intermediate Element ) will set Default Content-type ( or will insert Content-type when that is missing ) & that might get Detected.
That Detection might ( will ) make the transaction fail even though there is no real Issue here. That false Positive resulting in transaction failure might then result in unnecessary losses to Customer or to Business.

To avoid that , there should be no unknowns & no Defaults : all things should be Explicitly known in the Security Environment.

Thus the requirement that the Content-type Header ( & all other things ) be set makes sense.

The requirement could be modified to state that there should be no such header when it is not necessary , though there is no guarantee that Intermediate Elements will not insert it , to make false Positives.
Better use a header Explicitly & Ensure that it is not getting tampered.

END Of Answer


Interested folks may be curious to check Page 261 & Page 262 of the PCI DSS Document.
It is listed like this :


11.6 Unauthorized changes on payment pages are detected and responded to.
11.6.1 A change- and tamper-detection mechanism
is deployed as follows:
• To alert personnel to unauthorized modification
(including indicators of compromise, changes,
additions, and deletions) to the HTTP headers
and the contents of payment pages as received
by the consumer browser.
• The mechanism is configured to evaluate the
received HTTP header and payment page. 
...
By comparing the current version of the HTTP
header and the active content of payment pages
as received by the consumer browser with prior or
known versions, it is possible to detect
unauthorized changes that may indicate a
skimming attack.
...
The intention of this requirement is not that an entity
installs software in the systems or browsers of its
consumers, but rather that the entity uses
techniques such as those described under
Examples in the Guidance column to prevent and
detect unexpected script activities.
...
Examples
Mechanisms that detect and report on changes to
the headers and content of the payment page
include but are not limited to:
...
Reverse proxies and Content Delivery
Networks can detect changes in scripts and
alert personnel.
Often, these mechanisms are subscription or
cloud-based, but can also be based on custom
and bespoke solutions.


10
  • 1
    Interesting find. It could explain where this is coming from in the first place.
    – Dantre
    Commented Nov 23, 2023 at 15:01
  • hmm, this still wouldn't make the mising header a security issue... it would make it a compliancy issue (and using it is in general a goof idea anyway). Great find anyway,
    – LvB
    Commented Nov 23, 2023 at 15:53
  • 2
    I don't think this makes sense - this posits the existance of a specific type of broken proxy (are any known to exist?). The same way one could posit the existance of proxies that tamper with data when the content-type header exists on a 204 response. There is no way to predict how a hypothetical broken proxy will behave. This would only make sense if this was a known bug in proxies that are used in reality, and only if no other proxies exist that malfunction in other ways. Commented Nov 23, 2023 at 23:03
  • In Security Environments , "Possibility" is enough & "Existence" is not necessary , @RememberMonica , & there are lots of Proxies [ & Web Pipelines ] where Headers get inserted. This is a Paranoid Safeguard ! [[ I am reminded of my Queries + Comments to my Bank getting deleted , because I used the word "UPDATE" & the Paranoid Bank Process deleted those Comments , imagining it to be SQL ! When I changed the wording to "I want to let you know" , the Comments went though ! ]]
    – Prem
    Commented Nov 24, 2023 at 11:49
  • 2
    "There should be no unknowns and no defaults." 204 is well known to not have any content, and all programmers assume that there is no need to check a Content-Type header for content that doesn't exist. Even a broken proxy adding a default Content-Type would be harmless. If there were any possibility of that header not being present could break a client, that is a security vulnerability of the client, not the server or the network at large.
    – phyrfox
    Commented Nov 24, 2023 at 17:56

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .