why does .htaccess rewrite behave differently based on form content?

Tags: , , ,



I am doing a post transaction with “having x,” in the form field being submitted. My .htaccess is ensuring https: and www. My redirect is changing the post to a get for the previously mentioned data. If I change pretty much anything it redirects the post just fine.

What I’m looking for is for it to act like test 2, in other words forward as a post transaction with the associated post data. It seems really odd that the content of the form could affect the behavior of the rewriting. Any ideas are very welcome. Thanks!


EDIT: Per the accepted answer below, this was the host running mod-security to guard against sql injection attacks. I could have asked them to turn it off, but decided to leave it and just check $_SERVER[‘REDIRECT-STATUS’] for a ‘403’ in order to respond with an appropriate message.


Here is the code for my test, which I invoke with /test uri to get the form.

<?php
$uri = $_SERVER['REQUEST_URI'];

if ($uri == '/test') {
?>
<html>
<head>

</head>
<body>
    <form 
        name="testForm" 
        method="post" 
        action="/testpost">

    <input type="text" 
           name="testName"
           value="having x,"/>

    <input type="submit" name="submit" id="submit" value="test" />

    </form> 
</body>    
</html>
<?php
} elseif ($uri == '/testpost') {
echo '<pre>';
var_dump($_POST);
var_dump($_SERVER);
} 

And here are the tests, showing the $_POST data and the relevant portions of $_SERVER:

Test 1 having x,

array(0) {
}
array(56) {
  ["CONTENT_TYPE"]=>
  string(33) "application/x-www-form-urlencoded"
  ["CONTENT_LENGTH"]=>
  string(2) "32"
  ["HTTP_USER_AGENT"]=>
  string(120) "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36"
  ["HTTP_X_FORWARDED_PROTO"]=>
  string(5) "https"
  ["HTTP_X_HTTPS"]=>
  string(2) "on"
  ["REDIRECT_REDIRECT_HTTPS"]=>
  string(2) "on"
  ["REDIRECT_REDIRECT_SERVER_PORT"]=>
  string(3) "443"
  ["REDIRECT_REDIRECT_REQUEST_METHOD"]=>
  string(4) "POST"
  ["REDIRECT_REDIRECT_STATUS"]=>
  string(3) "403"
  ["REDIRECT_HTTPS"]=>
  string(2) "on"
  ["REDIRECT_SERVER_PORT"]=>
  string(3) "443"
  ["REDIRECT_STATUS"]=>
  string(3) "403"
  ["HTTPS"]=>
  string(2) "on"
  ["SERVER_PORT"]=>
  string(3) "443"
  ["REQUEST_SCHEME"]=>
  string(5) "https"
  ["CONTEXT_PREFIX"]=>
  string(0) ""
  ["REMOTE_PORT"]=>
  string(5) "39916"
  ["REDIRECT_URL"]=>
  string(10) "/403.shtml"
  ["SERVER_PROTOCOL"]=>
  string(8) "HTTP/1.1"
  ["REQUEST_METHOD"]=>
  string(3) "GET"
  ["QUERY_STRING"]=>
  string(0) ""
  ["REQUEST_URI"]=>
  string(9) "/testpost"
  ["SCRIPT_NAME"]=>
  string(10) "/index.php"
  ["PHP_SELF"]=>
  string(10) "/index.php"
}

Test 2 havng x,

In test 2 notice the misspelling of having as havng

array(2) {
  ["testName"]=>
  string(8) "havng x,"
  ["submit"]=>
  string(4) "test"
}
array(51) {
  ["CONTENT_TYPE"]=>
  string(33) "application/x-www-form-urlencoded"
  ["CONTENT_LENGTH"]=>
  string(2) "31"
  ["HTTP_USER_AGENT"]=>
  string(120) "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36"
  ["HTTP_X_FORWARDED_PROTO"]=>
  string(5) "https"
  ["HTTP_X_HTTPS"]=>
  string(2) "on"
  ["REDIRECT_HTTPS"]=>
  string(2) "on"
  ["REDIRECT_SERVER_PORT"]=>
  string(3) "443"
  ["REDIRECT_STATUS"]=>
  string(3) "200"
  ["HTTPS"]=>
  string(2) "on"
  ["SERVER_PORT"]=>
  string(3) "443"
  ["REQUEST_SCHEME"]=>
  string(5) "https"
  ["CONTEXT_PREFIX"]=>
  string(0) ""
  ["REMOTE_PORT"]=>
  string(5) "42046"
  ["REDIRECT_URL"]=>
  string(9) "/testpost"
  ["SERVER_PROTOCOL"]=>
  string(8) "HTTP/1.1"
  ["REQUEST_METHOD"]=>
  string(4) "POST"
  ["QUERY_STRING"]=>
  string(0) ""
  ["REQUEST_URI"]=>
  string(9) "/testpost"
  ["SCRIPT_NAME"]=>
  string(10) "/index.php"
  ["PHP_SELF"]=>
  string(10) "/index.php"
}

It will also work with:

having x
having,
aving x,
having something else,
etc.

But will not work with

having something,
having somethingelse,

Here is the htaccess code:

Options +FollowSymLinks 
RewriteEngine on
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} ^www. [NC]
RewriteCond %{HTTP_HOST} ^(?:www.)?(.+)$ [NC]
RewriteRule ^ https://%1%{REQUEST_URI} [L,NE,R=301]
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L]
RewriteRule ^.*$ /index.php [NC,L]

Answer

Your host is blocking having x. It thinks this is a SQL injection attack on your server. You need to talk to your host if you want them to allow this.



Source: stackoverflow