Is it possible to determine that a page actually exists when it is designed to throw a 404 NOT FOUND?

On my server, when a request to a script is made while passing invalid parameters, I am throwing a 404 http status code because I don't want those with no knowledge of the system to know the page (public URL) exists. I am hoping that throwing a 404 will make an attacker think the script does not exist. No resources on the server itself actually direct to the script, it would all be from external requests.

What I really want to know is, from just the response, would someone be able to tell the difference between a page that does not exist and a page configured to return a 404?

The response headers when making an invalid request to the script do indicate a http status of 404, and not a http status of 200 with a 404 page displayed.

Below is the response header I am getting when I make an invalid request.

HTTP/1.1 404 Not Found
Date: Fri, 27 Jan 2017 23:32:28 GMT
Server: Apache
X-Frame-Options: SAMEORIGIN
X-Powered-By: PHP/5.4.16
X-XSS-Protection: 1; mode=block
Content-Length: 0
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/html; charset=UTF-8

EDIT: Below is the response header I am getting when I hit a page that truly does not exist.

HTTP/1.1 404 Not Found
Date: Tue, 31 Jan 2017 19:08:06 GMT
Server: Apache
X-Frame-Options: SAMEORIGIN
Content-Length: 203
Keep-Alive: timeout=5, max=99
Connection: Keep-Alive
Content-Type: text/html; charset=iso-8859-1
  • 1
    Ok, so is your real question, "is there a way to determine that a page does in fact exist if it throws a 404?" – schroeder Jan 30 '17 at 21:57
  • 1
    @Mocking I think, at this point, you might need to overhaul your question text. It's a little disjointed and difficult to follow. I'll take a stab at it, and you can revert if I miss the mark. – schroeder Jan 31 '17 at 7:55
  • 1
    I'm unsure, because it could depend on the actual Apache configuration, but that field X-Powered-By: PHP/5.4.16 might be a hint. Does it exist for truely missing pages? Maybe you could add a response got for a truely missing page in your question. – Serge Ballesta Jan 31 '17 at 8:35
  • 1
    Why don't you design your page so it's secure even if an attacker does know it exists? Then you don't need to pretend it doesn't exist. – user253751 Jan 31 '17 at 9:32
  • 5
    Have you compared your "fake" 404 to a page that really doesn't exist? – user253751 Jan 31 '17 at 9:33

Throwing 404 error for every invalid request could be questionable, an attacker may start suspecting this behavior specially if he knows the service he is targeting.
Does this help protecting your service ? this really depends on the perseverance of the attacker.


The attacker can detect the difference if you don't craft the 404 response header properly as the server would do

Here is a PoC for Java server case (Tomcat8):
This is a 'truthful' 404 status returned by the server itself for any not found resource :

Date:Tue, 31 Jan 2017 09:15:54 GMT

This one is returned by the servlet :

Date:Tue, 31 Jan 2017 09:18:04 GMT

You notice the parameter's value of "Content-length" in both cases, this one could attract the attacker's attention.

|improve this answer|||||
  • Content length was also right. Thanks for the help. – Mocking Jan 31 '17 at 19:13
  • You mean the param 's values was different ? I think you got the answer – elsadek Jan 31 '17 at 21:24

Beware, hiding actual error code smells a little as obfuscation. There is nothing really bad from a security point of view, but it adds little security if any. Do you really think that attackers blindly accept error codes? You know they can be changed at will, and they do too. Ok, it can be useful against script kiddies but not facing a serious attack, so you should really think about what is your threat model before going that way.

And there could be a drawback here. Unless you build a special log system that logs the internal error, you will end in logs containing only 404 errors. That means that you have lost any possibility of log analysis to try to discover attacks to your site and possible security flaws. IMHO error code are more useful for the maintainer of an application that for an attacker...

|improve this answer|||||
  • I think the question is: how would attackers be able to pierce this obfuscation? – schroeder Jan 31 '17 at 8:01
  • note that I just overhauled the question while you composed your answer - sorry for confusion – schroeder Jan 31 '17 at 8:02

The same idea applies with user authentication.

Most web services as you have seen, will not tell you what is wrong in your username and password. It will give you a general prompt saying that something with the whole pair was invalid. This leaves the attacker not knowing if the username is incorrect, the password was incorrect, or the pair itself was incorrect.

It's much faster to determine if the user exists compared to does the user exist, and is the password correct. Some attackers will take this into account when trying to gain access to a system by timings.

Likewise the same holds for a 404 (Not Found) vs. 403 (Not authorized). It's faster for the webserver to return a 404 than a 403, but the timings here could be so small, the margin of error might take over.

It's not unheard of to always spit out a 404 instead of both 404/403. A web server such as Apache can customize it's response to a web page request. It's a little harder to change the HTTP return code, but it is certainly easier to modify the page the user sees. Just as with the username/password idea, the attacker is left with two cases:

  • Does this resource actually exist?
  • Do I have to be authorized before I have access to this?

It's more common now for server sided code to handle authorization and authentication without having the web server return a 404/403 code. Server sided code will normally handle such requests, and the web server will simply return a 200 or 300 code. The contents of the page may say 403, but the HTTP code will be 200 or 300. 403 is used for HTTP authentication which has lost popularity over time.

|improve this answer|||||
  • I do want to point out however, that my whole purpose of doing this was so that attackers wouldn't even know the script existed to begin with. – Mocking Jan 27 '17 at 23:11
  • @Mocking Since the web server will always return a 200 or 300 code with server sided code (unless it's overburdened or something), all that requires changing is the page displayed to users. You can simply make it generic by "Invalid access". Does the resource exist? Do I have to sign in? What accounts have access to the resource? These are potential questions an attacker will have to answer with a generic page. – dark_st3alth Jan 27 '17 at 23:14
  • By 200 or 300 code, do you mean http status code? With an invalid request my page returns a 404 status code. – Mocking Jan 27 '17 at 23:25
  • @Mocking There is a hierarchy to the web server. The server it self will first determine if the page exists. If it doesn't, the server will return a 404 code. If the page does exist, the web server will let the server sided code (PHP/ASP/Etc.) run, and then return a 200 or 300 HTTP code along with the contents from the PHP/ASP script. – dark_st3alth Jan 27 '17 at 23:27
  • 1
    I did read that before asking this question, and you commenting that leads me to believe this is not the answer I am looking for. – Mocking Jan 27 '17 at 23:51

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.