skip to Main Content

After apache update, my server started dropping this error in URL queries, containing spaces:

AH10411: Rewritten query string contains control characters or spaces

URL looks as follows:

www.example.com/modulename/searchfuncname/filter,searchstring,quick fox jumps/

.htaccess as follows:

<IfModule mod_rewrite.c>
RewriteEngine On

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)$ index.php?QueryString=%{REQUEST_URI} [B,L]
</IfModule>

I tried adding B flag, removing B flag, adding BNP flag and combinations of both or none.

Nothing helped. With any URL provided, server drops the very same error.

When I try to manually replace spaces with %20:
www.example.com/modulename/searchfuncname/filter,searchstring,quick%20fox%20jumps/
server replaces them back, gives 403 responce and drops AH10411 error.

But for some reason, if I replace space with + sign, server works. Disregarding BPN flag.

I tried all the variants, described in this thread:
AH10411 error: Managing spaces and %20 in apache mod_rewrite
none worked.

2

Answers


  1. RewriteRule ^(.+)$ index.php?QueryString=%{REQUEST_URI} [B,L]
    

    The B flag doesn’t work here because you are not using a backreference (you are using the REQUEST_URI server variable instead). Try the following instead:

    RewriteRule ^(.+)$ index.php?QueryString=/$1 [B,L]
    

    When I try to manually replace spaces with "%20": /modulename/searchfuncname/filter,searchstring,quick%20fox%20jumps/ server replaces them back

    This would make no difference, because this is identical to the first request. If you don’t explicitly URL-encode the spaces in the initial request, the browser does this for you (when it makes the request) – in order to make a valid URL. (Look at the network traffic in the browser – you will see %20 regardless of whether you have manually encoded the space or not).

    But yes, the RewriteRule pattern matches the URL-decoded URL-path anyway.

    But for some reason, if I replace space with "+" sign, server works. Disregarding BPN flag.

    %20 is a URL-encoded space, regardless of where it is used in the URL. However, a + in the URL-path is a literal + (plus). But, a + in the query string is a URL-encoded space (alternative encoding). So, yes, if you used + in the URL-path of the original request then it "bypasses" this problem. The BNP flag does not apply, since it is not encoding a space, it is simply copying a literal +.


    UPDATE: Limit what is encoded

    $_GET now doesn’t break into array if URL is provided with addditional parameters like /fox/&tail=red

    Probably because the & is being URL-encoded in the resulting query string. You can limit the encoding to spaces and ? only (requires Apache 2.4.26+). For example:

    RewriteRule ^(.+)$ index.php?QueryString=/$1 "[B= ?,L]"
    

    & will no longer be encoded in the backreference, so its special meaning in the query string will still apply.

    NB: You can’t encode only spaces (since spaces can’t be used as the last character), hence the additional ? character. Consequently, the flags argument needs to be surrounded in double quotes.

    Login or Signup to reply.
  2. I had the same and due to circumstances I found the easy way:

    #
    # php-fpm can use .user.ini instead of .htaccess
    #
    <Files ".user.ini">
        Require all denied
    </Files>
    <IfModule mod_rewrite.c>
        RewriteEngine On
        RewriteOptions AllowAnyURI
        #
        # Authorization header for JWT backend
        #
        SetEnvIf Authorization .+ HTTP_AUTHORIZATION=$0
    
        #
        # Don't rewrite if dir/link/file exists
        #
        RewriteCond %{REQUEST_FILENAME} -f [OR]
        RewriteCond %{REQUEST_FILENAME} -d
        RewriteRule .* - [L]
    
        #
        # Handle in route class...
        #
        RewriteCond %{HTTPS} off
        RewriteRule .* - [E=REQUEST_SCHEME:http]
    
        RewriteCond %{HTTPS} on
        RewriteRule .* - [E=REQUEST_SCHEME:https]
    
        RewriteRule ^/?(.*)$ /index.php?request=- [L,QSA]
    </IfModule>
    

    basically it is this setting: RewriteOptions AllowAnyURI

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search