Returning for wisdom...rudimentary obfuscation

My goal is to attempt to obfuscate the mvc pattern I’m using by creating a 404 response when a user tries to access actual directories in my site, save for the resources directory where my css, images, and javascript are held. Here’s what I have:


RewriteEngine on

##
#   This section is intended to obfuscate the fact that an mvc pattern is being used.
#   Though the idea is fairly rudimentary, it provides a thin level of security.
##

RewriteCond %{REQUEST_URI} /sandbox/application [OR]
RewriteCond %{REQUEST_URI} /sandbox/controller [OR]
RewriteCond %{REQUEST_URI} /sandbox/incs [OR]
RewriteCond %{REQUEST_URI} /sandbox/logs [OR]
RewriteCond %{REQUEST_URI} /sandbox/model [OR]
RewriteCond %{REQUEST_URI} /sandbox/views
RewriteCond %{QUERY_STRING} !rt=
RewriteRule ^(application)|(controller)|(incs)|(logs)|(model)|(views)(.*) index.php?rt=404 [L]


##
#   This set of conditions and rewrite rule are the engine behind the mvc pattern.
#   The rule rewrites ALL requests to the server to the main controller with one key (rt)
#   whose value is that of the specified route.  If the rt key exists, do not rewrite again.
##

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{QUERY_STRING} !rt=
RewriteRule ^(.*)$ index.php?rt=$1 [L]

Now, this DOES work, but I thought about it and decided a better way might be to replace

RewriteCond %{REQUEST_FILENAME} !-d

with

RewriteCond %{REQUEST_URI} !/sandbox/resources

This also works. So, and while asking I feel like this may be a dumb question, is the second solution more efficient server-wise than the multiple-line first solution? I like the first solution because it is very clear what my intent is and makes it very easy to add any future directories that might appear in the future. If the load on the server is negligible I may want to keep the first solution, even though the second solution means I wouldn’t have to modify the .htaccess file if adding future non-accessible directories in the future…

Smola,

First, NO question is dumb if you’re in a learning mode!

[QUOTE=Smola;4754322]My goal is to attempt to obfuscate the mvc pattern I’m using by creating a 404 response when a user tries to access actual directories in my site, save for the resources directory where my css, images, and javascript are held. Here’s what I have:


RewriteEngine on

##
#   This section is intended to obfuscate the fact that an mvc pattern is being used.
#   Though the idea is fairly rudimentary, it provides a thin level of security.
##

RewriteCond %{REQUEST_URI} /sandbox/application [OR]
RewriteCond %{REQUEST_URI} /sandbox/controller [OR]
RewriteCond %{REQUEST_URI} /sandbox/incs [OR]
RewriteCond %{REQUEST_URI} /sandbox/logs [OR]
RewriteCond %{REQUEST_URI} /sandbox/model [OR]
RewriteCond %{REQUEST_URI} /sandbox/views
RewriteCond %{QUERY_STRING} !rt=
RewriteRule ^(application)|(controller)|(incs)|(logs)|(model)|(views)(.*) index.php?rt=404 [L]
[indent]It does? The regex in the RewriteRule disturbs me as, if you want anything in those six directories to be redirected to index.php, that should be ^(application|controller|incs|logs|model|views)/? (you're not using the ${whatever} so there's no need to use the :kaioken: EVERYTHING :kaioken: atom).

Looking just a bit closer, all the RewriteCond statements imply (a) server or VirtualHost configuration file OR (b) Apache 1.x. Moreover, they could all be matched (unless sandbox is used for other, non-obfuscated files, i.e., WHERE are your css, js, images, etc. files located?) by merely using RewriteCond %{REQUEST_URI} sandbox/.

##
#   This set of conditions and rewrite rule are the engine behind the mvc pattern.
#   The rule rewrites ALL requests to the server to the main controller with one key (rt)
#   whose value is that of the specified route.  If the rt key exists, do not rewrite again.
##

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{QUERY_STRING} !rt=
RewriteRule ^(.*)$ index.php?rt=$1 [L]
# That should work fine.
# RewriteCond %{REQUEST_URI} !/sandbox/resources
# would be great if that leading / is removed AND
# sandbox/resources handles all the subdirectories
# in the list above.

You’re becoming an expert! :tup:

Regards,

DK

