WP-CONFIG.PHP — HARDENING

wp-config.php beveiligen?

Het belangrijkste bestand van je hele WordPress-installatie staat default op een setting waar de helft van mijn cleanup-klanten over struikelt. Drie regels toevoegen en het meest voorkomende type post-compromise damage — via de WP code-editor PHP injecteren, debug-info naar bezoekers lekken, salts die 6 jaar oud zijn — is meteen weg. Hieronder de complete checklist die ik bij elke hardening standaard installeer: regel voor regel uitgelegd, met een kopieerbaar voorbeeld-bestand aan het eind.

  • 11 concrete regels, geen vage tips
  • Werkende voorbeeld-config aan het eind
  • Uit dagelijkse hardening-praktijk

Wat doet wp-config.php eigenlijk — en waarom kijk ik 't altijd als eerste?

Elke keer als ik een nieuwe cleanup binnenkrijg, vraag ik om twee dingen: SSH- of FTP-toegang en de naam van de hosting. Het eerste wat ik open is wp-config.php. Niet de plugin-lijst, niet de database, niet de logs. Eerst dit ene bestand.

Want hierin staat het geheim van je hele site — en het is verbazingwekkend hoe vaak ik daar dingen zie die de aanvaller eigenlijk een uitnodiging geven. Negen van de tien keer is 't variatie op één van deze:

// Wat ik te vaak zie in 't veld:
define('DB_PASSWORD', 'WelkomWP2018');           // ← zes jaar oud wachtwoord
$table_prefix = 'wp_';                            // ← default voorspelbaar
define('WP_DEBUG', true);                         // ← in productie!
define('AUTH_KEY', 'put your unique phrase here'); // ← niemand heeft 't veranderd
// DISALLOW_FILE_EDIT — ontbreekt volledig

Die ene laatste, DISALLOW_FILE_EDIT, is mijn persoonlijke favoriet om te vergeten. Want zonder die regel kan iedere admin (legitiem of niet) via Weergave → Editor in /wp-admin direct PHP-code in een theme-bestand plakken. Krijgt een aanvaller via een gestolen wachtwoord of een phishing-aanval ééns admin-toegang? Dan zijn ze van shell-toegang op je server vijf seconden verwijderd. Eén regel toevoegen voorkomt dat hele scenario.

Daarom dit artikel. Hieronder loop ik regel voor regel door de wp-config-settings die ik bij elke hardening installeer, met de redenering waarom achter elk. Aan het eind staat een complete, kopieerbare voorbeeld-config die je direct kunt overnemen — alleen je eigen DB-gegevens nog invullen.

Veel hardening-artikelen geven je een lijst constants zonder uitleg. Hier krijg je per regel de aanvalsroute die je dichtzet — want hardening zonder waarom is bijgeloof. En bijgeloof is hoe sites alsnog gehackt worden.

VIER DINGEN DIE JE NU AL KUNT DOEN — EER JE VERDER LEEST

Als je weinig tijd hebt: doe deze vier eerst. Dekt al één van de meest voorkomende aanvalsroutes. De rest van het artikel gaat dieper.

  1. Stap 1 — vernieuw je salts. Open https://api.wordpress.org/secret-key/1.1/salt/ in je browser. Je krijgt 8 ready-to-use define()-regels terug. Open je wp-config.php, zoek het bestaande blok met AUTH_KEY, SECURE_AUTH_KEY, etc., en vervang het hele blok met de nieuwe regels. Klaar. Alle ingelogde sessies worden uitgelogd — gestolen cookies en gekraakte sessies zijn vanaf nu waardeloos.
  2. Stap 2 — zet DISALLOW_FILE_EDIT aan. Voeg deze regel toe boven de regel /* That's all, stop editing! */ in wp-config.php: define('DISALLOW_FILE_EDIT', true);. Hierdoor verdwijnen de Editor-menu's onder Weergave en Plugins in /wp-admin. Krijgt een aanvaller via een gestolen wachtwoord admin-toegang? Dan kan hij geen PHP meer injecteren via de WordPress-interface. Doet niets aan plugins en thema's installeren via de zip-upload, maar blokkeert wel de meest gebruikte post-compromise route.
  3. Stap 3 — zet WP_DEBUG_DISPLAY op false. Als je WP_DEBUG aan hebt staan (vaak om foutmeldingen te zien), zorg dan dat WP_DEBUG_DISPLAY uit staat. Anders krijgen bezoekers van je site PHP-fouten te zien — inclusief volledige bestandspaden en soms zelfs SQL-queries. Beste combinatie: WP_DEBUG=true, WP_DEBUG_LOG=true, WP_DEBUG_DISPLAY=false. Fouten gaan dan naar /wp-content/debug.log in plaats van naar bezoekers.
  4. Stap 4 — chmod 400 op wp-config.php. Via SSH: chmod 400 wp-config.php. Hierdoor kan alleen de eigenaar (jij/PHP) het bestand lezen. Werkt niet op alle shared hostings — sommige draaien de webserver als andere user. In dat geval: chmod 440 en plus een .htaccess deny rule (verderop in dit artikel).
  5. Bonus — check je $table_prefix. Open wp-config.php en kijk naar de regel $table_prefix = 'wp_';. Staat daar nog wp_? Dan ben je voorspelbaar voor elk geautomatiseerd SQL-injection script in de buitenwereld. Wijzigen kan, maar vereist database-werk (alle tabellen renamen) — doe dat samen met de complete hardening verderop. Tot die tijd: minstens noteren als «todo».
