Skip to content
GeneralAdvanced

How to Configure a Secure .htaccess File for PHP Websites: URL Routing, 410 Gone and Fake URL Blocking

The .htaccess file is an important configuration file used by Apache web servers. For PHP websites hosted on Apache-compatible hosting, it can control URL re...

BI
Bison Technical Team Enterprise IT specialists
Updated 07 Aug 2026 15 min read 0 total views

The .htaccess file is an important configuration file used by Apache web servers. For PHP websites hosted on Apache-compatible hosting, it can control URL rewriting, redirects, access rules, error handling and application routing without requiring direct access to the main Apache server configuration.

One common problem faced by website administrators is the appearance of strange or unwanted URLs such as:

Advertisement
https://www.example.com/?listing/184760400/
https://www.example.com/?listing/938472001/
https://www.example.com/?listing/123456789/

These URLs may appear after malware activity, automated bot scanning, an old CMS installation, incorrect rewrite rules, spam campaigns, abandoned plugins or previously compromised website files.

Even after the malicious or unwanted files have been removed, search engines may continue trying to crawl these URLs.

A properly configured .htaccess file can help by:

  • Blocking known unwanted URL patterns
  • Returning HTTP 410 Gone for permanently removed URLs
  • Preserving access to legitimate files and directories
  • Routing clean application URLs through index.php
  • Preventing unnecessary processing of invalid URLs

This article explains a practical .htaccess configuration and the reasoning behind each directive.


Recommended .htaccess Configuration

For a typical custom PHP website using index.php as its main router, the following configuration can be used:

RewriteEngine On
RewriteBase /

# Block fake / unwanted listing query URLs
# Example: https://www.example.com/?listing/184760400/
# Returns HTTP 410 Gone
RewriteCond %{QUERY_STRING} ^listing/ [NC]
RewriteRule ^ - [G,L]

# Allow index.php directly
RewriteRule ^index\.php$ - [L]

# Normal PHP routing
# Existing files and folders open normally
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]

Before implementing any .htaccess change on a production website, keep a backup of the existing file.


Understanding the Configuration

1. Enabling Apache RewriteEngine

The first directive is:

RewriteEngine On

This enables Apache's URL rewriting functionality provided through mod_rewrite.

Without this directive, subsequent RewriteCond and RewriteRule instructions will not operate as intended.


2. Setting RewriteBase

RewriteBase /

This establishes / as the base path for relative rewrite processing.

For a website installed directly inside the domain's document root, / is normally appropriate.

For example:

https://www.example.com/

If an application is installed in a subdirectory, its configuration may need to be adjusted.


3. Blocking Fake ?listing/... URLs

Consider unwanted URLs such as:

https://www.example.com/?listing/184760400/

The part following the question mark is the query string:

listing/184760400/

The following condition detects it:

RewriteCond %{QUERY_STRING} ^listing/ [NC]

Let's break this down.

%{QUERY_STRING}

This Apache variable contains everything appearing after ? in the requested URL.

For:

https://www.example.com/?listing/184760400/

the query string is:

listing/184760400/

^listing/

The ^ character means the value must start with the specified pattern.

Therefore:

listing/12345/

matches.

But something unrelated such as:

product=12345

does not match.

[NC]

NC means No Case or case-insensitive matching.

Consequently, variants such as these can also match:

listing/
Listing/
LISTING/
LiStInG/

4. Returning HTTP 410 Gone

The next rule is:

RewriteRule ^ - [G,L]

This is particularly important.

The G flag tells Apache that the requested resource is permanently Gone.

Apache therefore returns:

HTTP 410 Gone

The L flag means:

Last Rule

Apache stops processing additional rewrite rules for that request.


5. Why Use 410 Gone Instead of Redirecting Fake URLs?

Website owners sometimes redirect every invalid URL to the homepage.

For example:

/fake-page

might be redirected to:

/

This is not always a good strategy.

If a URL was generated by spam, malware or an unwanted script and should never exist again, returning:

410 Gone

provides a much clearer signal.

It effectively tells clients and search engines:

This resource previously may have existed, but it has been permanently removed and should not be expected to return.

For intentionally removed spam-generated URL patterns, this can be preferable to silently routing everything to the homepage.


6. 404 Not Found vs 410 Gone

