Search code examples
wordpress.htaccessuploadhttp-status-code-404urlencode

Images with URL encoded characters in WordPress uploads folder returning 404s


I have a lot of images in my WordPress uploads folder. Most of these images display just fine. However, any images that have URL encoded characters in their filenames (e.g., %22 instead of ") return a 404 when I try to access them via a web browser. I've verified that those image files exist on the server by connecting via FTP, downloading one of the offending images, and opening it on my computer.

I imagine this could be a .htaccess issue, but .htaccess is inscrutable to me. Here's the .htaccess in the root of my site:

# BEGIN rlrssslReallySimpleSSL rsssl_version[3.3.5]
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{HTTPS} !=on [NC]
RewriteCond %{REQUEST_URI} !^/\.well-known/acme-challenge/
RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R=301,L]
</IfModule>
# END rlrssslReallySimpleSSL
# BEGIN WordPress
# The directives (lines) between "BEGIN WordPress" and "END WordPress" are
# dynamically generated, and should only be modified via WordPress filters.
# Any changes to the directives between these markers will be overwritten.
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>

# END WordPress

# Wordfence WAF
<Files ".user.ini">
<IfModule mod_authz_core.c>
    Require all denied
</IfModule>
<IfModule !mod_authz_core.c>
    Order deny,allow
    Deny from all
</IfModule>
</Files>

# END Wordfence WAF

Here's the .htaccess file in my /wp-content/uploads/ folder:

# BEGIN Wordfence code execution protection
<IfModule mod_php5.c>
php_flag engine 0
</IfModule>
<IfModule mod_php7.c>
php_flag engine 0
</IfModule>
<IfModule mod_php.c>
php_flag engine 0
</IfModule>

AddHandler cgi-script .php .phtml .php3 .pl .py .jsp .asp .htm .shtml .sh .cgi
Options -ExecCGI
# END Wordfence code execution protection

There are no other .htaccess files along the path to my images. I feel like I'm going crazy, but I'm likely missing something obvious.


Solution

  • This would seem to be a URL encoding issue on the initial HTTP request from the client, not related to your .htaccess file. If the actual filenames contain %22 then that needs to be URL encoded as %2522 (ie. the % in %22 needs to also be %-encoded) in the request, otherwise, it's going to look for a file containing ", not %22 (when the requested URL is decoded).

    This isn't a problem with your .htaccess file, although you could potentially resolve this with the help of .htaccess (to manually URL encode these requests), but only if you are unable to "fix" the requested URLs in the HTML source. Fixing these URLs at source would be the preferred solution.

    Needless to say, avoiding special characters in the filename in the first place (ie. sanitizing uploaded filenames) would be preferred. The double quote (") is an invalid char in Windows OS filenames, so that may be why it's remained %-encoded in the filename? But otherwise, %-encoded chars have no place in filenames, since this is a URL encoding scheme.