Block URLs that don't contain query string - regex

Using mod_rewrite how can I block a URL that does NOT contain the query string on the end.
My website uses /get.php?page=blah in several different folders
I see a lot of bots/something hitting every file get.php without the query string. So I want to deny access to get.php when it is requested without ?page=whatever
I am struggling to work it out
RewriteCond %{THE_REQUEST} \^get.php$ [NC]
RewriteRule .* - [F]
Everything I search for regarding this comes up with how to turn query strings into friendly URLs, this is not what I a trying to achieve though.

You can use this code in your DOCUMENT_ROOT/.htaccess file:
RewriteEngine On
RewriteCond %{QUERY_STRING} ^$
RewriteRule (^|/)get\.php$ - [NC,F]

Related

htaccess - rewrite URL ending with specific string and capturing the unique part

I want to feed several URLs into a single php file that will handle the contents of the page, the URLs are like
domain.com/fashion-registration
domain.com/singing-registration
I want to capture URLs ending with -registration and feed fashion or singing into the page but it doesn't seem to be working. This is what I tried
RewriteRule ^(.*)$-registration category.php?link=$1 [NC,L,QSA]
Could you please try following.
RewriteEngine ON
RewriteCond %{REQUEST_URI} ^/(.*)-registration/?$ [NC]
RewriteRule ^(.*)$ /category.php?link=%1 [NE,NC,L]
OR you could try following too, one without RewriteCond.
RewriteEngine ON
RewriteRule ^(.*)-registration/?$ /category.php?link=$1 [NE,NC,L]
Problem in OP's attempt: Since you have used ^(.*)$ and after that you are using -registration in your regex that's why your regex is NEVER going to match -registration

Using htaccess, how do you re-write for parameters over 8 characters or more only?

Using .htaccess file, I am trying to re-write the URL when the 'folder' is 8 or more characters long only. In other words:
https://example.com/blog - goes to the /blog folder
- but -
https://example.com/12345678 - goes to https://example.com/script.php?id=12345678
Ideally, the answer would ensure that https://example.com/12345678/ still works too (note the trailing slash /).
This is for a Linux server running on a shared hosting plan - think Hostgator, GoDaddy, etc.
This is so wrong, but:
RewriteRule ^(.*)$ [>8character]? "script.phpid=$1" ? "";
How about:
RewriteEngine On
RewriteCond %{REQUEST_URI} !^/script.php.*$
RewriteRule ^([^\/]{8,})[^\/]*$ "/script.php?id=$1" [R,L]
Uses RewriteCond as extra guard against a redirect loop
By default, the original query string is discarded when adding a new one, so if you want to preserve the original (so, example.com/12345678?utm_campaign=foo goes to example.com/script.php?id=12345678&utm_campaign=foo) use the [QSA] flag, like this:
RewriteEngine On
RewriteCond %{REQUEST_URI} !^/script.php.*$
RewriteRule ^([^\/]{8,})[^\/]*$ "/script.php?id=$1" [QSA,R,L]
If the ID is always just numbers, you could change the Regex to ^(\d{8,})[^\/]*$ to make it a little more foolproof.

removing multiple groups of slashes everywhere in URL in .htaccess

I currently have a website where guests are able to access each url with any number of slashes to separate folder names. For example, if a URL is supposed to be:
http://example.com/one/two/three/four
Then users could access the same page via any of the following:
http://example.com/one//two///three////four/////
http://example.com/one/two////three/four/////
http://example.com///one///////////two////three/four/
http://example.com///////////one///////////two/three/four
However, I want the above example urls to only redirect users to this URL:
http://example.com/one/two/three/four
This is my .htaccess file to attempt to stop the enormous slashes:
RewriteCond %{ENV:REDIRECT_STATUS} !^$
RewriteRule .* - [L]
RewriteRule ^(.*)/+$ /$1 [R=301,L,NC]
RewriteCond %{REQUEST_URI} ^/+(.*)/+$
RewriteRule .* /%1 [R=301,L]
The third line successfully stops trailing slashes on long URLs. The 4th and 5th lines are my attempt to stop trailing slashes right after the domain name, but that was unsuccessful.
The reason why I ask this question is because I don't want google to catch me for duplicate content and with adsense active on the site, google will likely scan all the URLs that I access.
Is there a RewriteCond/RewriteRule combo I can use to strip the middle slashes or is it more involved?
You can use this rule for removing multiple slashes anywhere in URL except query string:
RewriteCond %{THE_REQUEST} \s[^?]*//
RewriteRule ^.*$ /$0 [R=302,L,NE]
This works for me:
RewriteCond %{REQUEST_URI} ^(.*)//(.*)$
RewriteRule . %1/%2 [R=301,L]