Niet zeker of je site al schoon is?
Laat de WPTS scanner eerst kijken
Hardening op een al-besmette site is dweilen met de kraan open. De gratis scan kijkt eerst of er actieve infectie is voordat je gaat hardenen.
Start gratis scan

DRIE NIVEAUS — KIES WAT BIJ JE PAST

Niet elke site heeft hetzelfde risicoprofiel. Een hobby-blog heeft minder hardening nodig dan een webshop met klantgegevens. Hieronder drie niveaus — van "ik heb 10 minuten" tot "complete lockdown".

01

Basis — 10 minuten

De 4 dingen hierboven plus: DISALLOW_FILE_MODS aanzetten om plugin/theme-installatie via dashboard te blokkeren. Voldoende voor blogs, portfolio's, brochuresites. Voorkomt 80% van de aanvalsroutes die ik in de praktijk zie. Geen hosting-aanpassingen nodig.

02

Medium — 30 minuten

Bovenop basis: $table_prefix wijzigen, database-rechten beperken (REVOKE TRIGGER, CREATE ROUTINE, ALTER), FORCE_SSL_ADMIN aan, WP_HTTP_BLOCK_EXTERNAL met whitelist, externe WP-Cron, salts in versiebeheer uit halen. Voor MKB-sites met klantcontact of e-commerce.

03

Advanced — 1-2 uur

Bovenop medium: wp-config.php verplaatsen naar één directory hoger dan de webroot, .htaccess deny-rules op kritieke bestanden, file-permissions strict (400 op wp-config, 444 op .htaccess, 755 op dirs), index.php in elke uploads-subfolder. Voor zorginstellingen, advocaten, fintech, alles met persoonsgegevens.

DE BELANGRIJKE CONSTANTS — REGEL VOOR REGEL

Hieronder de constants die ik zelf bij elke hardening neerzet, gegroepeerd per thema. Per regel de bedoeling, het aanval-scenario dat 'ie blokkeert, en de exacte code-snippet.

Authentication keys + salts

WordPress beveiligt al jouw cookies en sessies met acht random strings: vier keys en vier salts. Worden die nooit gewijzigd, dan blijven oude gestolen sessie-cookies oneindig geldig. Vernieuwen logt iedereen uit en maakt eerdere lekken waardeloos:

// Genereer op:
// api.wordpress.org/secret-key/1.1/salt/
define('AUTH_KEY',         '...long random...');
define('SECURE_AUTH_KEY',  '...long random...');
define('LOGGED_IN_KEY',    '...long random...');
define('NONCE_KEY',        '...long random...');
define('AUTH_SALT',        '...long random...');
define('SECURE_AUTH_SALT', '...long random...');
define('LOGGED_IN_SALT',   '...long random...');
define('NONCE_SALT',       '...long random...');

Doe dit minstens jaarlijks én altijd direct na elke vermoedelijke inbraak. De officiële generator levert acht verse strings — copy/paste en je bent klaar.

$table_prefix wijzigen

Standaard heet je wp_ — voorspelbaar voor elk geautomatiseerd SQL-injection script in de buitenwereld. Wijzig naar iets willekeurigs en je verbreekt direct die hele klasse van aanvallen:

$table_prefix = 'xyz_';

