Wat is .htaccess?
Het .htaccess bestand (HyperText Access) is een configuratiebestand voor Apache webservers. Het bevindt zich in de root van je WordPress installatie en bepaalt hoe de server omgaat met verzoeken naar je website.
In tegenstelling tot security plugins, werkt .htaccess op server-niveau. Dit betekent dat kwaadaardige verzoeken worden geblokkeerd voordat ze WordPress bereiken - een veel effectievere aanpak.
Kenmerken van .htaccess:
- Server-level: Blokkeert aanvallen voordat PHP wordt uitgevoerd
- Geen overhead: Geen extra database queries of PHP processing
- Onmiddellijk actief: Wijzigingen zijn direct van kracht
- Plugin-vrij: Geen compatibility issues of updates nodig
Waarom .htaccess voor beveiliging?
Security plugins zoals Wordfence of Sucuri zijn nuttig, maar ze hebben een fundamenteel nadeel: ze werken binnen WordPress. Dit betekent dat kwaadaardige code al gedeeltelijk is uitgevoerd voordat de plugin kan ingrijpen.
Met .htaccess beveiliging blokkeer je aanvallen op het laagste niveau - de webserver zelf. Dit heeft meerdere voordelen:
- Snellere respons: Geen PHP of WordPress overhead bij geblokkeerde verzoeken
- Minder serverbelasting: Geblokkeerde bots verbruiken minimale resources
- Betere bescherming: Sommige aanvallen kunnen alleen op server-niveau worden gestopt
- Geen updates nodig: De regels blijven werken ongeacht WordPress versie
Regel 1: Server Hygiene
De eerste stap is het verbergen van server-informatie die hackers kunnen gebruiken om kwetsbaarheden te vinden.
# Server hygiene
ServerSignature Off
Options -Indexes
Wat doet dit?
ServerSignature Off- Verbergt Apache versie-informatie in error pagesOptions -Indexes- Voorkomt dat mappen zonder index.php hun inhoud tonen
Zonder deze regels kan een hacker eenvoudig zien welke Apache versie je draait en welke bestanden in je mappen staan. Dit is waardevolle informatie voor gerichte aanvallen.
Regel 2: WordPress Permalinks
Deze standaard WordPress regels zorgen voor mooie URLs (pretty permalinks). Ze zijn essentieel voor de werking van je website.
# WordPress permalinks
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
Deze regels sturen alle verzoeken naar index.php tenzij het een bestaand bestand of map betreft. WordPress handelt vervolgens de routing af.
Regel 3: Kritieke Bestanden Blokkeren
Sommige bestanden bevatten gevoelige informatie en mogen nooit toegankelijk zijn via de browser.
# Blokkeer kritieke bestanden
<FilesMatch "(^\.|wp-config\.php|readme\.html|license\.txt|install\.php)">
Require all denied
</FilesMatch>
Geblokkeerde bestanden:
^\.- Alle bestanden die beginnen met een punt (.htaccess, .git, etc.)wp-config.php- Bevat database credentials en secret keysreadme.html- Onthult WordPress versielicense.txt- Onthult WordPress versieinstall.php- Kan gebruikt worden voor re-installatie aanvallen
wp-config.php bestand bevat je database wachtwoord en authenticatie keys. Als dit bestand ooit gelekt wordt, moet je onmiddellijk alle credentials wijzigen.
Regel 4: Uploads Map Beveiligen
De uploads map (wp-content/uploads) is een populair doelwit voor hackers. Ze proberen vaak PHP backdoors te uploaden via kwetsbare plugins.
# Uploads = NO PHP
<FilesMatch "^wp-content/uploads/.*\.(php|phtml|php3|php4|php5|phps)$">
Require all denied
</FilesMatch>
Deze regel voorkomt dat PHP bestanden in de uploads map kunnen worden uitgevoerd. Zelfs als een hacker erin slaagt een PHP bestand te uploaden, kan het niet worden geactiveerd.
Regel 5: wp-includes Afschermen
De wp-includes map bevat WordPress core bestanden. Directe toegang tot deze bestanden is vrijwel nooit nodig en kan worden misbruikt.
# wp-includes afschermen
<IfModule mod_rewrite.c>
RewriteRule ^wp-includes/.*\.php$ - [F,L]
RewriteRule ^wp-includes/js/tinymce/langs/.*\.php$ - [F,L]
RewriteRule ^wp-includes/theme-compat/ - [F,L]
</IfModule>
Dit blokkeert directe PHP requests naar wp-includes, behalve wanneer ze via WordPress zelf worden aangeroepen. De [F,L] flags betekenen "Forbidden" en "Last rule".
Regel 6: XML-RPC Blokkeren
XML-RPC is een verouderd protocol dat WordPress gebruikt voor externe communicatie. Het wordt zelden nog gebruikt maar is een populair doelwit voor brute-force aanvallen.
# XML-RPC blokkeren
<Files xmlrpc.php>
Require all denied
</Files>
Regel 7: wp-login.php IP-Restrictie
De login pagina is het meest aangevallen onderdeel van WordPress. Door alleen specifieke IP-adressen toe te staan, blokkeer je vrijwel alle brute-force aanvallen.
# wp-login.php IP-restrictie
<Files wp-login.php>
Require all denied
# Vervang met je eigen IP(s)
Require ip 123.123.123.123
Require ip 111.111.111.111
</Files>
123.123.123.123 met je eigen IP-adres. Je kunt je huidige IP vinden op whatismyipaddress.com. Als je een dynamisch IP hebt, overweeg dan een VPN met vast IP.
Regel 8: wp-admin Afschermen
Naast de login pagina moet ook de hele admin map worden afgeschermd voor ongeautoriseerde IP-adressen.
# wp-admin afschermen (rewrite-based)
<IfModule mod_rewrite.c>
RewriteCond %{REQUEST_URI} ^/wp-admin
RewriteCond %{REMOTE_ADDR} !^123\.123\.123\.123$
RewriteCond %{REMOTE_ADDR} !^111\.111\.111\.111$
RewriteRule .* - [F,L]
</IfModule>
Let op de escape characters (\.) voor de punten in het IP-adres. Regex behandelt een punt als "elk karakter", dus we moeten ze escapen voor letterlijke matching.
Regel 9: Backup Bestanden Blokkeren
Ontwikkelaars laten soms per ongeluk backup bestanden achter. Deze kunnen gevoelige informatie bevatten zoals database dumps of oude configuraties.
# Blokkeer back-up / lekbestanden
RedirectMatch 403 (\.bak|\.old|\.sql|\.log|\.ini|\.env|\.git)
Geblokkeerde extensies:
.baken.old- Backup bestanden.sql- Database dumps.log- Log bestanden met mogelijke gevoelige data.ini- Configuratie bestanden.env- Environment variabelen (vaak met credentials).git- Git repository data
Regel 10: Script Kiddies en Bots Blokkeren
Veel geautomatiseerde aanvallen gebruiken herkenbare user agents. Door deze te blokkeren voorkom je het meeste "low-hanging fruit" verkeer.
# Script-kiddie user agents blokkeren
SetEnvIfNoCase User-Agent "curl|wget|python|libwww|scan|nikto|sqlmap" bad_bot
<If "%{ENV:bad_bot} == '1'">
Require all denied
</If>
Geblokkeerde tools:
curl/wget- Command-line download toolspython/libwww- Scripting librariesnikto- Vulnerability scannersqlmap- SQL injection tool
Let op: legitieme services kunnen ook deze tools gebruiken. Monitor je logs voor false positives.
Regel 11: Request Methods Beperken
De meeste websites hebben alleen GET, POST en HEAD nodig. Andere HTTP methods zoals PUT, DELETE of TRACE kunnen worden misbruikt.
# Request method lockdown
<LimitExcept GET POST HEAD>
Require all denied
</LimitExcept>
Dit is een simpele maar effectieve maatregel tegen bepaalde types aanvallen zoals HTTP verb tampering.
Regel 12: Security Headers
HTTP security headers instrueren de browser om bepaalde beveiligingsmaatregelen te nemen. Dit beschermt je bezoekers tegen aanvallen zoals clickjacking en XSS.
# Security headers
<IfModule mod_headers.c>
Header always set X-Frame-Options "SAMEORIGIN"
Header always set X-Content-Type-Options "nosniff"
Header always set Referrer-Policy "strict-origin-when-cross-origin"
Header always set Permissions-Policy "geolocation=(), microphone=(), camera=()"
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
</IfModule>
Uitleg van elke header:
X-Frame-Options- Voorkomt clickjacking door embedding in iframes te blokkerenX-Content-Type-Options- Voorkomt MIME-type sniffingReferrer-Policy- Controleert welke referrer info wordt gedeeldPermissions-Policy- Blokkeert toegang tot gevoelige browser APIsStrict-Transport-Security- Forceert HTTPS voor een jaar
Volledige Configuratie
Hieronder vind je de complete .htaccess configuratie met alle 12 beveiligingsregels gecombineerd. Kopieer dit naar je .htaccess bestand en pas de IP-adressen aan.
######################################################################
# #
# ********************************************************** #
# * * #
# * WPTS.nl WordPress Security Config * #
# * ELITE OG .htaccess – Plugin Free * #
# * * #
# * Touch this file = you own the consequences * #
# * * #
# ********************************************************** #
# #
######################################################################
########################################
# 0. Server hygiene
########################################
ServerSignature Off
Options -Indexes
########################################
# 1. WordPress permalinks (berichtnaam)
########################################
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
########################################
# 2. Blokkeer kritieke bestanden
########################################
<FilesMatch "(^\.|wp-config\.php|readme\.html|license\.txt|install\.php)">
Require all denied
</FilesMatch>
########################################
# 3. Uploads = NO PHP (htaccess-safe)
########################################
<FilesMatch "^wp-content/uploads/.*\.(php|phtml|php3|php4|php5|phps)$">
Require all denied
</FilesMatch>
########################################
# 4. wp-includes hard afschermen
########################################
<IfModule mod_rewrite.c>
RewriteRule ^wp-includes/.*\.php$ - [F,L]
RewriteRule ^wp-includes/js/tinymce/langs/.*\.php$ - [F,L]
RewriteRule ^wp-includes/theme-compat/ - [F,L]
</IfModule>
########################################
# 5. Plugins & themes PHP blokkeren
########################################
<FilesMatch "^wp-content/(plugins|themes)/.*\.php$">
Require all denied
</FilesMatch>
########################################
# 6. XML-RPC blokkeren
########################################
<Files xmlrpc.php>
Require all denied
</Files>
########################################
# 7. wp-login.php IP-restrictie
########################################
<Files wp-login.php>
Require all denied
# Vervang met je eigen IP(s)
Require ip 123.123.123.123
Require ip 111.111.111.111
</Files>
########################################
# 8. wp-admin afschermen (rewrite-based)
########################################
<IfModule mod_rewrite.c>
RewriteCond %{REQUEST_URI} ^/wp-admin
RewriteCond %{REMOTE_ADDR} !^123\.123\.123\.123$
RewriteCond %{REMOTE_ADDR} !^111\.111\.111\.111$
RewriteRule .* - [F,L]
</IfModule>
########################################
# 9. Blokkeer back-up / lekbestanden
########################################
RedirectMatch 403 (\.bak|\.old|\.sql|\.log|\.ini|\.env|\.git)
########################################
# 10. Script-kiddie user agents blokkeren
########################################
SetEnvIfNoCase User-Agent "curl|wget|python|libwww|scan|nikto|sqlmap" bad_bot
<If "%{ENV:bad_bot} == '1'">
Require all denied
</If>
########################################
# 11. Request method lockdown
########################################
<LimitExcept GET POST HEAD>
Require all denied
</LimitExcept>
########################################
# 12. Security headers
########################################
<IfModule mod_headers.c>
Header always set X-Frame-Options "SAMEORIGIN"
Header always set X-Content-Type-Options "nosniff"
Header always set Referrer-Policy "strict-origin-when-cross-origin"
Header always set Permissions-Policy "geolocation=(), microphone=(), camera=()"
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
</IfModule>
Veelgestelde Vragen
Mijn website werkt niet meer na wijzigingen!
Herstel je backup van .htaccess via FTP. Als je geen backup hebt, hernoem of verwijder .htaccess en ga naar WordPress → Instellingen → Permalinks → Opslaan om een nieuwe aan te maken.
Ik krijg een 500 Internal Server Error
Dit duidt vaak op een syntax error. Controleer of alle tags correct zijn gesloten (</Files>, </IfModule>, etc.) en of er geen typfouten in staan.
Werkt .htaccess ook op Nginx servers?
Nee, .htaccess is alleen voor Apache webservers. Voor Nginx moet je equivalente regels toevoegen aan je nginx.conf of server block configuratie.
Hoe weet ik of mijn hosting Apache gebruikt?
Maak een PHP bestand met <?php phpinfo(); ?> en bekijk de "Server API" regel. Of vraag het aan je hosting provider. De meeste shared hosting gebruikt Apache.
Moet ik alle 12 regels implementeren?
Nee, je kunt kiezen welke regels je implementeert. Begin met de basis (gevoelige bestanden blokkeren) en voeg geleidelijk meer toe. Test altijd na elke wijziging.
Blijft dit werken na WordPress updates?
Ja! WordPress updates raken je custom .htaccess regels niet aan. Alleen de WordPress permalink regels worden beheerd door WordPress zelf.
Conclusie
Een goed geconfigureerd .htaccess bestand is een van de meest effectieve manieren om je WordPress website te beveiligen. Het werkt op server-niveau, vereist geen plugins, en blokkeert aanvallen voordat ze WordPress bereiken.
Checklist voor implementatie:
Hulp nodig met WordPress beveiliging?
Onze experts helpen je graag met het implementeren van deze en andere beveiligingsmaatregelen.