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.
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.