Let op: alleen wijzigen in wp-config.php is niet genoeg — je moet ook alle tabellen renamen in de database. RENAME TABLE wp_posts TO xyz_posts; voor elke wp_-tabel, plus de meta_key entries in wp_options en wp_usermeta die referenties bevatten naar de oude prefix updaten. Doe dit op een staging-kopie eerst, of laat het door iemand met DB-ervaring uitvoeren.

DISALLOW_FILE_EDIT + DISALLOW_FILE_MODS

De twee belangrijkste constants voor post-compromise-mitigatie. Eerste schakelt de PHP-editor in /wp-admin uit, tweede verbiedt elke plugin- of theme-installatie via dashboard:

define('DISALLOW_FILE_EDIT', true);
define('DISALLOW_FILE_MODS', true);

Vergeet niet: DISALLOW_FILE_MODS blokkeert ook auto-updates van core, plugins en thema's. Combineer met WP_AUTO_UPDATE_CORE aan via SSH, of doe updates handmatig met WP-CLI. Voor kritische sites is dat een acceptabele trade-off.

WP_DEBUG correct configureren

Drie constants die altijd samen ingesteld moeten worden:

define('WP_DEBUG',         true);  // logging aan
define('WP_DEBUG_LOG',     true);  // naar bestand
define('WP_DEBUG_DISPLAY', false); // niet naar browser
@ini_set('display_errors', 0);

Fouten gaan dan netjes naar /wp-content/debug.log. Bezoekers van je site zien nooit een PHP-foutmelding, dus geen lekken van bestandspaden, plugin-namen of databasequeries. Zet WP_DEBUG_LOG eventueel uit op high-traffic sites om disk-vulling te voorkomen.

FORCE_SSL_ADMIN + cookie security

Forceert dat alle admin-sessies via HTTPS gaan. Voorkomt session-hijacking op publieke wifi en dwingt de browser cookies als Secure te markeren:

define('FORCE_SSL_ADMIN', true);
@ini_set('session.cookie_secure', 1);
@ini_set('session.cookie_httponly', 1);

Vereist natuurlijk dat je site een geldig SSL-certificaat heeft — bij elke moderne hosting is dat standaard via Let's Encrypt. Geen reden om dit ooit uit te laten.

WP_HTTP_BLOCK_EXTERNAL + whitelist

Een van mijn favorieten tegen geïnfiltreerde malware. Blokkeert álle externe HTTP-calls vanuit PHP, behalve de hosts die je expliciet toestaat. Werkt zo:

define('WP_HTTP_BLOCK_EXTERNAL', true);
define('WP_ACCESSIBLE_HOSTS',
    'api.wordpress.org,*.wordpress.org,' .
    'downloads.wordpress.org,' .
    'api.example.com');

Wat dit doet: zelfs als een aanvaller een payload weet te installeren, kan die payload geen POST-back naar zijn command-and-control server doen. Geen data-exfiltratie, geen instructies ophalen. Wordpress.org-domeinen moet je toestaan voor core/plugin-updates — voeg verder alleen toe wat je site echt nodig heeft.

DISABLE_WP_CRON + echte server-cron

De default WP-Cron draait bij elke pagina-load — traag, onbetrouwbaar, en aanvallers kunnen de endpoint wp-cron.php misbruiken om je server plat te leggen. Beter:

define('DISABLE_WP_CRON', true);
// Plus in je hosting cron-jobs:
// */15 * * * * wget -q -O - \
//   https://jouwsite.nl/wp-cron.php\
//   ?doing_wp_cron > /dev/null 2>&1

Resultaat: scheduled events draaien op vaste momenten i.p.v. willekeurig bij paginabezoeken. Sneller, voorspelbaarder, minder DoS-risico. Plus: een cron die elke 15 minuten loopt is voor de meeste sites ruimer dan nodig.

Database-user rechten beperken

Niet in wp-config zelf, maar wel cruciaal: de MySQL-user die in DB_USER staat. Standaard krijgt 'ie ALL PRIVILEGES — veel te veel. Voor normale WordPress-werking is dit genoeg:

GRANT SELECT, INSERT, UPDATE, DELETE,
      CREATE, DROP, INDEX, ALTER, LOCK TABLES,
      REFERENCES, CREATE TEMPORARY TABLES
ON wp_database.* TO 'wp_user'@'localhost';