Both HTTP responses indicate that the requested content isn't available, but their meanings differ.

HTTP 404 Not Found

A 404 means that the server cannot find the requested resource.

The server isn't explicitly stating whether the absence is temporary or permanent.

HTTP 410 Gone

A 410 explicitly indicates that the resource is gone and its removal is considered permanent.

For known fake or unwanted URLs that you deliberately want eliminated, 410 Gone is therefore a useful response.


7. Allowing index.php Directly

The next rule is:

RewriteRule ^index\.php$ - [L]

This tells Apache not to rewrite the request when the requested path is already:

index.php

The backslash before the period is important:

index\.php

In regular expressions, a plain . represents any character.

Therefore:

index.php

is less precise than:

index\.php

Escaping the period means that Apache matches the literal filename:

index.php

8. Checking Whether the Requested File Exists

The next condition is:

RewriteCond %{REQUEST_FILENAME} !-f

REQUEST_FILENAME represents the server-side path associated with the request.

The operator:

!-f

means:

Continue only if the requested path is NOT an existing regular file.

Suppose your website contains:

/css/style.css
/images/logo.png
/js/app.js
/contact.php

Apache should normally serve these files directly instead of routing them through the main application controller.


9. Checking Whether a Directory Exists

The next condition is:

RewriteCond %{REQUEST_FILENAME} !-d

The operator:

!-d

means:

Continue only when the requested path is NOT an existing directory.

This prevents valid physical directories from unnecessarily being rewritten.


10. Routing Non-Existing URLs to index.php

The final rule is:

RewriteRule . /index.php [L]

When the requested resource is neither an existing file nor an existing directory, Apache internally routes the request to:

/index.php

This is commonly known as a front-controller architecture.

It is used by many PHP applications and frameworks.


Example of How Requests Are Processed

Suppose the website receives:

https://www.example.com/contact.php

If contact.php physically exists, Apache serves it normally.

Now consider:

https://www.example.com/services/cloud-backup

If there is no physical file or directory with that path, the request is internally processed by:

/index.php

The PHP application can then decide what page to display.


What Happens to a Fake Listing URL?

Consider:

https://www.example.com/?listing/987654321/

Apache evaluates:

RewriteCond %{QUERY_STRING} ^listing/ [NC]

The query string matches.

Apache then executes:

RewriteRule ^ - [G,L]

and returns:

410 Gone

The request does not continue to the normal PHP routing section.


Correct Apache Variable Syntax

An important technical detail is the spelling of Apache variables.

Correct:

%{QUERY_STRING}
%{REQUEST_FILENAME}

Do not accidentally use formatting escapes copied from Markdown or another editor, such as:

QUERY\_STRING
REQUEST\_FILENAME

The actual .htaccess file should contain:

QUERY_STRING
REQUEST_FILENAME

without a backslash before the underscore.


Testing the Configuration

After installing the .htaccess file, test several categories of URLs.

Test 1: Homepage

Open:

https://www.example.com/

It should load normally.

Test 2: Existing PHP Page

Open something such as:

https://www.example.com/contact.php

It should continue working normally if the file exists.

Test 3: CSS and Images

Verify that resources such as:

https://www.example.com/css/style.css
https://www.example.com/images/logo.png

load correctly.

Test 4: Fake Listing URL

Test:

https://www.example.com/?listing/123456789/

The expected HTTP status should be:

410 Gone

Testing With cURL

On Windows, Linux or macOS, HTTP headers can be checked using cURL.

For the homepage:

curl -I "https://www.example.com/"

A healthy homepage normally returns:

HTTP/1.1 200 OK

Then test the unwanted URL:

curl -I "https://www.example.com/?listing/123456789/"

The expected result is:

HTTP/1.1 410 Gone

This confirms that the blocking rule is working.


What If the Homepage Returns 500 Internal Server Error?

If the website stops opening immediately after editing .htaccess, an Apache configuration or syntax problem may exist.

Temporarily rename:

.htaccess

to something such as:

.htaccess-backup

If the website starts working again, inspect the .htaccess directives and server compatibility.

Do not simply leave the file disabled without determining why the error occurred.


.htaccess and Malware: Important Distinction

A clean .htaccess file does not prove that a website is malware-free.

