1

My site used to have a SEO hack. Although I have reinstalled the website, the attacker is still trying to access these URLs via Google or direct:

/404.html?page=/wp-content/uploads/2020/03/...
/wp-content/uploads/2020/03/...

How to block these accesses? For the /wp-content/uploads/2020/03/... one I can create a .htaccess file in the folder with Deny from all, but what about the 404 page? I read the .htaccess Cheat Sheet but find no result there.

  • 3
    Presumably that URL would return a 404 Not Found status. If so, that is already good enough for SEO. Google will not index that URL. – Stephen Ostermiller May 31 at 12:02
3
/404.html?page=/wp-content/uploads/2020/03/...

I assume the ... is "anything that follows". To block this URL, you could use mod_rewrite in your root .htaccess file. But you need to use a condition (RewriteCond directive) to match the query string.

The RewriteRule pattern matches against the URL-path only (less the directory prefix), ie. 404.html. To match the query string (ie. page=/wp-content/uploads/2020/03/...) you need to use a RewriteCond directive and match against the QUERY_STRING server variable.

For example, at the top of your root .htaccess file (before any other WordPress directives):

RewriteCond %{QUERY_STRING} ^page=/wp-content/uploads/2020/03/
RewriteRule ^404\.html$ - [F]

This matches the exact URL /404.html?page=/wp-content/uploads/2020/03/, followed by anything. Note the absence of the slash prefix in the RewriteRule pattern.

The F flag triggers an immediate 403 Forbidden response. The L flag is not required here.

(You don't need to repeat the RewriteEngine On directive, if it is already present in the WordPress section of the .htaccess file, even if this appears later in the file.)

If you need to be more general and match the page URL parameter anywhere in the query string, and allow for variations in case then you could modify the above directive like so:

RewriteCond %{QUERY_STRING} (^|&)page=/wp-content/uploads/2020/03/ [NC]
RewriteRule ^404\.html$ - [NC,F]

To match /wp-content/uploads/2020/03/... as well, a separate rule is required. For example:

RewriteRule ^wp-content/uploads/2020/03/ - [F]

(Or use mod_auth... blocking directives in the respective directory - as you mention - but note that Deny from all is an Apache 2.2 directive. If you are on Apache 2.4+ you should be using Require all denied instead.)


Aside:

I read the .htaccess Cheat Sheet but find no result there.

Yes, there doesn't appear to be any mention of matching against the query string portion of the URL in the .htaccess "cheat sheet". (A common requirement and source of error. eg here, here and here)

You would use the same method (ie. RewriteCond w/ QUERY_STRING server variable) for redirects and rewrites (eg. "clean URLs").


UPDATE:

Stephen: Presumably that URL would return a 404 Not Found status ...

Must admit, I kinda overlooked this! If one (or even both) of these URLs are already returning a 404 then there is really nothing more you need to do in terms of SEO. The difference is just a 403 ("blocked") or 404 (not found) response. Neither of which will be indexed by search engines (over time any previously indexed URLs will drop from the SERPs).

The only thought (with this being WordPress/CMS) is that these 404s would be processed by WordPress, which could potentially put an increased load on the server if these URLs are being hammered. In this case it might be preferable to handle this in .htaccess (or preferably your server config).

Instead of returning a "403 Forbidden", you could instead return a "404 Not Found", by changing the F flag in the above directives to R=404. Note that this will return Apache's 404 response, not WordPress.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.