Allow %0A in url RewriteRule with htaccess - .htaccess

I've got a rewriterule in my .htaccess which allows me to add unlimited parameters separated by /'s.
RewriteRule ^(.*)/?$ index.php?params=$1 [L,NC]
This works properly untill I send an urlencoded string to it (using cURL) with an encoded \n in it (%0A).
So server/param1/param2/param3text works, but server/param1/param2/param3text1%0Aparam3text2 doesn't.
I found one Q on Stack Overflow mentioning a similar problem:
How can I apply an htaccess rewrite rule to a URL containing a linefeed character (%0A)?
But I can't/don't know how to implement [\r\n] in my (.*).
Any help?

Ok, so first, I had to add a check to make sure that the file didn't exist (the two RewriteCond's take care of that). Then I had to create a pattern that matched any character, or a \r or a \n that was matched one or more times(+). The zero or more times operator (*) didn't return the results properly.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^((.|\r|\n)+)/? index.php?params=$1 [L,NC]

Just an FYI here: A common hacking method called Whitespace filtering uses %0A
Filtering can be bypassed on the space character by using alternative
whitespace characters to the space character (%20). Most SQL engines
consider a line return (%0a in a *NIX environment, %0a%0d in a Windows
environment), tab characters, or the + character as valid whitespace:

You must utilize %{THE_REQUEST} variable to grab actual path from original Apache web server request.
Try this code:
RewriteCond %{QUERY_STRING} !^params=.+ [NC]
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s/+[^/]+/([^\s]+) [NC]
RewriteRule ^ index.php?params=%1 [L,QSA]
Then inside index.php check $_SERVER["QUERY_STRING"] for the full unadulterated path with %0A in it.

Related

url rewriting with htaccess not working

I am trying to rewrite my urls in my site so whatever is after the slash is passed as an argument (example.com/Page goes to example.com/index.php?page=Page)
here is the code that isn't working (it gives a Forbidden):
RewriteEngine On
RewriteRule ^/(.+)/$ /index.php?page=$1 [L]
Any Help will be appreciated
This is what I suggested in the comment to your question:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !^/index\.php
RewriteRule ^(.+)$ /index.php?page=$1 [L,B]
The leading slash does not make sense in .htaccess style files, since you do not process an absolute oath in there, but a relative one. About the trailing slash: your example does not show such a slash, so why do you want to have it in the regular expression? It results in your pattern not matching anything but a request terminated by a slash. Which is not what you want.
The RewriteCond lines are there to still allow access to physical existing files and directories and to prevent an endless loop, though that should not occur with an internal-only rewriting. And you need the B flag to escape the part of the request url you want to specify as GET argument.
The last condition is actually obsolete, since obviously /index.php should be a file. I leave it in for demonstration purposes.
In general it is a very good idea to take a look at the documentation of apaches rewriting module: httpd.apache.org/docs/current/mod/mod_rewrite.html
It is well written, very precise and contains lots of really good examples. It should answer all your questions.

mod_rewrite to php file unless directory exists

I have a mod_rewrite rule working to direct non-existing directories to a php file which does a database get based on the $1.
Everything works fine unless the directory does exist, which displays the proper directory, but it also appends the query string when it's not necessary.
I have been scouring the web for the past few hours and trying different methods with no luck.
Does anyone know how to keep this functioning as-is, but get rid of the query string?
Thanks much.
Here is my code:
RewriteEngine On
Options +FollowSymlinks
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([0-9a-zA-Z\-]+)/$ $1 [R]
RewriteRule ^([0-9a-zA-Z\-]+)$ product.php?product=$1
What ends up happening is the browser displays the URL as http://domain.com/existing_dir/?product=existing_dir
try that, it removes / on its own without repeating whole process
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*?)/?$ product.php?product=$1
if You insists on limiting special characters, that would do:
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([0-9a-zA-Z\-]+?)/?$ product.php?product=$1
+ is 1 or more repeatition, * is 0 or more, and +?, *? are modifiers for not hungry matching - it allows /? to match anything
Additionally in Your example, first RewriteRule is been executed conditionally (when directory does not exists), the second one is executed always (if first whould not break the process) so even if directory exists
Mod_rewrite doesn't affect the query string, it will always be tagged on to the end of the new URL unless you tell mod_rewrite to have an empty query string. This is done by adding just a ? at the end of the new string. So the first line should look like this:
RewriteRule ^([0-9a-zA-Z\-]+)/$ $1? [R]

.htaccess with variables for user friendly urls

