# Securing Apache: Return 404 instead of 403 with mod_rewrite

## mlnzigzag

Hi people, i'm basically a noob of mod rewrite.

I would like to write a rule that matches any 403 error and rewrites it as a 404.

I'm able already to do that for a specific directory with such a rule:

```
RewriteRule ^/WebSite/img$ /error/404_403.php

RewriteRule ^/WebSite/img/$ /error/404_403.php
```

/error/404_403.php is purposely a non-existant file

That rule will return a 404 instead of the 403 Forbidden for the existing directory

as you can see i had to write two rules with and without the ending / to handle both cases.

And here you can see a curl output of the rule above, as you can see the server returns a 404 Not Found, that is my goal:

```
> GET /WebSite/img/ HTTP/1.1

> User-Agent: curl/7.19.7 (universal-apple-darwin10.0) libcurl/7.19.7 OpenSSL/0.9.8l zlib/1.2.3

> Host: *******.net

> Accept: */*

> 

< HTTP/1.1 404 Not Found

< Date: Fri, 05 Nov 2010 10:05:40 GMT

```

What i would like to write is one global rule that rewrites any 403 forbidden to a 404 not found.

Please note that is not enough to serve custom error pages, such as:

```

ErrorDocument 403 /error/existing_404_403.php

ErrorDocument 404 /error/existing_404_403.php
```

with an existing and proper 404 error page, as with the appropriate curl flags (and with many other tools) a remote attacker will still be able to see the true http response, wich will still be 403, even if the disaplyed html is a 404 Not Found custom error page:

```
< HTTP/1.1 403 Forbidden

< Date: Thu, 04 Nov 2010 14:42:52 GMT

< X-Powered-By: PHP/5.2.10

< Content-Length: 202

< Connection: close

< Content-Type: text/html; charset=ISO-8859-1

< 

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">

<html><head>

<title>404 Not Found</title>

</head><body>

<h1>Not Found</h1>

<p>The requested URL was not found on this server.</p>

```

Please be patient with my poor english 

I'm not very sure if this thread should be in Security, the moderators will please take care of that.

Thanks a lot for any kind of help

Marco

----------

## aCOSwt

 *mlnzigzag wrote:*   

> What i would like to write is one global rule that rewrites any 403 forbidden to a 404 not found.

 

Well, I do not know the answer to your exact question.

What I do personally in order to achieve what you wish in final with a single rule is that :

1/ I give special names to the files / directories I want to protect. Let's say their names all begin with a "."

2/ RedirectMatch 404 ".*\/\..*" does the trick.

----------

## mlnzigzag

 *aCOSwt wrote:*   

>  *mlnzigzag wrote:*   What i would like to write is one global rule that rewrites any 403 forbidden to a 404 not found. 
> 
> Well, I do not know the answer to your exact question.
> 
> What I do personally in order to achieve what you wish in final with a single rule is that :
> ...

 

Thanks mate, that actually would solve the issue, but how would you apply such a change in a production environment, where 50 vhost based sites will have to change every path to the linked resources?  :Smile: 

I really wish there is something that can be done with mod_rewrite or any other apache mod to workaround this.

Many thanks for your reply

ML

----------

## aCOSwt

 *mlnzigzag wrote:*   

> ...how would you apply such a change in a production environment, where 50 vhost based sites will have to change every path to the linked resources? 

 

 :Shocked:  Gee ! I understand better your problem   :Confused: 

Hmmm... Nevermind... Fire the change... you'll tell it's aCOSwt's fault !   :Laughing: 

----------

## Hu

What value does this serve?  How does forging a 404 in place of a 403 improve security?

----------

## desultory

 *mlnzigzag wrote:*   