REVOKE TRIGGER, CREATE ROUTINE, ALTER ROUTINE,
       EXECUTE, EVENT
ON wp_database.* FROM 'wp_user'@'localhost';

REVOKE TRIGGER is hier de sleutel: dat is precies wat MySQL-trigger backdoors gebruiken om automatisch admin-accounts aan te maken. Trek dat recht in en die hele aanvalsklasse is dood. Doe dit via je hosting-controlpanel of vraag de hoster — bij Plesk staat het onder «Databases → Permissions».

Naast bovenstaande constants gebruik ik in elke productie-config nog: WP_POST_REVISIONS = 5 (anders groeit de DB onbeperkt), EMPTY_TRASH_DAYS = 7 (auto-cleanup), WP_MEMORY_LIMIT = '256M' en WP_MAX_MEMORY_LIMIT = '512M' voor admin-pagina's. Die zijn meer hygiëne dan security, maar voorkomen wel gekke errors die je hardening-werk verbergen.

FILESYSTEM-HARDENING ROND WP-CONFIG.PHP

Constants in wp-config zelf is de helft van het werk. De andere helft is hoe het bestand op disk staat en wie het kan lezen. Vijf concrete dingen die ik bij elke hardening doe.

  1. 01

    chmod 400 op wp-config.php

    Standaard heeft het bestand permissies 644 (alle users mogen lezen). Daarmee kan elke geïnfiltreerde plugin of script de DB-credentials uitlezen. Strakker:

    chmod 400 wp-config.php

    Alleen de eigenaar (jij/PHP-user) kan lezen. Werkt op de meeste hostings. Werkt het niet (sommige shared hostings draaien webserver onder andere user), val terug op chmod 440 of 444.

  2. 02

    Verplaats wp-config buiten je webroot

    WordPress zoekt wp-config eerst in de webroot, daarna één directory hoger. Verplaats het bestand een niveau omhoog en het is niet meer bereikbaar voor bezoekers, webcrawlers of bots die naar de URL jouwsite.nl/wp-config.php zoeken:

    # Vanuit je webroot:
    mv wp-config.php ../wp-config.php
    chmod 400 ../wp-config.php

    WordPress vindt 'm daar automatisch. Test wel altijd direct na de move dat je site nog werkt — sommige hostings (vooral managed WP zoals Kinsta) staan deze structuur niet toe.

  3. 03

    .htaccess deny rule als webroot-fallback

    Als je wp-config niet kunt verplaatsen, blokkeer minimaal de directe URL-toegang. In je site-root .htaccess:

    <Files wp-config.php>
        Require all denied
    </Files>
    
    <Files .htaccess>
        Require all denied
    </Files>
    
    <Files debug.log>
        Require all denied
    </Files>

    Resultaat: een 403 Forbidden voor wie de URL direct probeert — en hetzelfde voor je .htaccess en debug.log, die ook gevoelige info kunnen lekken.

  4. 04

    Lege index.php in elke uploads-subfolder

    Standaard is /wp-content/uploads/ wereld-leesbaar, en zonder index-bestand ziet een aanvaller netjes de directory-listing. Plus: malware-PHP wordt vaak in uploads-subfolders geplaatst, waar het direct uitvoerbaar is. Twee fixes:

    # 1. Lege index.php in alle dirs:
    find /var/www/html/wp-content -type d \
      -exec touch {}/index.php \;
    
    # 2. PHP-uitvoering uitschakelen in uploads
    # (voeg toe in .htaccess in /uploads/):
    <FilesMatch "\.php$">
        Require all denied
    </FilesMatch>

    De eerste regel maakt directory-listing onmogelijk. De tweede zorgt dat zelfs als een aanvaller PHP weet te uploaden, het bestand niet uitgevoerd kan worden.

  5. 05

    Correcte permissies in één keer zetten

    Als je een site overneemt is vaak alles op 777 of 755 gezet door «iemand die ergens iets las». Reset naar veilige defaults:

    # Alle directories naar 755
    find /var/www/html -type d \
      -exec chmod 755 {} \;
    
    # Alle PHP-bestanden naar 644
    find /var/www/html -type f -name "*.php" \
      -exec chmod 644 {} \;
    
    # wp-config en .htaccess strenger
    chmod 400 wp-config.php
    chmod 444 .htaccess

    Resultaat: WordPress kan alles uitvoeren wat 'ie moet, maar gebruikers/scripts kunnen niets meer schrijven waar dat niet hoort. Test daarna: kun je nog inloggen, plugins updaten? Zo ja, klaar.