I got these two urls:
/portfolio/stamped_concrete
/p_details.php?id_cat=23&?id=91
I want to make the second url rewrite to:
/portfolio/stamped_concrete/23/91
stamped_concrete is a dynamic url which is why I'm at a loss of how to solve this. Also the two files (portfolio.php and p_details.php) are in the same directory if that matters.
How would I accomplish this?
EDIT:
stamped_concrete is also a variable string that I rewrote before and it works:
RewriteRule ^services/([a-z0-9_-]+)$ /services.php?url=$1 [NC,L,QSA]
so how would I call it within the RewriteRule?
would this be on the right track?
RewriteCond %{QUERY_STRING} url=([a-z0-9_-]+)
RewriteCond %{QUERY_STRING} id_cat=([0-9]+)
RewriteCond %{QUERY_STRING} id=([0-9]+)
RewriteRule /p_details.php?.* /portfolio/$1/$2/$3
Try this:
RewriteCond %{QUERY_STRING} id_cat=([0-9]+)
RewriteCond %{QUERY_STRING} id=([0-9]+)
RewriteRule /p_details.php?.* /portfolio/stamped_concrete/$1/$2
Might need to tweak it a bit -- not sure if the RewriteRule part is correct (sorry).
But, the important part is QUERY_STRING, see the apache docs: http://httpd.apache.org/docs/2.0/mod/mod_rewrite.html
Also, from http://wiki.apache.org/httpd/RewriteQueryString
I always mix up the backreferences, so try it out, it's eiher dollar signs or percent signs (i really thought it was dollar signs...)
(QUOTE)
Making the Query String Part of the Path
Take a URL of the form http://example.com/path?var=val and transform it into http://example.com/path/var/val. Note that this particular example will work only for a single var=val pair containing only letters, numbers, and the underscore character.
RewriteCond %{QUERY_STRING} ^(\w+)=(\w+)$
RewriteRule ^/path /path/%1/%2?
(END QUOTE)
So you could probably just say "RewriteRule ^/p_details.php /portfolio/%1/%2/%3"

Fixing Rewrite Rules and Conditions In HTACCESS file

Well lets say I have this follow code in my htaccess file,
Options +FollowSymlinks
RewriteEngine on
RewriteCond %{HTTP_HOST} ^www\.(.*) [NC]
RewriteRule ^(.*)$ http://%1/$1 [R=301,NC,L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^([^/]+)$ $1.php
RewriteRule ^forums/([0-9]+) forums.php?category=$1 [NC]
I was wondering how would I, with the above code, redirect certain extensions in a url to my websites 404 page.
For instance, if this link mywebsite.com/forums has any extension at the end of it such as .asp, .php, .html, and so forth it then would get redirected to my 404 page.
And on a quick side note how can I limit the last RewriteRule to only a certain forward slash where mywebsite.com/forums/2 would show the page fine and anything after that certain limit such as mywebsite.com/forums/2/so on... would be redirected to my 404 page.
Anyone have any ideas?
If I understand the question properly, then you need to firm up the regular expressions to only match the patterns you really want - at the moment, they're a bit too lenient for your needs.
For example:
RewriteRule ^([^/]+)$ $1.php
This will match anything without a trailing slash, whereas if you wanted to restrict it to only match, say, things without a trailing slash and consisting of alphanumeric characters, then you might do this:
RewriteRule ^([a-zA-Z0-9]+)$ $1.php
(You could achieve the same effect for certain extensions only by using a lookahead assertion, but that complicates your regular expression. I feel it's probably saner (and easier on the mind) to think about the patterns you really want matched, and then express those up-front.)
Likewise, your latter example:
RewriteRule ^forums/([0-9]+) forums.php?category=$1 [NC]
will match anything which starts with the string forums/, followed by one or more digits, whether or not there's anything after that. Adding an end anchor ($) as you have above
RewriteRule ^forums/([0-9]+)$ ...
will assert that the string ends after the digits.
This relies on the fact that if mod_rewrite can't find a match, it won't attempt any rewrites, and will (in the absence of any explicit resource at that path) fall through to Apache's 404 handling, which is then up to you to override.

.htaccess questions

Say I have the following .htaccess file:
RewriteEngine On
RewriteCond %{HTTP_COOKIE} name=value [NC]
RewriteRule ^image01.gif$ http://www.domain.tld/images/partner/image01.gif [NC,QSA]
RewriteCond %{HTTP_COOKIE} name=value [NC]
RewriteRule ^image02.gif$ http://www.domain.tld/images/partner/image02.gif [NC,QSA]
What do NC and QSA mean?
Also, instead of repeating the same RewriteCond twice is there to use it just once and have it apply to both RewriteRules?
Finally, if the above .htaccess is located at http://www.domain.tld/images/ why doesn't a RewriteRule like this work?:
RewriteRule ^image02.gif$ /images/partner/image02.gif [NC,QSA]
Or maybe this?:
RewriteRule ^image02.gif$ partner/image02.gif [NC,QSA]
The square bracket options are documented in the RewriteRule manual page:
'nocase|NC' (no case):
This makes the Pattern case-insensitive, ignoring difference
between 'A-Z' and 'a-z' when Pattern is matched against the current URL.
'qsappend|QSA' (query string append):
This flag forces the rewrite engine to append a query string part
of the substitution string to the
existing string, instead of replacing
it. Use this when you want to add more
data to the query string via a rewrite
rule.
As far as I know, the RewriteCond directives affect the RewriteRule they precede. If you were setting rules in the main confing file you could write the common directives in a file and include it several times but that's not an option in .htaccess files, sorry.
Your directive works for me, although you probably mean this:
RewriteRule ^image02\.gif$ /images/partner/image02.gif [NC,QSA]
How are you testing it exactly?
NC is for No Case, meaning it can be upper or lower case and it will take you to the same page.
QSA is for query string append. Not really sure on this one, however a quick search http://httpd.apache.org/docs/1.3/mod/mod_rewrite.html sheds a bit more light on this one.

Resources