> Please note that is not enough to serve custom error pages, such as:
> 
> ```
> 
> ErrorDocument 403 /error/existing_404_403.php
> ...

 Not enough, but it is close to a working solution. Create a directory for error handlers, set the global 404 and 403 handlers to a fully qualified URL pointing into that directory at some nonexistent resource, set the 404 handler for that directory to default or some other handler that does actually exist.

 *mlnzigzag wrote:*   

> I'm not very sure if this thread should be in Security, the moderators will please take care of that.

 It pertains to networking and security, so it would seem to fit.

 *Hu wrote:*   

> What value does this serve?  How does forging a 404 in place of a 403 improve security?

 It provides a degree of security through obscurity by not providing potential attackers with an easy way to determine where files that they are not supposed to have access to are located.

----------

## aCOSwt

 *Hu wrote:*   

> What value does this serve?  How does forging a 404 in place of a 403 improve security?

 

In a way that it does not give any clue.

HTTP403 does give a clue : You get a correct path but you do not get the right perms. => What you are looking for and should not see is actually here !

HTTP404 from the specs just say : There is nothing there !

Which, in a first step will mislead the hacker-n00b and confuse the Tux's little helper who knows that things can be disguised but then cannot deduce if the path is wrong or the perms are wrong.

EDIT : Desultory is quicker for comiting ! and definitely the most clever:

 *desultory wrote:*   

> Create a directory for error handlers, set the global 404 and 403 handlers to a fully qualified URL pointing into that directory at some nonexistent resource

 

Simply clever !

----------

## aCOSwt

 *aCOSwt wrote:*   

> Simply clever !

 

Well... only clever I mean...   :Exclamation: 

BTW... If I understand well your solution, this should not confuse the hacker-apprentice because there will actually be an initial HTTP403, that will in its turn trigger an HTTP404 right, but the initial HTTP403 is... Hmmm... how would I say... hmmm... see-able !Last edited by aCOSwt on Sat Nov 06, 2010 9:54 am; edited 1 time in total

----------

## desultory

The 403 would 302 to a 404.

----------

## aCOSwt

 *desultory wrote:*   

> The 403 would 302 to a 404.

 

You are right! I had summarized...

However... these transitions are see-able indeed !

----------

## desultory

They are visible but they are entirely consistent between 403 and 404, as both 302 to a 404, wrapping the whole thing behind a front end proxy could make it appear to directly 404 to a client, but by that point there must be a cleaner solution.

----------

## mlnzigzag

 *Hu wrote:*   

> How does forging a 404 in place of a 403 improve security?

 

Because returning a 403 Forbidden returns two informations to the remote attacker: 

1) the access to the file/folder is restricted

2) the file/folder EXISTS

Thus, the more 403 the remote attacker gets, more informations he gathers about the filesystem structure.

This is beyond the PCI-DSS compliance, i know it's something maniac, but some customers pretend this type of hardening!

I'll tell you later the exact Security Policy they want to meet, i can't remember it right now.

ML

----------

## mlnzigzag

 *desultory wrote:*   

> They are visible but they are entirely consistent between 403 and 404, as both 302 to a 404, wrapping the whole thing behind a front end proxy could make it appear to directly 404 to a client, but by that point there must be a cleaner solution.

 

Thanks a lot guys for your interest in my thread.

I'm gonna make my tests on monday, and will post the results ASAP.

Thank you very much!  :Smile: 

ML

----------

## mlnzigzag

 *mlnzigzag wrote:*   

> 
> 
> I'll tell you later the exact Security Policy they want to meet, i can't remember it right now.
> 
> 

 

http://owasptop10.googlecode.com/files/OWASP%20Top%2010%20-%202010.pdf

http://www.owasp.org/index.php/OWASP_Top_10_2010_AppSecDC

Belive me people, i'll pray for you that you never met such a document in your working-life!   :Shocked: 

I'll write back on monday

ML

----------

## aCOSwt

 *desultory wrote:*   

> They are visible but they are entirely consistent between 403 and 404, as both 302 to a 404

 

<trolling>

Consistence ?... Hmmm... Yes indeed !

If, as anybody can legally do, see a 302 -> 404, then...   :Rolling Eyes:   OK, there is some ambiguity...   :Very Happy: 

Either the sysadmin is a moron   :Rolling Eyes:   or... he is pulling my leg !   :Twisted Evil: 

</trolling>

<practicalling>

I do not think devoting the job to the proxy is an acceptable solution. Googling "tunisia fake 404" returns hundreds of suggestions on how to bypass a proxy faking 404s for whatever reasons.

mlnzigzag was looking for a solution with mod_rewrite, I initially thought mod_headers but, as far as I tried, it seems to imply many undesirable side effects because, as far as I undesrtood, it acts either on 2** statuses only or on everything, which leads to a significant amount of work.

</practicallling>

<intellectualling>

... then... why not... YESSSS !

THE solution is through a non-parsed headers script ! With a nph-* script, to the simple cost of being obliged to define the entire header yourself, you will send the 403 with an authentic 404 http header.

</intellectualling>

</dreaming>

vi apache_sources

:g/403/s//404/g

ZZ

</dreaming>

<Off-Topicing-Moral>

BTW : I am convinced that either mlnzigzag's systems face true hackers who are likely to easily bypass the proxy and of course not get mislead by redirections, in which case a nph-* script is THE solution...

OR... as his last post suggests,

it is only a matter of internal policy... in which case... it is just too stupid.

It is well known that policies are reinforced by standards/common-sense. A policy infringing standards/common-sense just weakens itself !

And the standard/common-sense is : serve your pages as what they are !   :Twisted Evil: 

Well... anyway... I believe it is not in mlnzigzag's power to discuss that kind of things with his bosses... => Do what desultory advised !

His solution is simple, aesthetic and answers your rolling-over issue.

After all, mlnzigzag you seem asked for something... period. Not necessarily something... efficient !  :Rolling Eyes: 

</Off-Topicing-Moral>

----------

## desultory

 *aCOSwt wrote:*   

> <intellectualling>
> 
> ... then... why not... YESSSS !
> 
> THE solution is through a non-parsed headers script ! With a nph-* script, to the simple cost of being obliged to define the entire header yourself, you will send the 403 with an authentic 404 http header.
> ...

 Using bouncing redirects was meant only as a way to do something functionally equivalent while only depending on core modules, if scripting is an option, nph scripts are indeed the correct solution.

----------