COMPLETE VOORBEELD-WP-CONFIG.PHP — COPY/PASTE KLAAR

Alle hierboven besproken hardening in één bestand. Vervang de placeholder-waarden (DB-gegevens, salts) met je eigen, en dit kun je direct in productie zetten.

<?php
/**
 * ════════════════════════════════════════════════════════════
 *
 *   ██╗    ██╗██████╗ ████████╗███████╗
 *   ██║    ██║██╔══██╗╚══██╔══╝██╔════╝
 *   ██║ █╗ ██║██████╔╝   ██║   ███████╗
 *   ██║███╗██║██╔═══╝    ██║   ╚════██║
 *   ╚███╔███╔╝██║        ██║   ███████║
 *    ╚══╝╚══╝ ╚═╝        ╚═╝   ╚══════╝
 *
 *   WordPress configuratie  •  hardened template
 *
 * ════════════════════════════════════════════════════════════
 *
 *   Site         :  [vul je domein in]
 *   Toegepast op :  [datum]
 *
 *   Template     :  WPTS — Website Technical Support
 *   Bron         :  https://wpts.nl/wp-config-php-beveiligen
 *
 *   Hulp nodig bij hardening of een complete security-audit?
 *      Daniel Mulder  •  info@wpts.nl  •  06 12 29 47 06
 *
 *   © WPTS.nl  •  vrije te gebruiken & aan te passen
 *
 * ════════════════════════════════════════════════════════════
 */

// ============================================================
// DATABASE
// ============================================================
define( 'DB_NAME',     'jouw_database_naam' );
define( 'DB_USER',     'jouw_db_user' );        // beperkte rechten!
define( 'DB_PASSWORD', 'sterk-uniek-wachtwoord' ); // min. 24 karakters
define( 'DB_HOST',     'localhost' );
define( 'DB_CHARSET',  'utf8mb4' );
define( 'DB_COLLATE',  '' );

// ============================================================
// AUTHENTICATION KEYS & SALTS
// Genereer verse keys: api.wordpress.org/secret-key/1.1/salt/
// Roteer minstens jaarlijks én na elke inbraak
// ============================================================
define( 'AUTH_KEY',         '...vul met verse random string...' );
define( 'SECURE_AUTH_KEY',  '...vul met verse random string...' );
define( 'LOGGED_IN_KEY',    '...vul met verse random string...' );
define( 'NONCE_KEY',        '...vul met verse random string...' );
define( 'AUTH_SALT',        '...vul met verse random string...' );
define( 'SECURE_AUTH_SALT', '...vul met verse random string...' );
define( 'LOGGED_IN_SALT',   '...vul met verse random string...' );
define( 'NONCE_SALT',       '...vul met verse random string...' );

// ============================================================
// TABLE PREFIX — niet wp_, maakt SQL-injection moeilijker
// ============================================================
$table_prefix = 'xyz_';

// ============================================================
// CORE HARDENING
// ============================================================
// Schakelt PHP-editor in /wp-admin uit (Editor onder Weergave + Plugins)
define( 'DISALLOW_FILE_EDIT', true );

// Verbiedt plugin/theme installatie via dashboard
// (Vergeet niet auto-updates extern in te richten als je deze aanzet)
define( 'DISALLOW_FILE_MODS', true );

// Forceer HTTPS in admin
define( 'FORCE_SSL_ADMIN', true );

// Cookies alleen via HTTPS + niet leesbaar via JS
@ini_set( 'session.cookie_secure',   1 );
@ini_set( 'session.cookie_httponly', 1 );

// ============================================================
// DEBUG — in productie naar log, NIET naar browser
// ============================================================
define( 'WP_DEBUG',         true );
define( 'WP_DEBUG_LOG',     true );
define( 'WP_DEBUG_DISPLAY', false );
@ini_set( 'display_errors', 0 );

// ============================================================
// AUTO-UPDATES
// ============================================================
// minor + security automatisch, major handmatig
define( 'WP_AUTO_UPDATE_CORE', 'minor' );

// ============================================================
// EXTERNAL HTTP — alleen vertrouwde hosts
// ============================================================
define( 'WP_HTTP_BLOCK_EXTERNAL', true );
define( 'WP_ACCESSIBLE_HOSTS',
    'api.wordpress.org,*.wordpress.org,' .
    'downloads.wordpress.org,api.example-payment-provider.com'
);

