Need to pass backslashes in query string with pretty urls - php

I'm trying to pass a backslash as part of a query string argument.
The project uses a pretty simple url_rewriting method:
//.Htaccess
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule .* index.php?arguments=$0 [NC,L]
Then receive $_GET['arguments'] with values separated by /
Ex.: blog/post/2/ will fill $_GET['arguments'] with: 'post/2/'
The problem is, when I try to pass something like test%5Cabc (url encoded for test\abc), the request returns a 404 error instead of passing it as an argument
I have no idea how to fix it. Thanks in advance.

The reason you get a 404 error is because by default, Apache has AllowEncodedSlashes turned off, and its behavior is to 404 any request containing a backslash. This is because having it turned on is a potential security hazard. In Apache 2.2.18 and later, there is a NoDecode setting which makes this a bit safer, and works well for your case.
Anyway I tried turning it on locally, and indeed this script:
<?php var_dump($_REQUEST); ?>
is able to handle urls like
http://localhost/this\is\a\test
and outputs
array(1) { ["arguments"]=> string(14) "this\is\a\test" }
However, it (or my browser) seems to have problems with encoded backslashes, converting them to regular backslashes - maybe that's not a problem. If you enable the B flag on your rewriterule, it will convert unencoded backslashes to encoded backslashes.

I hope I got you right, try using this :
'/file.php?id=$value'//this utilise that backslash and then pass the id to the `$_Get[]` Function somewhere in the file.php.

Related

.htaccess Php rewrite url

I try to realize a system of rewriting URLs in .htaccess.
Then here is my goal:
If I have an url of this form: http://localhost/view.php?Id=456
Then I want to transform it to: http://localhost/456
I use this rule in htaccess:
RewriteRule ^ ([a-zA-Z0-9] +) $ view.php? Id = $ 1
Now this works very well!
But my problem I want to add points to id ie instead of 456 I can put: my.book
That is to say: http://localhost/my.book
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([a-zA-Z0-9\.]+)$ view.php?id=$1 [QSA,L]
You need RewriteCond %{REQUEST_FILENAME} !-f before the RewriteRule line to tell the server that the RewriteRule written below to be executed if the input passed in the URL is not an actual file. Because server searches for a file matching the input you pass in the URL and also it won't work in case you pass my.book in the URL since web server recognizes . as prefix for extension like .php or .html or like so and thereby it results in Not Found error if there is no file named my.book exists. So, you also need to escape . in the URL.
To allow .'s in the input, you need to add . with escape sequence \ in the character class group like ^([a-zA-Z0-9\.]+)$. Note, allowing this can result in escaping the extension in the URL, that is, passing view.php in the URL won't navigate to the actual file. Rather, it will be considered as a value in the query string.
Try this:
RewriteRule ^([a-zA-Z0-9\.]+)$ view.php?Id=$1
Basically what I did is I added \. with your pattern. This will make sure your regex matches any letter (small/caps), decimal numbers and periods (.). Hope this helps :)

Parse question mark as normal character after mod_rewrite

So this may sound weird, however I currently have mod_rewrite set-up to pass 2 variables through.
RewriteRule ^profiel/(.*)$ index.php?p=profiel&user=$1
In the second var (&user=), it passes a username which is retrieved through GET in PHP. However, some of the usernames can have question marks in them. However if this is the case, the question mark won't be passed to the GET variable. (For example: "www.example.com/profiel/whoami?" ends up as just "whoami" instead of "whoami?")
I honestly don't know how to solve this problem. Any help would be great!
You can use this rule by capturing your values directly from THE_REQUEST variable:
RewriteEngine On
RewriteCond %{THE_REQUEST} /(profiel)/(\S+)\s [NC]
RewriteRule ^profiel/ index.php?p=%1&user=%2 [L,NC]
You can use the PHP function urlencode to encode the username. For example, whoami? will become whoami%3F. So your url will become www.example.com/profiel/whoami%3F
Then to retrieve your username, you can use urldecode.
Here's the documentation on both function:
urlencode
urldecode

mod_rewrite not matching regexp

