One of our apps has been pentested by our client’s infosec provider and the results are … less than useful.

The so-called pentest appears to have been a scripted nmap (of CloudFront!) and a scripted poke around the HTTP headers returned by the CloudFront server fronting the React app. I hope the client didn’t pay very much for a check I could have run in 5 minutes for them.

Anyway, one of the findings is that you can see from the HTTP header “Server” that the service is delivered by CloudFront and that’s apparently a problem. Because an attacker could target their attacks based on known CloudFront vulnerabilities, I guess.

This is bullshit because there are many other ways to detect a CloudFront service and changing the Server header achieves absolutely nothing. Except one thing: “look we’re doing something about security”. The client is a corporate and there are literally teams of people being paid salaries to generate, manage and document this bullshit.

In the meantime there is genuine, well-known and actionable technical debt that we could be addressing except for the maintenance budget being used up by this box-checking crap.

Here’s my response to the ticket. I don’t use the word “futile” very often in Jira.


I believe this finding is about the HTTP header “Server”, which in the case of our app returns

Server: CloudFront

Although the finding mentions port 80 (HTTP) this is also true for port 443 (HTTPS) requests.

This Server header is returned whichever URL is used for either of the apps in production.


  • The Server header cannot be removed entirely with CloudFront.
  • The Server header could be set to an arbitrary string such as “Undisclosed”

Other remarks

CloudFront sets several other headers which identify the service’s origins as follows:

  • X-Cache: this header is set to indicate whether the page was served from CloudFront’s cache and always includes the word “CloudFront”. It cannot be user-configured and is always present.
  • Via: this header is set to indicate which of CloudFront’s CDN servers actually served the page. It always includes the word “CloudFront” and cannot be user-configured
  • X-Amz-Cf-Id , X-Amz-Cf-Pop and X-Amz-Server-Side-Encryption: the names of these headers indicate an Amazon AWS source for the page. They are not configurable.
  • The IP addresses of CloudFront’s global PoPs are well known and would reliably indicate the page has been served by CloudFront in the absence of any headers.

The reasoning behind this finding is that allowing an attacker to know which type of server serves the web page could steer them towards known vulnerabilities in that engine. In the case of CloudFront it is not possible to conceal the type of server since headers other than “Server” also identify the page’s origin.

It is therefore futile to change the “Server” header to an arbitrary string as there are other ways to determine that the page is served by CloudFront.

We rely on AWS CloudFront to securely serve the React app and this is true whether or not it is identifiable as the origin. CloudFront does not serve the app’s data which comes entirely from the back end service.

If it helps you in any way to change the Server header to an arbitrary string then we can do this but all non-default configuration options carry with them the minor risk that they are less well understood and less widely tested than default configuration options.