// ============================================================
// WP-CRON via externe trigger (zie hosting cron-jobs)
// ============================================================
define( 'DISABLE_WP_CRON', true );

// ============================================================
// PERFORMANCE / HYGIENE
// ============================================================
define( 'WP_POST_REVISIONS',    5 );      // niet onbeperkt revisions
define( 'EMPTY_TRASH_DAYS',     7 );      // auto-cleanup
define( 'AUTOSAVE_INTERVAL',    300 );    // 5 minuten i.p.v. 60sec
define( 'WP_MEMORY_LIMIT',      '256M' );
define( 'WP_MAX_MEMORY_LIMIT',  '512M' );

// ============================================================
// MULTISITE (alleen als van toepassing)
// ============================================================
// define( 'WP_ALLOW_MULTISITE', true );
// define( 'MULTISITE', true );

// ============================================================
// ABSPATH — nooit aanpassen
// ============================================================
if ( ! defined( 'ABSPATH' ) ) {
    define( 'ABSPATH', __DIR__ . '/' );
}
require_once ABSPATH . 'wp-settings.php';

// ════════════════════════════════════════════════════════════
//  Geharded met de WPTS hardening-template
//  https://wpts.nl/wp-config-php-beveiligen
// ════════════════════════════════════════════════════════════

Vergeet niet: na het overzetten van deze config, log uit en weer in. Salts zijn vernieuwd dus alle bestaande sessies zijn ongeldig — ook die van jezelf. Als je site na save niet meer werkt, controleer dan eerst of je geen typefouten in DB_*-regels hebt staan; daarna pas naar de hardening-constants kijken. Test ook of plugins die je gebruikt nog functioneren — WP_HTTP_BLOCK_EXTERNAL kan integraties met externe API's breken die niet in je whitelist staan.

Hardening niet zelf willen doen? Ik kom 't voor je inrichten.

Bij elke cleanup die ik doe zit een complete wp-config hardening standaard inbegrepen. Heb je geen cleanup nodig maar wil je de bovenstaande hardening op productie laten installeren? Dat doe ik als losse opdracht: alle 11 regels door, salts vernieuwd, database-rechten beperkt, file-permissions gezet, getest. Eén werkdag, vaste prijs.

Hardening laten doen

VEELGESTELDE VRAGEN OVER WP-CONFIG HARDENING

De vragen die ik in de praktijk het meest krijg over wp-config.php beveiliging.

Wat is wp-config.php precies en waarom is het zo belangrijk?

wp-config.php is het centrale configuratiebestand van elke WordPress-installatie. Het bevat je database-credentials (gebruikersnaam, wachtwoord, host), de authentication keys en salts die sessies en cookies beveiligen, en alle PHP-constants die het gedrag van WordPress bepalen. Als dit bestand lekt, heeft een aanvaller direct toegang tot je hele site. Als het verkeerd is geconfigureerd, kan een gecompromitteerd admin-account binnen 30 seconden PHP-code injecteren via de WordPress code-editor. Daarom is het het eerste bestand dat ik bij elke cleanup en hardening open.

Werkt DISALLOW_FILE_EDIT op managed hosting zoals SiteGround of Kinsta?

Ja, DISALLOW_FILE_EDIT is een puur WordPress-niveau constant die alle hosting-omgevingen ondersteunen. Het schakelt simpelweg de Weergave → Editor en Plugins → Editor menu's uit in /wp-admin. Geen hosting-specifieke configuratie nodig. Bij sommige managed hosts staat het zelfs standaard al aan — check je wp-config.php voordat je 't toevoegt.

Hoe vaak moet ik mijn WordPress salts roteren?

In de praktijk: minstens één keer per jaar, en altijd direct na een vermoedelijke inbraak of een wachtwoord-reset van een admin-account. Salts vernieuwen logt alle ingelogde sessies en cookies meteen uit zodra je ze wijzigt — ook die van een aanvaller die net binnen was. Sommige security-policies (zoals NIS2) raden zelfs aan om elke 90 dagen te roteren, maar voor een gemiddelde MKB-site is jaarlijks plus na-incident voldoende.

Wat als ik $table_prefix wijzig nadat mijn site al live staat?