I have a regexp that seems to work fine when tested at regexp101.com
but that does not give me the same result within mod_rewrite.
So, the URL I am trying to rewrite is:
/modeles-voiture/Nissan/Qashqai+2
The expected result is:
/modeles.php?brand=Nissan&model=Qashqai+2
The rewrite rule:
RewriteCond %{REQUEST_URI} ^/?modeles-voiture [NC]
RewriteRule \/([A-Z][\-A-Za-z]+)\/([\+\-A-Za-z0-9]+$) /modeles.php?brand=$1&model=$2 [L]
What I am getting out of the rewrite rule is:
/modeles-voiture/Nissan/Qashqai 2
Note the missing + sign, which throws off my script at modeles.php
Thanks for your help.
I think you want the [B] flag.
Look at the answer to this question: How to encode special characters using mod_rewrite & Apache?
So then mod_rewrite changes your request '/tag/c++' to 'script.php?tag=c++'. But in a query string component in the application/x-www-form-encoded format, the escaping rules are very slightly different to those that apply in path parts. In particular, '+' is a shorthand for space (which could just as well be encoded as '%20', but this is an old behaviour we'll never be able to change now).
So PHP's form-reading code receives the 'c++' and dumps it in your _GET as C-space-space.

CodeIgniter Mod Rewrite Rules and the Controller

Learning PHP, I am playing around with mod_rewrite and CodeIgniter. I have configured my .htaccess file correctly with
RewriteEngine On
RewriteRule ^(resources)/(.*) $1/$2 [L]
RewriteRule ^(user_guide)/(.*) $1/$2 [L]
RewriteRule (.*) index.php?$1 [L]
I understand a bit of regex, and can appreciate what happens here. The rewrite rules are applied and the server than handles the final URL which in the above case- attaches index.php (the front controller) to the "pretty" URL. So far so good.
I now want a URL pattern :
/<person-name>/at/<place>
to get translated to :
/index.php/person/list?personName=$1&place=$2
And i handle the request at my list function in the person controller. I do not understand why the following doesn't work:
RewriteRule ^([a-z]+)/(at)/([a-z]+)$ index.php/person/list?personName=$1&place=$2 [L]
What am i doing wrong/where is my understanding flawed? I see that the placeholders are extracted correctly ($1 and $3), however, it throws a CodeIgniter 404.
Many thanks!
It's possible that the simplest fix will fix your issue. By wrapping "at" in parentheses, you're creating another matching group, which means that $2 will always be "at." That could be breaking everything. You want index.php?person/list?personName=$1&place=$3 But you may have noticed that issue and fixed it without fixing the problem, in which case, read on.
Check out How to make CodeIgniter accept "query string" URLs?. It seems to indicate that you can't mix and match the segment-based approach and the query string approach. Without seeing your controller code, I can't say for certain, but I'd start investigating there. You might also try:
RewriteRule ^([a-z]+)/(at)/([a-z]+)$ index.php?person/list/$1/$3 [L]
which would do the same thing the general-purpose CI redirect rule below does; send the URL off to index.php as a query string for processing. You've said you got it working with routes, so rather than passing a query string to your controller, you can expect person and place as two arguments. CI's handling of query strings leaves a lot to be desired, and I've never tried to MOD_REWRITE something including a query string into a query string.

URL encode in htaccess, maybe?

Consider the following scenario:
I want to be able to access http://www.example.com/word/hello/, where the word hello is variable. So I set up .htaccess to configure that.
RewriteEngine On
RewriteRule ^word/(.+)/?$ displayword.php?word=$1 [L]
I used .+ because I also want to filter any symbols such as ?+-.!;: etc.
And I set up my PHP file accordingly:
<?php
echo $_GET['word'];
?>
Remember that this is just a scenario. Now, I went to this URL: http://www.example.com/word/Are you ok?/, and the page outputted this:
Are you ok
And I couldn't figure out why. But then I realised that the question mark symbol is the starting point of the URL variables.
So is there a way to 'url encode' the question mark in the above example, in order for it to be displayed correctly?
There is no need to encode it, try this:
RewriteEngine On
RewriteRule ^word/([a-zA-Z0-9-=_.?]+)/?$ displayword.php?word=$1 [L]
It will display ? in the parameter and any other character you add to the [group]. I did not test if the rule works, though, but I suppose it does. Looks ok and that is not the question.
I don't know heaps about .htaccess files, but you could change your PHP script to use $_SERVER['PATH_INFO'] instead of $_GET or $_REQUEST.
Particularly, this comment might help you out.
In the HTTP protocol the "?" separates the querystring from the rest of the URL, so I don't think it will be possible to use it directly inside the URL. One solution would be to encode the question mark into %3F.
Then you can use string urldecode (string $str) to decode the string.
See this URL Encoding Reference for the encoding of other characters.
Change your code to this:
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s/+word/([^/]+) [NC]
RewriteRule ^ index.php?word=%1 [L,QSA]
Reason this works is because RewriteRule works on %{REQUEST_URI} which gets URI i.e. string before question mark ? however %{THE_REQUEST} works on the full URL that includes question mark ? as well.

Categories