Thanks for the reply dk. Sorry I didn’t provide more information at the time. I forgot to include that sandbox is just a directory I’ve set up on my local and also testing server online and actually represents the domain name. I would have removed it completely for any production sites I did.

As for resources, those directories look like this:

resources/css
resources/js
resources/images (and within images there would be subdirectories for each main area of the site)

You bring up an interesting point with the leading slash though. I was actually wondering about that. The only requests I would need to stop directly would be those directories mentioned in my first post, but only that first level deep (their actual location). If the user tried something like /sandbox/foo/model, my PHP would have parsed and sent it to a 404 anyway since it’s not an actual directory. So I figured that I needed the ^ symbol in front for each RewriteCond pattern. However, when I tried this, I could not get it to work. The way that I determine what to use for my conditions and rules is that I write the entire PHP $_SERVER array to a log file and examine its contents. I am running Apache 2.x both locally and on the testing server, but the REQUEST_URI value had the leading slash, so I figured I could get what I wanted by using:

RewriteCond %{REQUEST_URI} ^/sandbox/dir

even though I have read posts by you and other information saying the leading slash was only required for Apache 1.x! However, I don’t think I was able to get it to work which was why I ended up removing the caret and including the slash. Perhaps I should have stopped then and come back here for any clarification instead of writing a messy file…:x

Once I finished writing this I began thinking…if the only existing directory I want accessible for requests is resources, could I have just used (for the first set of conditions in my file):


RewriteCond %{REQUEST_URI} -d [OR]
RewriteCond %{REQUEST_URI} -f
RewriteCond %{REQUEST_URI} !^sandbox/resources
RewriteCond %{QUERY_STRING} !rt=

As for the Rewrite Rule to follow, you said I could just use:

^(application|controller|incs|logs|model|views)/?

for the pattern. I read this pattern as matching any request that begins with any of those directory names with an optional slash following. Then, if using the same rewrite pattern, it would rewrite that directory request to my index.php file with a query string of rt=404. Does it matter if there’s an actual file request involved like model/file.php? I thought the new text to be written only replaces the matched pattern, so if a user made the request I just mentioned, it would get rewritten to index.php?rt=404file.php. Or does the rewrite rule always replace the ENTIRE URI?

Smola,

Aw, my whining about “Specificity” is my fallback when I get confused about what the member is trying to do. Most of the time, I don’t think even the member knows so that’s a “wake-up call” to many.

Okay, IMHO, it’s better to create a VirtualHost for local testing as that SHOULD leave you with an identical file structure. Just a tip, though.

Okay, you want to allow access to resources (again, are there directories under resources you’re playing keep-away with?).

The Leading Slash: This is a very interesting thing as (1) the leading slash would be required in the server and VirtualHost configuration and (2) is “kinda required” in the .htaccess. Okay, it’s REQUIRED that it NOT be present in the RewriteRule BECAUSE the mod_rewrite engine removes that / for the {REQUEST_URI} variable’s processing BUT it IS present when %{REQUEST_URI} is used in a redirection. It’s all very confusing (what Apache.org has done with this thing) but, if you remember these rules, you’ll be okay:

Server & VirtualHost configuration - include the leading /
.htaccess:

[indent]RewriteRule

[indent]Apache 1.x - ^/
Apache 2.x - ^
Either/both - ^/?[/indent]
USING %{REQUEST_URI}

This will HAVE the leading / so http://%{HTTP_HOST}%{REQUEST_URI} will have the proper /'s in the proper locations.[/indent]

BTW, EXCELLENT method (and reasoning) to see (and use) the $_SERVER variables! :tup:

Thinking again? Now you’re thinking like a mod_rewrite coder! :tup:

First, I didn’t know what you were trying to do with all that code so my suggestion was to replace the improper regex with those directories to make sense (to me). Your implication (with your code) was that any request made to those directories (except to any file OR directory within them without the rt “marker” - nice conditions, BTW) should be sent to the 404 via index.php.

Did that address all your questions?

Regards,

DK

The latter; a rewrite rule always replaces the entire URL.

Unless:

  1. You add the [QSA] – Query String Append – flag to the URL, in which case it will copy all the query string parameters from the input URI to the new URI
  2. You rewrite to a complete URL that doesn’t have a query string, Apache will then also copy all the query string parameters from the input URI to the new URI. If you want to avoid this, end the new URI in a question mark.

Note that this only concerns query strings, not directory and/or filenames.