How do I strip all query string besides one directory from URL?

I want to force rewrite all url using queries /?campaign=whatever etc.
I wrote something like this (I'm not sure if it's the best way to do it):
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /([^?]*)\?
RewriteRule (.*) /$1? [R=301,L]
How can I tell apache not to rewrite only directory /admin/ ?
Also, if anyone knows if it's possible to mess up some other services using this technique? I don't need analytics campaigns etc, people just link with their own stupid tracking urls to my blog and it bypasses the cache but I can't change the cache system currently.
Example:
http://www.example.com/admin/
http://www.example.com/admin/pages.php?var=blabla
(anything after or /admin/) - ignore
Else - clean the query strings.
RewriteCond %{QUERY_STRING} .+
RewriteCond %{REQUEST_URI} !^/admin(?:/.*)?$
RewriteRule (.*) /$1? [R=301,L]
Check if query string contains something.
Check the request URI if it does not start with /admin/.
If all conditions are met, redirect URL - remove query string.

rewritecond with query string works, but when i submit a new query from the clean url, it just appends the url with the old query string

Here is are my rewrite rules and conditions
#link ReWrite
RewriteRule ^searchresults/([^/]*)/([^/]*)/([^/]*)/([^/]*)/([^/]*)$ /searchresults.php?search=1&year_search_type=single&isused=$1&year=$2&make=$3&model=$4&price=$5 [L]
#query Rewrite
RewriteCond %{ENV:REDIRECT_STATUS} 200
RewriteRule .* - [L]
RewriteCond %{REQUEST_URI} ^/searchresults.php [NC]
RewriteCond %{QUERY_STRING} ^.*[&]?isused=(\w+).*&year=(\w+).*&make=(\w+).*&model=(\w+).*&price=(\w+).*$ [NC]
RewriteRule . /searchresults/%1/%2/%3/%4/%5? [R=301,L]
Situation -
i have a search page that searches the database and shows results. This setup catches the Query and rewrites it to clean urls (awesome!) BUT if i run a query a second time, aka from the cleaned url, the search request now just adds the original ?key=value&key=value to the clean url to make the request.
searchresults.php?make=value&model=value turns into searchresults/value/value as i want it to
but when i run the second query from searchresults/value/value it ends up turning it into
/searchresults/value/value?make=value&model=value
any way to defeat that from within .htaccess as the search query itself is in some deep php crazy land of code, and i honestly cant even find the thing, so editing the php is not in the cards.
ALSO, as a bonus, if anyone can tell me what edits to make so that when the query sends a request that looks like key=value+with+spaces i get the correct clean url back? right now it takes key=value+with+spaces and gives me back "value" but drops off with+spaces and moves onto the next key value pair....
THANKS
Not sure why you're having the problem, your rules worked perfectly fine for me on a vanilla apache install in a blank htaccess file. But you can try changing your rules a little:
The first thing you need to do is swap the order of your two rules. The redirect rule must be before any internal rewrites. This prevents two rules from being applied to the same request (the rewrite engine loops through all the rules until the URI stops changing). Second, you need to match against the actual request instead of the %{QUERY_STRING} match against the %{THE_REQUEST} variable:
RewriteCond %{THE_REQUEST} \ /+searchresults\.php\?.*[&]?isused=(\w+).*&year=(\w+).*&make=(\w+).*&model=(\w+).*&price=(\w+).*$ [NC]
RewriteRule ^ /searchresults/%1/%2/%3/%4/%5? [R=301,L]
RewriteRule ^searchresults/([^/]*)/([^/]*)/([^/]*)/([^/]*)/([^/]*)$ /searchresults.php?search=1&year_search_type=single&isused=$1&year=$2&make=$3&model=$4&price=$5 [L]