Dat kan, maar het is een operatie met risico. Je moet drie dingen tegelijk doen: alle tabel-namen renamen in de database (RENAME TABLE wp_posts TO xyz_posts; etc.), de prefix updaten in wp-config.php, en de meta_key entries in wp_options en wp_usermeta updaten die de oude prefix bevatten (er staan referenties in user_roles en capabilities). Doe het altijd op een staging-kopie eerst — ik krijg regelmatig gebroken sites binnen van klanten die dit zonder backup probeerden.

Mijn hoster zegt dat ik chmod 400 niet mag op wp-config.php — wat nu?

Sommige shared hostings draaien de web-server als een andere user dan jouw FTP-account, waardoor chmod 400 betekent dat de webserver het bestand niet meer kan lezen en je site stuk gaat. In dat geval: gebruik chmod 440 (group readable) of laat het op 644 staan maar zet een .htaccess deny rule erbij. Het effect is vergelijkbaar — de webserver kan het lezen, externe bezoekers niet. Voor de meeste Plesk/cPanel-hostings werkt chmod 440 wel.

Breekt DISABLE_WP_CRON mijn scheduled events zoals backups of e-mails?

Nee — mits je een echte server-cron instelt die wp-cron.php elke 5-15 minuten aanroept. WordPress draait dan álles wat normaal door wp-cron werd afgehandeld (backups, scheduled posts, e-mailnotificaties, plugin-updates) via die echte cron in plaats van bij elke pagina-load. Voor sites met meer dan 100 bezoekers per dag is dit zelfs sneller én betrouwbaarder. Bij Plesk: cron-job aanmaken die elke 15 minuten wget -q -O - https://jouwsite.nl/wp-cron.php?doing_wp_cron > /dev/null uitvoert.

Waar haal ik nieuwe WordPress salts vandaan?

WordPress heeft een officiële generator: api.wordpress.org/secret-key/1.1/salt/. Open die URL in je browser en je krijgt acht ready-to-use define()-statements terug. Knip en plak het hele blok over de bestaande define-regels in wp-config.php. Elke aanroep van de URL geeft compleet nieuwe random keys — gebruik dus altijd verse exemplaren en kopieer ze nooit tussen sites.

Wat is het verschil tussen WP_DEBUG_LOG en WP_DEBUG_DISPLAY?

WP_DEBUG_DISPLAY zorgt dat PHP-fouten zichtbaar worden in de browser — voor BEZOEKERS van je site, niet alleen admin. Dat lekt bestandspaden, plugin-versies en soms zelfs SQL-queries naar iedereen die op een foutpagina komt. Zet deze ALTIJD op false in productie. WP_DEBUG_LOG schrijft dezelfde fouten naar /wp-content/debug.log — alleen jij ziet ze. Goede productie-combinatie: WP_DEBUG=true, WP_DEBUG_LOG=true, WP_DEBUG_DISPLAY=false.

Helpt deze hardening tegen casino-spam besmettingen?

Indirect ja — REVOKE TRIGGER op de DB-user blokkeert direct de MySQL-trigger backdoors die ik in casino-spam cleanups vaak tegenkom. En DISALLOW_FILE_EDIT voorkomt dat een aanvaller na een gestolen admin-account meteen PHP kan injecteren. Maar als je site al besmet is, is hardening niet genoeg — eerst moet de actieve infectie weg. Zie mijn artikel over casino-spam verwijderen voor de cleanup-procedure.

NEEM CONTACT OP

Bellen of WhatsApp is bij urgente zaken het snelst — meestal reageer ik binnen het uur. Ook mailen of een bericht via het formulier op de homepage kan altijd.

Online — reactie meestal binnen 4 uur
Daniel Mulder

Daniel Mulder

Website Technical Support Specialist
WordPress · Drupal · Joomla · OpenCart · CMS Made Simple

15+ JAAR
500+ SITES
4u REACTIE
Diagnose altijd kosteloos 30 dagen garantie op fixes KvK 63456842 · Werkzaam in heel NL
WhatsApp Snelste manier — direct chatten, ook foto's en logs delen 06 12 29 47 06 Bellen — bij noodgevallen het snelste pad info@wpts.nl E-mail — voor uitgebreidere uitleg, screenshots of logs

Werkuren

Maandag – Vrijdag09:00 – 18:00
ZaterdagOp afspraak
ZondagGesloten

Spoed buiten werkuren? Bel altijd — bij echte noodgevallen reageer ik vaak binnen 30 minuten.