Turn off mod_security for a page in shared hosting environment - php

My page showing error forbidden access error, when I post some html and javascript mixed data by other page post method .
but when I open that page directly its appears correctly without any error.
I know this is server security related issue when I am posting data.
As I searched I found the solution of Turn off mod_security in .htaccess file .
But I want to do this just for this page not for my complete website.
My hosing environment is shared.but I can edit my .htaccess file.

Take a look at some mod_security and .htaccess tricks. There's a lot of different ways you can enable or disable mod_sceurity. The easiest may be to set the MODSEC_ENABLE environment variable to On or Off. You can use SetEnvIf to match against a number of things including the Request_URI:
SetEnvIf Request_URI your_page\.php$ MODSEC_ENABLE=Off
Or a number of pages:
SetEnvIf Request_URI ^/directory/file.*\.php$ MODSEC_ENABLE=Off
Or if you need to do something more complicated, like matching against a query string, using mod_rewrite:
RewriteEngine On
RewriteCond %{QUERY_STRING} example_param=example_value [NC]
RewriteRule ^path/your_file\.php$ - [E=MODSEC_ENABLE:Off]

Do you have the OWASP Core Rule set enabled? Check your Apache error log to see which rule is matching. You may find that it's blocking some of your legitimate users on other pages as well. Talk to your hosting provider about what rule set they are using and what they are doing about false positives.
To solve your immediate problem, you can prevent a URI from being blocked by adding a new SecRule (and you can do this in your .htaccess file.
SecRule REQUEST_URI "/your/uri" "phase:1,pass"
To limit this to POST requests, you could use REQUEST_LINE:
SecRule REQUEST_LINE "POST /your/uri" "phase:1,pass"
Depending on what rule is matching and blocking the request currently, you may have to change those to phase:2 or even add a second, identical rule with phase:2.

Related

Change Wordpress page URL with parameter

I have created a dynamic content page on my Wordpress site. The content is taken from the MySQL database and will be shown based on the GET URL parameter. I created this dynamic page by inserting a PHP code to a Wordpress Page (I use Advanced Ads plugin to insert the code)
I want to change the URL without an URL parameter.
Example:
DomainName.com/hotel-details/?hotelcode=First-Hotel
I want to change it to
DomainName.com/hotel-details/First-Hotel
or
DomainName.com/sometext/First-Hotel
I have tried to adding mod_rewrite to the .htaccess file in the root folder.
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule ^hotel-details/([A-Za-z0-9-]+)$ hotel-details/?hotelcode=$1 [NC,L]
</IfModule>
But it seems doesn't work, when I access DomainName.com/hotel-details/First-Hotel I got an error 404 Page Not Found.
Any help much appreciated!
You are using the rule the wrong way 'round. Instead try that:
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^/?hotel-details/(\w+)/$ /hotel-details/?hotelcode=$1 [END]
In case you receive an internal server error (http status 500) using the rule above then chances are that you operate a very old version of the apache http server. You will see a definite hint to an unsupported [END] flag in your http servers error log file in that case. You can either try to upgrade or use the older [L] flag, it probably will work the same in this situation, though that depends a bit on your setup.
This rule will work likewise in the http servers host configuration or inside a dynamic configuration file (".htaccess" file). Obviously the rewriting module needs to be loaded inside the http server and enabled in the http host. In case you use a dynamic configuration file you need to take care that it's interpretation is enabled at all in the host configuration and that it is located in the host's DOCUMENT_ROOT folder.
And a general remark: you should always prefer to place such rules in the http servers host configuration instead of using dynamic configuration files (".htaccess"). Those dynamic configuration files add complexity, are often a cause of unexpected behavior, hard to debug and they really slow down the http server. They are only provided as a last option for situations where you do not have access to the real http servers host configuration (read: really cheap service providers) or for applications insisting on writing their own rules (which is an obvious security nightmare).

Apache mod_rewrite: URL slug not updating

There are a few SO questions about mod_rewrite such as here and here, but so far I cannot find one that works with my example.
I have an Apache webserver running my PHP website at the root var/www/html. at /var/www/html/news I have a .htaccess file which will be used to convert ugly $_GET filled url string into SEO friendly urls.
My current url looks like this:
https://mywebsite.com/news/article.php?id=2&title=myfirstarticle
I would like my url to look like this:
https://mywebsite.com/news/2/myfirstarticle
Here is my .htaccess file, currently redirecting to the indended url structure.
RewriteEngine on
RewriteRule ^([^/]*)/([^/]*)$ /article.php?id=$1&title=$2
So far my URL is not being changed to the SEO friendly URL, what am I missing?
You need to handle both directions: the external redirection and the internal rewriting:
RewriteEngine on
RewriteCond %{QUERY_STRING} (?:^|&)id=(\d+)&title=([^&]+)(?:&|$)
RewriteRule ^article.php$ /news/%1/%2 [R=301]
RewriteRule ^([^/]+)/([^/]+)$ /article.php?id=$1&title=$2 [END]
It is a good idea to start out with a 302 temporary redirection and only change that to a 301 permanent redirection later, once you are certain everything is correctly set up. That prevents caching issues while trying things out...
In case you receive an internal server error (http status 500) using the rule above then chances are that you operate a very old version of the apache http server. You will see a definite hint to an unsupported [END] flag in your http servers error log file in that case. You can either try to upgrade or use the older [L] flag, it probably will work the same in this situation, though that depends a bit on your setup.
This rule will work likewise in the http servers host configuration or inside a dynamic configuration file (".htaccess" file). Obviously the rewriting module needs to be loaded inside the http server and enabled in the http host. In case you use a dynamic configuration file you need to take care that it's interpretation is enabled at all in the host configuration and that it is located in the host's DOCUMENT_ROOT folder.
And a general remark: you should always prefer to place such rules in the http servers host configuration instead of using dynamic configuration files (".htaccess"). Those dynamic configuration files add complexity, are often a cause of unexpected behavior, hard to debug and they really slow down the http server. They are only provided as a last option for situations where you do not have access to the real http servers host configuration (read: really cheap service providers) or for applications insisting on writing their own rules (which is an obvious security nightmare).
Try the below htaccess rule:
RewriteEngine On
RewriteRule ^news/([^/]*)/([^/]*)$ /news/article.php?id=$1&title=$2

How to clean a url with php without using htaccess?

I have a problem with a project I'm doing with PHP and it's in the URLs.
When I load a script like index.php everything works fine, the problem is when I load a script that is located within two or more directories.
In the URL the scripts with the routes begin to be enmeshed
Here is an example of the problem I have
I need to load a script, even if it is in several levels of nesting, make its functionality and in the url is reflected as:
I need to have something like this
1:
I thank you in advance.
Regards
You can't use PHP to achieve this. PHP is not responsible for determining if PHP (let along a particular PHP script) will handle any given URL.
You have to configure your webserver to do it. Since you mention .htaccess but provide no further information about your server, I'm going to assume you are using Apache HTTPD.
For Apache, that means using mod_rewrite, Alias or something similar. You can put the configuration for those tools in .htaccess, but you don't want to and the documentation advises not to use them.
So put your mod_rewrite or Alias configuration in the main Apache configuration.
You're going to need an htaccess rule no matter what. However, it doesn't have to be a mod_rewrite rule. The reason you need this rule is because PHP is not responsible for the routing - it is merely responsible for the execution of your script.
The point of the rule is to direct apache and instruct it to execute the right script (in your case, script32.php) while keeping the request uri as intact as possible.
There are two ways around it, basically.
Way 1 (cleaner): mod_rewrite
This is pretty straightforward, the set of rules you need are as follows:
# If the requested file name is a valid file/inode
RewriteCond %{REQUEST_FILENAME} -f [OR]
# ...or a directory
RewriteCond %{REQUEST_FILENAME} -d
# ...then throw them straight on it
RewriteRule (.*) - [L]
# ...otherwise, redirect to script32.php with the full content of the request in query string
RewriteRule (.*) /welcome/script32.php?$1 [L]
The requested URL is now in $_SERVER['QUERY_STRING'] and you can now do whatever you like with it in PHP
Way 2: catchall
This does not rely on mod_rewrite and may therefore be slightly faster. However, technically, it's a cheap hack. The way around it is as follows:
ErrorDocument 404 /welcome/script32.php
The requested URL can now be found in $_SERVER['REQUEST_URI'] and is available for parsing in PHP. However, with this, you've also disabled "legit" 404 errors from being generated through apache - and should make sure to obey proper behaviour in PHP to compensate.

Use slash with get request

I'm in the process of working on an error system for my site (i.e., if MySQL encounters an error, it sends them to an error page). I'm wondering, is it possible to use a "/" instead of "?err=" for a URL?
What I'd like to do is have people sent to the url "/error/404/" but display on page the content at url "/error?err=404". Is there a way to do this with HTAccess, or something of the sort?
My current way is with lots of files and iframes, and it gets really annoying when you have to update one tiny little thing.
Thanks!
What you are looking for is url rewriting. You can set it up using an .htaccess file, given that your installation of apache has mod_rewrite enabled (if not, check this question).
Here is a nice tutorial on how to do it.
Have a try with this:
RewriteEngine on
RewriteRule ^error/(\d+)$ error?err=$1 [L,QSA]
This should not end in a redirection loop, since this requires a trailing number in the URI.
Note that I removed your leading slashes from both the pattern and the result. .htaccess style files work on relative paths.
In general you should always prefer to place such rules inside your http servers host configuration instead of using .htaccess style files. Those files are notoriously error prone, hard to debug and the really slow the server down. They are only available as a last option for users who do not have access to the host configuration, for example when using a cheap hosting provider.

POST request to SEO URL Forbidden

I have a basic MVC system that is sending POST data to URLs such as
admin/product/add/
But this is giving me an error
Forbidden
You don't have permission to access
/admin/product/add/ on this server.
Additionally, a 404 Not Found error was encountered while trying to
use an ErrorDocument to handle the request.
The RewriteRule is simply
RewriteRule ^(.*)/$ index.php?uri=$1
Last time I saw this on a server changing file/directory permissions to 755 seemed to fix it but not this time. I have never really understood the reason for the error so was hoping someone may be able to provide some more information?
You have 2 errors:
You don't have permission to access /admin/product/add/ on this server.
Additionally, a 404 Not Found error was encountered while trying to use an ErrorDocument to handle the request.
The 2nd one is quite certainly a consequence of the same bug. You may have something in your apache configuration which remove 404 errors from default http server handling and push it to your php application, if this php application was working we would have a nice 404, but...
The first one tells you your php application is not running at all.
So. This first error tell us that apache did try to directly access the directory /path/to/documentroot/admin/product/add/ on your server and to produce a listing of it (well a listing of the directory content would be done only if apache were authorized to do so). But of course this is not a real directory on your server. It is a virtual path in your application. So apache ends up with a 404 (which leads to error 2).
The application handles a virtual path, apache does not manage it. The RewriteRule job is to catch the requested path before apache is trying to serve it and give it to one single php file (index.php) as a query string argument.
So... this rewrite rule was not applied. Things that could prevent this rule to be applied are numerous:
mod_rewrite not activated: is the module present and enabled (RewriteEngine on)?
syntax error: mod rewrite syntax is quite hard to read, sometimes really complex. But here it seems quite simple.
The RewriteRule resulting file is maybe not a valid target for apache. If the index.php file is not present in the DocumentRoot, or not readable by the apache user, then apache will fail. Warning: having a file readable by the apache user means having read rights on the file but also execution rights on all parents directories for the apache user. This is where your classical chmod/chown solutions are fixing the problems.
The rule must be in a valid configuration file. Is this rule in a an apache configuration file, inside a Location or Directory section? Or maybe in the global scope -- this may alter the rewrite Rule syntax--. Or is it in a .htaccess file? If it's a .htacces does apache reads the .htacces files and are mod-rewrite instructions allowed there (AllowOverride None). Isn't there others .htaccess files taking precedence?
So to fix the problem:
If you have an apache version greater than 2.2.16 you can replace the RewriteRule by FallbackRessource /index.php to check that this does not come from a mod-rewrite problem.
try to directly request index.php, so that at least a direct request to this file does work
try to directly access a valid ressource on the documentRoot (a txt file, an image, something that should not be handled by the rewrite but directly served)
check that if any of your virtual paths could map real physical paths Apache is not trying to serve the physical one (like when you write a RewriteCond %{REQUEST_FILENAME}-d) but really push the path to index.php
check apache error logs.
debug mod_rewrite with RewriteLog and RewriteLogLevel
collect facts, settings and tests, and then push that to SO or Servfault.
So the problem is quite simple: the php application is not receiving the request. But there are a very big number of ways to end in this state. The message in itself is not very important. The only way to find the error is to check all parameters (or to have years of bug fixing experience and developing a pre-cognitive intuition organ for lamp bugs -- usually a beard --, like admins). And the only way for us to help you is to find strange facts in a big list of configuration details, this is why good questions contains a lot of informations, even if all theses informations looks simply "classical" for you.
EDIT
To clarify the problem you should edit your answer, track the POST requests with tools such as Chrome developpers tools or firebug (keep the network tracking in record mode to catch several POSTS) or try to replay the post with Live HTTP headers reply. You should try to isolate the problematic POST and give us details. Debug is not magical.
Now I know one magical random POST failure. It's the empty GET url bug. It could be that (or not). If you have one empty GET url hidden somewhere (<IMG SRC="">, url() in css, or an empty LINK in headers for example. As theses hidden POST are defined in HTTP as "replay-the-request-which-launched-the-source-page, and some browsers even replay the POST that gives you the page if they found one. This could lead to broken hidden POSTS.
It could be also that the POST is not sent to the right server. Hard to say. So please collect informations from your comments, add some more network analysis and edit the question which is now really containing not enough facts.
Try this:
RewriteCond %{REQUEST_METHOD} =POST
RewriteRule ^(.*)/$ index.php?uri=$1
Use this:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php?uri=$1 [L]
Also use only www or non-www domain but not both at the same time. Redirect users with htaccess where you would like like to...
NonWWW to WWW:
RewriteCond %{HTTP_HOST} !^www\.(.*)$ [NC]
RewriteRule ^(.*)$ http://www.%{HTTP_HOST}/$1 [R=301,L]
WWW to NonWWW:
RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
RewriteRule ^www\.(.*)$ http://%1/$1 [R=301,L]

Categories