Attackers sometimes modify .htaccess, but malicious code can also exist in:

index.php
header.php
footer.php
config.php
includes/
uploads/
assets/
cache/
plugins/
themes/

or unexpected PHP files and randomly generated directories.

Therefore, if suspicious URLs appeared after a website compromise, checking .htaccess should be only one part of the security investigation.


Suspicious .htaccess Entries to Investigate

Website administrators should investigate unexpected directives involving:

Redirect
RedirectMatch
RewriteRule
RewriteCond
SetHandler
AddHandler
php_value
php_flag
auto_prepend_file
auto_append_file

These directives are not inherently malicious. Many legitimate applications use them.

The warning sign is when they appear unexpectedly or point toward unknown files, external domains or unusual scripts.

For example, an unexpected redirect to an unfamiliar external website deserves immediate investigation.


Watch for auto_prepend_file

A particularly important PHP configuration is:

auto_prepend_file

This feature can legitimately cause PHP to execute another file before the requested script.

Attackers can also abuse this behavior.

If you discover an unexpected auto_prepend_file directive referencing an unfamiliar PHP file, investigate both the directive and the referenced file.


Look for Unexpected PHP Execution Rules

Attackers may attempt to configure files with unusual extensions to execute as PHP.

Therefore, unexpected AddHandler, SetHandler or MIME-handler modifications should be investigated.

Again, these directives have legitimate uses, so context matters.


Search the Entire Hosting Account

If one PHP file has been compromised, don't assume that it is the only infected file.

Check:

  • Main website directory
  • Subdomains
  • Old website backups
  • Test installations
  • WordPress installations
  • Plugin directories
  • Theme directories
  • Upload folders
  • Temporary directories
  • Cache folders
  • Hidden files
  • Cron jobs
  • FTP/SFTP accounts
  • Hosting control-panel users

A compromised account can sometimes contain multiple backdoors.


Check Recently Modified PHP Files

One useful investigation technique is to identify PHP files modified around the approximate time of the compromise.

For example, if most legitimate website files are months old but several unfamiliar PHP files were modified yesterday, those files deserve investigation.

However, modification dates alone are not proof of infection because legitimate updates can also modify many files.


Search for Suspicious PHP Patterns

Security investigations commonly inspect unfamiliar PHP files for functions or patterns involving:

eval(
base64_decode(
gzinflate(
gzuncompress(
str_rot13(
shell_exec(
system(
exec(
passthru(

These functions are not automatically malware.

Legitimate applications can use some of them.

The concern is unexpected combinations, heavy obfuscation, encoded payloads, dynamically generated code or code that clearly does not belong to the application.


Don't Delete Files Based Only on Function Names

For example:

base64_decode()

has legitimate uses.

Similarly:

exec()

can be used by legitimate software.

Therefore, the presence of one function should trigger investigation rather than automatic deletion.

Use file location, purpose, modification time, code structure and known-good application files to make the determination.


Check for Randomly Named Directories

Unexpected directory structures such as:

/assets/847293/928374/293847/
/includes/593827/
/cache/283746/

can deserve investigation when your application normally does not generate such directories.

If these folders contain unfamiliar index.php files or heavily obfuscated PHP code, treat them as suspicious until verified.


Never Format or Delete the Whole Website Immediately

When malware is suspected, first preserve a backup for investigation.

Then determine:

  1. Which files were modified?
  2. How did the attacker gain access?
  3. Are additional backdoors present?
  4. Were credentials compromised?
  5. Is an outdated CMS, plugin or script responsible?
  6. Are there unauthorized FTP/SFTP accounts?
  7. Are scheduled tasks recreating the malicious files?

Simply deleting one visible malicious file may not eliminate the original entry point.


Change Hosting Credentials After a Compromise

After cleaning a compromised website, consider changing:

  • Hosting control-panel password
  • FTP/SFTP passwords
  • SSH credentials
  • Database passwords
  • CMS administrator passwords
  • Application administrator passwords
  • Email credentials associated with hosting administration
  • API keys where exposure is possible

Enable multi-factor authentication where the hosting provider supports it.


Update the Website Software

For CMS-based websites, update:

  • Core CMS
  • Themes
  • Plugins
  • Extensions
  • PHP version where appropriate

Remove abandoned components rather than simply disabling them if they are no longer required.

For custom PHP applications, review third-party libraries and dependencies as well.


File Permissions

Overly permissive file permissions can increase security risk.

Common configurations often use permissions similar to:

Files:       644
Directories: 755

However, the correct permissions depend on the hosting platform, application and server configuration.

Avoid using:

777

unless there is a specific, justified requirement and you understand the security implications.


Search Engine Cleanup After a Compromise

After malware or spam URLs are removed, search engines may continue showing or crawling them for some time.

A cleanup strategy can include:

  1. Remove malicious files and the original vulnerability.
  2. Return the appropriate HTTP status for invalid URLs.
  3. Use 410 Gone for known URL patterns that were intentionally and permanently removed.
  4. Maintain 200 OK for legitimate pages.
  5. Maintain proper 404 Not Found behavior for ordinary missing pages.
  6. Check the website in the relevant webmaster/search-console tools.
  7. Request validation or review where appropriate.
  8. Continue monitoring server logs.

Search engine cleanup is normally not instantaneous.


Do Not Block Every Unknown Query String

A website may legitimately use query strings such as:

?search=laptop
?page=2
?id=125
?category=cloud

Therefore, a rule such as:

RewriteCond %{QUERY_STRING} ^listing/ [NC]

is deliberately targeted.

It blocks only the known unwanted pattern rather than every URL containing a query string.


Why Targeted Rules Are Better

A broad blocking rule can accidentally break:

  • Search functionality
  • Pagination
  • Login links
  • Tracking parameters
  • Product filters
  • Form submissions
  • API requests
  • Payment gateway callbacks
  • Password-reset links

For this reason, .htaccess security rules should be as specific as practical.


Production Checklist

Before deploying the configuration, verify:

  • A backup of the previous .htaccess exists.
  • Apache mod_rewrite is available.
  • Homepage returns 200 OK.
  • Existing PHP pages work.
  • CSS loads correctly.
  • JavaScript loads correctly.
  • Images load correctly.
  • Existing directories remain accessible as intended.
  • Application routing works.
  • Known fake listing URLs return 410 Gone.
  • No unexpected redirects occur.
  • No 500 Internal Server Error appears.
  • Server error logs are checked after deployment.

Final Recommended Configuration

For quick reference:

RewriteEngine On
RewriteBase /

# Block fake / unwanted listing query URLs
RewriteCond %{QUERY_STRING} ^listing/ [NC]
RewriteRule ^ - [G,L]

# Allow index.php directly
RewriteRule ^index\.php$ - [L]

# Normal PHP routing
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]

This configuration provides a simple combination of targeted unwanted-URL blocking and normal PHP front-controller routing.


Frequently Asked Questions (FAQ)

1. What is an .htaccess file?

.htaccess is a per-directory Apache configuration file that can control rewriting, redirects, access rules and other supported server behaviors.

2. Is .htaccess a PHP file?

No. It is an Apache configuration file.

3. What does RewriteEngine On do?

It enables Apache rewrite processing for the applicable configuration context.

4. What is QUERY_STRING?

It contains the portion of a URL appearing after the ?.

For:

https://example.com/?listing/123/

the query string is:

listing/123/

5. What does [NC] mean?

It means No Case, making the rule's matching case-insensitive.

6. What does [L] mean?

It indicates that rewrite processing should stop at that rule for the current rewrite pass.

7. What does [G] mean?

It marks the requested resource as gone and produces an HTTP 410 Gone response.

8. What is HTTP 410 Gone?

It indicates that the requested resource is intentionally and permanently unavailable.

9. Is 410 the same as 404?

No. A 404 means the resource was not found, while 410 more explicitly communicates permanent removal.

10. Should all 404 pages return 410?

No. Use 410 when you intentionally know that particular content or URL pattern has been permanently removed.

11. Can 410 help remove spam URLs from search engines?

It provides a clear permanent-removal signal for those URLs. Search engines may still take time to recrawl and update their indexes.

12. Why shouldn't fake URLs simply redirect to the homepage?

Redirecting unrelated invalid URLs to the homepage can hide the fact that the requested resource doesn't exist. Returning an appropriate error status is usually cleaner.

13. What does !-f mean?

It means that the requested path is not an existing regular file.

14. What does !-d mean?

It means that the requested path is not an existing directory.

15. Why route requests through index.php?

This allows a PHP application to centrally process virtual or clean URLs using a front-controller design.

16. Will existing images be routed through index.php?

Not with the shown conditions, provided those image files physically exist.

17. Will CSS files continue working?

Yes, provided the CSS files exist and the surrounding server configuration is correct.

18. Why write index.php instead of index.php?

Because . is a special regular-expression character. \. explicitly matches a literal period.

19. Can an incorrect .htaccess break a website?

Yes. Invalid or unsupported directives can result in a 500 Internal Server Error or incorrect routing.

20. Should I back up .htaccess before editing it?

Yes. Always preserve the working configuration before making production changes.

21. Can malware modify .htaccess?

Yes. Attackers sometimes modify .htaccess to create redirects, alter handlers or manipulate requests.

22. Does a clean .htaccess prove the website is clean?

No. Malware can exist elsewhere in PHP files, plugins, themes, uploads, scheduled tasks or other account locations.

23. Should I delete every PHP file containing base64_decode?

No. Investigate the context. The function itself is not proof of malware.

24. What should I do if malicious files return after deletion?

Assume the underlying vulnerability or another backdoor may still exist. Investigate scheduled tasks, credentials, CMS components and other files.

25. Should I change passwords after website malware infection?

Generally, yes. Credentials potentially exposed during a compromise should be rotated.

26. Can .htaccess protect an entire website from hackers?

No. It can contribute to security but cannot replace secure application code, updates, strong authentication, monitoring and server security.

27. How can I check the HTTP status of a URL?

Use a browser developer tool, an HTTP status checker or:

curl -I "https://www.example.com/"

28. What status should a healthy homepage normally return?

Normally:

200 OK

29. What should a blocked fake listing URL return in this configuration?

410 Gone

30. Can I use this configuration on Nginx?

No. Nginx does not use .htaccess; equivalent rules must be configured in Nginx configuration files.

Conclusion

A well-designed .htaccess configuration can solve two different problems at the same time: normal PHP application routing and targeted handling of unwanted URLs.

For known fake URLs such as:

?listing/123456789/

returning 410 Gone can clearly indicate that these URLs are permanently unavailable, while the REQUEST_FILENAME checks allow legitimate physical files and directories to continue working normally.

Most importantly, .htaccess cleanup should not be treated as complete malware remediation. If fake URLs appeared because a website was compromised, administrators should investigate PHP files, credentials, CMS components, scheduled tasks, hidden files, old installations and other possible persistence mechanisms.

The safest approach is to clean the infection, close the original vulnerability, return correct HTTP responses for unwanted URLs, and continue monitoring the website afterward.

 

#Htaccess #Apache #PHP #PHPSecurity #WebsiteSecurity #CyberSecurity #WebSecurity #ModRewrite #RewriteRule #RewriteCond #URLRewriting #HTTP410 #410Gone #HTTP404 #WebsiteMalware #MalwareCleanup #PHPDeveloper #WebDeveloper #ApacheServer #WebHosting #SharedHosting #WebsiteHacked #HackedWebsite #MalwareRemoval #SpamURLs #FakeURLs #SEO #TechnicalSEO #SearchEngineOptimization #SearchConsole #WebsiteRecovery #PHPWebsite #WebDevelopment #ServerSecurity #SecurityAudit #WebsiteProtection #CyberAttack #PHPBackdoor #WebShell #MaliciousCode #WebsiteAdministrator #SystemAdministrator #ITSecurity #HostingSecurity #ApacheSecurity #URLRouting #FrontController #WebsiteMaintenance #TechSupport #SecurityBestPractices

YOUR FEEDBACK

Was this guide useful?

Your answer helps us keep BISONKB accurate and practical.

BISON AI

Ask about “How to Configure a Secure .htaccess File for PHP Websites: URL Routing, 410 Gone and Fake URL Blocking”

This interface is ready to connect to your preferred AI provider. No article or user data is sent until that service is configured.

THE BISON BRIEF

Practical IT knowledge, once a week.

New troubleshooting guides, scripts and infrastructure notes. No noise.

By subscribing, you agree to our privacy policy.