Terug naar hoofdinhoud
Joomla beveiligen: security hardening in de diepte
Op deze pagina

Joomla beveiligen: security hardening in de diepte

06 augustus 2026

De meeste Joomla-sites worden niet gehackt door slimme, gerichte aanvallen. Ze worden gehackt vanwege een verouderde extensie, een zwak wachtwoord of een instellingen die nooit zijn aangepast. Security hardening houdt in dat je die gemakkelijke toegangswegen afsluit voordat iemand er gebruik van maakt.

Dit artikel legt stap voor stap uit hoe je een Joomla-site hardent. Het behandelt de basis voor eigenaren en redacteuren, de dagelijkse instellingen voor beheerders, en de technische details voor ontwikkelaars. Je leert hoe je de core en extensies up-to-date houdt, gebruikersaccounts beschermt met sterke wachtwoorden en multi-factor authenticatie, de beveiligingsinstellingen in de Algemene configuratie afstelt, de webserver hardent, de juiste HTTP security headers verstuurt, je logs in de gaten houdt, en begrijpt welke beschermingen Joomla al voor je ingebouwd heeft.

Beveiliging is geen product dat je installeert. Het is een reeks gewoontes, en Joomla biedt je de hulpmiddelen voor bijna al die gewoontes.

Het doel is eenvoudig: je met vertrouwen je Joomla-site laten hardenen, grotendeels met wat er al in Joomla zit.

1. De basis

1.1 Wat is security hardening?

Security hardening betekent het aantal manieren verkleinen waarop een aanvaller je site binnenkomt, en de schade beperken wanneer er toch iets misgaat. Het is niet een magische schakelaar. Het is een reeks kleine beslissingen in vier lagen:

LaagVoorbeelden
Server PHP-versie, HTTPS, bestandsrechten, .htaccess-regels.
Joomla core Updates, Algemene configuratie, sessie-instellingen, security headers.
Extensies Updates, verwijderen wat je niet gebruikt, betrouwbare ontwikkelaars kiezen.
Mensen Sterke wachtwoorden, multi-factor authenticatie, beperkte rechten.

Elke laag telt. Een volledig gepatchte Joomla achter een zwak Super User-wachtwoord is nog steeds een open deur.

1.2 Hoe Joomla-sites echt gecompromitteerd raken

Jaar na jaar staan dezelfde oorzaken bovenaan de lijst:

  • Verouderde extensies met bekende kwetsbaarheden.
  • Verouderde Joomla core-versies.
  • Zwakke of hergebruikte wachtwoorden op beheerdersaccounts.
  • Achtergebleven bestanden: oude back-ups, testkopieen, verlaten componenten.
  • Gecompromitteerde hosting-buren op slecht gescheiden shared servers.

Let op wat er niet hoog op de lijst staat: exotische zero-day-aanvallen. De meeste inbraken gebruiken problemen die al opgelost waren in een update die de site nooit installeerde. Dat is goed nieuws, want het betekent dat de effectiefste hardening-stappen ook de simpelste zijn.

1.3 Beveiliging is een proces

Je hardent een site een keer, maar je houdt hem elke week veilig: updates installeren, accounts controleren, logs bekijken, back-ups verifieren. Dit artikel volgt die volgorde, van de stappen met de grootste impact naar de fijnere details.

Naar boven

2. Hou alles up-to-date

2.1 Core-updates

Joomla updaten is de meest effectieve beveiligingsmaatregel die je kunt nemen. Joomla kondigt beveiligingsfixes aan in de release notes, wat betekent dat elke release aanvallers ook precies vertelt wat er kapot was in de vorige versie. Vanaf het moment dat een security release uit is, worden niet-gepatchte sites doelwit.

Je updatet via Systeem → Update → Joomla. Sinds Joomla 6 verifieert het updatesysteem downloads met TUF (The Update Framework): de update-metadata is cryptografisch ondertekend, zodat een gemanipuleerde updateserver of een vergiftigde download je geen nep-Joomla-pakket kan aansmeren.

Joomla kan zichzelf ook updaten sinds versie 5.4. In de opties van Joomla Update kun je de site registreren voor automatische updates, zodat patch releases op de achtergrond installeren zonder op jou te wachten. Let op de reikwijdte: dit werkt alleen Joomla zelf bij en verder niets - je third-party extensies updaten nooit automatisch en blijven jouw taak (sectie 2.2). De dienst vereist dat je site bereikbaar is vanaf het internet, en met de optie backupcheck laat je Joomla eerst controleren op een recente back-up. Voor een site die niet elke week door een mens wordt bijgewerkt, zijn automatische updates een sterk vangnet.

Automatische updates zijn niet de enige professionele strategie. Op mijn eigen sites, en op websites van klanten met een onderhoudscontract, laat ik ze bewust uit: ik wil zelf bepalen wanneer een update draait. Als ik handmatig update en er daarna iets vreemds op de site verschijnt, is de update mijn eerste verdachte - een verband dat je makkelijk mist wanneer updates stilletjes op de achtergrond installeren.

Om handmatige updates werkbaar te houden over veel sites gebruik ik YourSites, een commercieel sitebeheerplatform dat je als Joomla-extensie op een eigen site installeert. Vanuit dat ene dashboard monitor en update ik alle Joomla-, WordPress- en ClassicPress-sites die ik onderhoud - en omdat het zelf gehost is, verlaat er nooit klantdata mijn eigen server, wat de opzet AVG-vriendelijk houdt. Kies de strategie die past bij hoe de site beheerd wordt: automatische updates voor een site waar niemand wekelijks naar kijkt, gecontroleerde centrale updates wanneer een professional erover waakt.

2.2 Extensie-updates

Extensies zijn aanvalsvector nummer een, dus neem hun updates net zo serieus als core-updates. Controleer regelmatig Systeem → Update → Extensies. Schakel de plugin Task - Update Notification in samen met de taakplanner, en Joomla e-mailt je wanneer er een nieuwe core-versie beschikbaar is, ook als niemand inlogt op de backend.

De backend is niet je enige kanaal. De meeste serieuze ontwikkelaars hebben een nieuwsbrief en mailen hun gebruikers over beveiligingsupdates - abonneer je voor elke extensie waar je op leunt. Een centraal dashboard zoals YourSites (sectie 2.1) houdt extensie-updates over al je sites tegelijk bij. En actief zijn in de Joomla-community levert meer op dan mensen verwachten: vrijwilligers en ontwikkelaars praten met elkaar, dus nieuws over een probleem bereikt je vaak eerder dan de formele release.

Het tempo is hier veranderd. AI-ondersteunde code-analyse heeft het goedkoop en snel gemaakt om grote hoeveelheden extensiecode op beveiligingsfouten te scannen, en beide kanten gebruiken het. Ontwikkelaars en beveiligingsonderzoekers vinden en repareren kwetsbaarheden in extensies van derden nu in een veel hoger tempo dan vroeger, en daarom zie je de laatste tijd zoveel security releases van extensies. Aanvallers gebruiken dezelfde technieken om sites te vinden die die fixes nog niet hebben geinstalleerd. Het gevolg: het veilige venster tussen een security release en actieve uitbuiting wordt steeds kleiner, dus installeer extensie-updates snel in plaats van "als ik er een keer aan toekom".

Een gestage stroom beveiligingsfixes van een ontwikkelaar is meestal een goed teken, geen slecht. Het betekent dat iemand de code actief controleert en reageert. De extensie om je zorgen over te maken is degene die nooit een beveiligingsfix publiceert.

Twee selectiegewoonten voorkomen de meeste ellende vooraf: installeer alleen extensies van betrouwbare ontwikkelaars met een staat van dienst, en kies bij voorkeur extensies die aansluiten op Joomla's eigen updatemechanisme, zodat nieuwe versies automatisch verschijnen onder Systeem → Update → Extensies. De officiele Joomla Extension Directory (JED) markeert die vermeldingen met "Uses Joomla! Update System" - beschouw een vermelding zonder dat kenmerk als een waarschuwingssignaal.

2.3 PHP en de server-stack

Een verouderde PHP-versie krijgt geen beveiligingsfixes meer, hoe actueel je Joomla ook is. Draai een PHP-versie die actief ondersteund wordt, en houd ook MariaDB/MySQL en de webserver bij. Als bonus zijn nieuwere PHP-versies meestal sneller.

Je hoeft die ondersteuningsdata niet te gokken. De officiele pagina met ondersteunde PHP-versies toont precies wanneer elke PHP-tak stopt met bugfixes en wanneer de periode van alleen-beveiligingsfixes eindigt. Voor de rest van de stack houdt endoflife.date dezelfde data bij voor MariaDB, MySQL en vrijwel elk ander onderdeel dat je draait. Zet de relevante data in je agenda en plan de upgrade voordat de ondersteuning stopt, niet nadat je host de overstap afdwingt.

2.4 Voordat je updatet

Updates zijn veel minder eng met een routine: maak een back-up, lees de release notes, update, en test de site. Beheer je een bedrijfskritische site, test de update dan eerst op een kopie van de site.

Naar boven

3. Bescherm gebruikersaccounts

3.1 Sterke wachtwoordregels

Joomla laat je wachtwoordsterkte afdwingen voor alle gebruikers. Open Gebruikers → Beheren → Opties → Wachtwoordopties en stel in:

OptieBetekenis
minimum_length Minimale wachtwoordlengte. Maak dit minstens 12.
minimum_integers Minimaal aantal cijfers.
minimum_symbols Minimaal aantal symbolen.
minimum_uppercase / minimum_lowercase Minimaal aantal hoofdletters en kleine letters.

Lengte wint van complexiteit: een lange wachtwoordzin is sterker en makkelijker te onthouden dan een korte cryptische reeks. Joomla slaat elk wachtwoord op als een gezouten bcrypt-hash, nooit als platte tekst, en vervangt oude hashes stilletjes door sterkere wanneer een gebruiker inlogt.

3.2 Multi-factor authenticatie

Zelfs een sterk wachtwoord kan lekken. Multi-factor authenticatie (MFA) vraagt om een tweede bewijs na het wachtwoord, en Joomla levert vijf methoden in de plugin-groep multifactorauth:

PluginTweede factor
Verificatiecode (TOTP) Een 6-cijferige code uit een authenticator-app.
Passkeys (WebAuthn) Een hardwaresleutel, vingerafdruk of passkey op je apparaat. De sterkste optie.
YubiKey Een YubiKey hardware-token in OTP-modus.
Code per e-mail Een eenmalige code per e-mail. Beter dan niets.
Vaste code Een statische tweede code. Alleen om te testen, geen echte beveiliging.

Gebruikers stellen hun methoden in op hun eigen profiel, en Joomla bewaart de aangemelde methoden in de tabel #__user_mfa. In Gebruikers → Beheren → Opties kun je MFA verplichten voor specifieke gebruikersgroepen; begin met elke groep die op de backend kan inloggen. Joomla vertraagt ook mislukte MFA-pogingen (de opties mfatrycount en mfatrytime), zodat een tweede factor niet ongemerkt gebruteforcet kan worden.

3.3 Super User-hygiene

  • Houd het aantal Super Users zo klein mogelijk, het liefst een of twee.
  • Gebruik een Super User-account nooit voor dagelijks redactiewerk. Gebruik daarvoor een Administrator- of Editor-account.
  • Noem het account geen admin, en hergebruik het wachtwoord nergens anders.
  • Geef iedereen een eigen account. Gedeelde accounts maken logs nutteloos en offboarding onmogelijk.
  • Verwijder of blokkeer accounts van mensen die vertrokken zijn. Loop de gebruikerslijst een paar keer per jaar na.

3.4 Geef iedereen het minimum dat nodig is

Met de toegangsrechten van Joomla geef je een redacteur precies de rechten om artikelen te bewerken en niets meer. Wie geen extensies kan installeren, kan ook geen kwaadaardige extensie installeren, zelfs niet als het account gestolen wordt. Het principe heet least privilege: elk account krijgt de kleinste set rechten waarmee de persoon zijn werk nog kan doen.

Naar boven

4. Belangrijke instellingen in de Algemene configuratie

4.1 Forceer HTTPS

Zet in Systeem → Algemene configuratie → Server de optie Forceer HTTPS (force_ssl) op Gehele site. Elk wachtwoord, elke sessiecookie en elk API-token reist dan versleuteld. Er is geen goede reden meer om ook maar een pagina over gewoon HTTP te serveren; certificaten zijn gratis met Let's Encrypt.

4.2 Verberg fouten in productie

Zet Foutrapportage (error_reporting) op Geen en houd Debug systeem (debug) uit op een live site. Foutmeldingen en debug-uitvoer onthullen bestandspaden, databasequery's en versiedetails, precies de verkenning die een aanvaller zoekt. Zet ze alleen aan terwijl je actief problemen onderzoekt, en daarna weer uit.

4.3 Sessies en cookies

InstellingAdvies
session_handler Houd Database aan, tenzij je een reden hebt (zoals Redis) om te wisselen.
Sessieduur Zo kort als praktisch is. 15-30 minuten voor de backend is redelijk.
session_metadata Aan laten: het voedt de "wie is online"-gegevens en laat je sessies zien die er niet horen te zijn.
shared_session Uit laten, tenzij je echt een login voor site en administrator samen nodig hebt. Gescheiden sessies beperken schade.
cookie_domain / cookie_path Leeg laten tenzij je zeker weet dat je ze nodig hebt; een verkeerde waarde kan cookies laten lekken naar buurdomeinen.

4.4 Andere schakelaars om te kennen

  • Site offline (offline): gebruik het tijdens onderhoud, zodat half afgemaakte toestanden niet publiek zijn. De plugin Task - Site Status kan het inplannen.
  • Frontend bewerken (frontediting): schakel het bewerken van modules en menu's vanaf de frontend uit als redacteuren het niet gebruiken.
  • Massamail (massmailoff): schakel massamail uit als je het niet gebruikt; een gekaapte backend kan dan niet spammen vanaf jouw domein.
  • CAPTCHA (captcha): schakel er een in voor registratie- en contactformulieren tegen bot-aanmeldingen en formulierspam.

4.5 De geheime sleutel

Je configuration.php bevat een waarde $secret die Joomla gebruikt voor token- en HMAC-berekeningen, bijvoorbeeld voor de API-tokens van de Web Services API. Behandel het hele bestand als een wachtwoord: plak het nooit in een forumbericht, een ticket of een publieke repository.

Naar boven

5. Server hardening

5.1 Activeer de meegeleverde regels

Joomla levert een kant-en-klare Apache-configuratie mee als htaccess.txt. Hernoem het naar .htaccess (toch al nodig voor SEF-URL's) en je krijgt meerdere beschermingen cadeau:

  • Options -Indexes: niemand kan door je mappen bladeren op zoek naar interessante bestanden.
  • Een X-Content-Type-Options "nosniff"-header: browsers stoppen met het raden van bestandstypen, wat een klasse van content-smokkel-aanvallen blokkeert.
  • Een content security-regel voor geuploade SVG-bestanden, die anders scripts kunnen bevatten.
  • Blokkeerregels die verzoeken met duidelijke aanvalspatronen in de URL weigeren voordat Joomla uberhaupt draait.

Op IIS is het equivalente bestand web.config.txt. Op nginx vertaal je de regels naar je server block, want nginx leest geen .htaccess-bestanden.

5.2 Extra bescherming voor de backend

De inlogpagina op /administrator is de meest aangevallen URL van elke Joomla-site. Bots bestoken hem de hele dag met wachtwoordpogingen. Populaire tegenmaatregelen, ongeveer op volgorde van moeite:

  • Verplicht MFA voor alle backend-gebruikers (zie sectie 3). Dat maakt wachtwoord raden kansloos.
  • Zet HTTP Basic-authenticatie of een IP-allowlist op de map /administrator op serverniveau, zodat bots de Joomla-login nooit bereiken.
  • Gebruik een firewall of een fail2ban-achtig gereedschap op server- of hostingniveau om IP-adressen na herhaalde mislukkingen te blokkeren. Joomla core vergrendelt accounts niet na mislukte logins, dus rate limiting hoort in deze laag of in een beveiligingsextensie.

5.3 Kies je hosting bewust

Op goedkope shared hosting zonder goede scheiding kan een gecompromitteerde buursite soms bij jouw bestanden. Vraag je host hoe accounts van elkaar gescheiden zijn (bijvoorbeeld PHP-FPM-pools per gebruiker en open_basedir-restricties), of ze een web application firewall draaien, en hoe snel ze de stack patchen. Een paar euro per maand koopt hier veel veiligheid.

5.4 PHP hardening-instellingen

Een paar php.ini-instellingen sluiten deuren die Joomla zelf niet kan sluiten. Op managed hosting staan sommige al goed; op je eigen server stel je ze zelf in:

InstellingAanbevolenWaarom
display_errors Off PHP-fouten op het scherm lekken paden en codedetails. Log ze in plaats daarvan (log_errors = On).
expose_php Off Voorkomt dat PHP zijn versie in elke response-header aankondigt.
allow_url_include Off Blokkeert het includen van externe bestanden, de klassieke remote-file-inclusion-aanval.
open_basedir de paden van je site Beperkt de bestandstoegang van PHP tot de eigen mappen van de site.
disable_functions bijv. exec, shell_exec, system, passthru, proc_open, popen Verwijdert shell-functies die de meeste sites nooit nodig hebben, favoriet gereedschap van geuploade malware.

Test de site na het wijzigen van open_basedir of disable_functions: een paar extensies gebruiken de strengere functies legitiem, en dat ontdek je liever op een testkopie dan in productie.

5.5 Database-account hardening

De databasegegevens in configuration.php verdienen dezelfde zorg als een Super User-account:

  • Geef elke site een eigen database en een eigen databasegebruiker. Een gedeeld DB-account over sites heen betekent dat een gehackte site ze allemaal blootlegt.
  • Geef die gebruiker alleen de rechten die Joomla nodig heeft op de eigen database - nooit globale rechten zoals GRANT, SUPER of FILE, en geen toegang tot andere databases.
  • Gebruik een lang gegenereerd wachtwoord. Je typt het nooit; het staat alleen in configuration.php.
  • Schakel externe databasetoegang uit tenzij je die echt nodig hebt. Een database die alleen op localhost luistert, kan niet vanaf het internet worden aangevallen.

5.6 Een web application firewall

Een web application firewall (WAF) inspecteert verzoeken voordat ze Joomla bereiken en blokkeert bekende aanvalspatronen: SQL-injectiepogingen, kwaadaardige uploads, agressieve bots. Gangbare opties zijn Cloudflare (als proxy voor je site, inclusief rate limiting en botbescherming) en ModSecurity met de OWASP Core Rule Set op je eigen Apache of nginx.

Een WAF is een ondersteunende laag, geen vervanging voor updates: hij kan een verse extensie-kwetsbaarheid "virtueel patchen" en je tijd kopen, maar de echte oplossing blijft de update installeren. Biedt je host een WAF, zet hem dan aan; draai je een eigen server, dan is ModSecurity plus de Core Rule Set het standaard startpunt.

Naar boven

6. HTTP security headers

6.1 De ingebouwde HTTP Headers-plugin

Joomla levert een plugin System - HTTP Headers (plg_system_httpheaders) mee die moderne browser-beveiligingsheaders verstuurt zonder aan de serverconfiguratie te komen. Schakel hem in onder Systeem → Plugins en stel in:

HeaderWaartegen hij beschermt
X-Frame-Options Clickjacking: andere sites kunnen jouw pagina's niet in een verborgen frame tonen.
Strict-Transport-Security (HSTS) Protocol-downgrades: browsers weigeren je site ooit nog over gewoon HTTP te laden. Opties voor max-age, subdomeinen en preload.
Referrer-Policy Het lekken van volledige URL's van jouw pagina's naar sites waarnaar je linkt.
Cross-Origin-Opener-Policy Andere vensters die een scriptbare verwijzing naar jouw pagina's houden.
Content-Security-Policy (CSP) Cross-site scripting: de browser voert alleen scripts uit die jij expliciet toestaat.

6.2 Een Content Security Policy uitrollen

CSP is de krachtigste header en tegelijk degene waarmee je je site het makkelijkst breekt, omdat templates en extensies scripts van veel plekken laden. De plugin ondersteunt een veilig uitrolpad:

  1. Schakel CSP in in de modus Report-Only. De browser meldt overtredingen in de console maar blokkeert niets.
  2. Klik door de site en de backend, verzamel wat er zou breken, en voeg de benodigde directives toe.
  3. Schakel van report-only naar afdwingen zodra de console schoon blijft.

De plugin kan ook nonces en script-hashes genereren voor inline scripts, zodat je het gevaarlijke sleutelwoord unsafe-inline kunt vermijden. Test HSTS eerst met een korte max-age; de preload-optie is bijna onomkeerbaar, dus schakel die pas in als je zeker weet dat elk subdomein voor altijd HTTPS draait.

Naar boven

7. Bestanden, mappen en rechten

7.1 Verstandige bestandsrechten

Op een typische Linux-host horen bestanden 644 te zijn en mappen 755, in eigendom van het account waaronder PHP draait. Gebruik nooit 777; daarmee mag elk proces op de server in je bestanden schrijven. Als een extensie alleen met 777 werkt, vertelt die extensie je iets over zijn kwaliteit.

Je kunt een stap verder gaan en configuration.php alleen-lezen maken (444). Joomla vraagt om het te versoepelen wanneer je de Algemene configuratie opslaat, en daarna zet je het terug.

7.2 Geen restanten in de webroot

Oude back-ups (site-backup.zip), databasedumps (dump.sql), phpinfo-bestanden en vergeten testkopieen (/old/, /backup/) zijn cadeautjes voor aanvallers, die precies op deze namen scannen. Bewaar back-ups buiten de webroot, en verwijder wat je niet meer nodig hebt. De plugin Task - Check Files kan volgens schema op te grote bestanden scannen, wat ook verdwaalde archieven vangt.

7.3 Verplaats wat niet publiek hoort te zijn

Joomla laat je de mappen tmp en log verplaatsen via Pad naar de tijdelijke map en Pad naar de logmap in de Algemene configuratie. Wijs beide naar een plek buiten de webroot, zodat de inhoud nooit gedownload kan worden. Vooral logbestanden kunnen paden en gebruikersnamen lekken.

Sinds Joomla 5 kunnen nieuwe installaties verder gaan en de hele site serveren vanuit een aparte publieke map: alleen de toegangspunten en assets staan in de webroot (JPATH_PUBLIC), terwijl de applicatiecode, configuratie, logs en tijdelijke bestanden een niveau hoger staan, buiten bereik van de webserver. Begin je een nieuw project, overweeg deze indeling dan vanaf dag een.

7.4 Upload-instellingen

Houd in Inhoud → Media → Opties de lijst met toegestane extensies zo kort als je redactie nodig heeft. Wees voorzichtig met SVG-uploads: SVG is een XML-formaat dat scripts kan bevatten. Moet je het toch toestaan, dan bevat de meegeleverde .htaccess een regel die voorkomt dat geuploade SVG's scripts uitvoeren.

Naar boven

8. Verklein het aanvalsoppervlak

8.1 Verwijder wat je niet gebruikt

Elke geinstalleerde extensie is code die een kwetsbaarheid kan bevatten, zelfs als hij uitgeschakeld is. Ga naar Systeem → Beheren → Extensies en deinstalleer (niet alleen uitschakelen) extensies die je niet gebruikt. Minder extensies betekent ook snellere updates en minder conflicten.

8.2 Kies extensies als een scepticus

  • Kies bij voorkeur extensies van ontwikkelaars die changelogs publiceren en op beveiligingsmeldingen reageren.
  • Controleer de Vulnerable Extensions List (VEL) op de Joomla-website voor en na het installeren.
  • Vermijd verlaten extensies: jaren geen update is een rode vlag, geen teken van stabiliteit.
  • Installeer nooit nulled of illegale commerciele extensies. Ze zijn een bekend malwarekanaal.

8.3 Schakel ongebruikte toegangspunten uit

  • Gebruik je de Web Services API niet, schakel dan de plugins in de groep api-authentication en de plugin-groep Web Services uit.
  • Gebruik je nooit HTTP Basic-authenticatie voor de API, houd die plugin dan uitgeschakeld en vertrouw op tokens (zie sectie 12).
  • Schakel frontend-registratie uit (Gebruikers → Opties → Gebruikersregistratie toestaan) als de site geen bezoekersaccounts nodig heeft.

8.4 Over security by obscurity

Het hernoemen van de database-prefix, het verbergen van versienummers of het maskeren van de login-URL maakt het voor oppervlakkige scanners iets lastiger, maar houdt geen vastberaden aanvaller tegen. Doe deze dingen als ze je weinig moeite kosten, maar reken ze nooit als echte bescherming. Updates, MFA en least privilege doen het zware werk.

Naar boven

9. Monitoring, logging en geplande taken

9.1 Actielogs: wie deed wat

De gebruikersactielog (com_actionlogs met de plugin System - User Actions Log) registreert backend-activiteit: logins, extensie-installaties, artikelbewerkingen, configuratiewijzigingen. Bekijk hem onder Gebruikers → Gebruikersactielog. Na een incident beantwoordt deze log de cruciale vraag "wat is er gebeurd, en met welk account?". De plugin Task - Delete Action Logs ruimt oude regels volgens schema op, zodat de tabel niet eindeloos groeit.

9.2 Log mislukte logins

De plugin System - Log schrijft mislukte inlogpogingen naar een logbestand (hij abonneert zich op het event onUserLoginFailure). Een plotselinge golf mislukkingen in dat bestand is je vroege waarschuwing voor een wachtwoord-raad-aanval. De plugin Task - Rotate Logs voorkomt dat logbestanden onbeperkt groeien.

9.3 Zet de taakplanner aan het werk

De taakplanner (com_scheduler) draait onderhoudstaken die je beveiliging stilletjes ondersteunen:

Taak-pluginBeveiligingswaarde
updatenotification E-mailt je wanneer er een Joomla-update beschikbaar is.
rotatelogs Roteert logbestanden.
deleteactionlogs Ruimt de gebruikersactielog op.
sessiongc Ruimt verlopen sessies op.
checkfiles Vindt te grote bestanden, zoals vergeten archieven.
globalcheckin Checkt items in die vergrendeld achterbleven door verdwenen gebruikers.

Trigger de taakplanner betrouwbaar met een echte cronjob of de webcron-URL, niet alleen met backend-bezoeken.

9.4 Kijk ook van buitenaf

Vul de interne logs aan met een externe uptime-monitor en het liefst een periodieke malwarescan van de gerenderde site. Google Search Console waarschuwt je wanneer Google je site markeert; die waarschuwing hoort nooit het eerste moment te zijn waarop je van een hack hoort, maar sluit hem toch aan.

Naar boven

10. Back-ups: je vangnet

10.1 Hardening omvat ook herstel

Geen enkele hardening neemt het risico volledig weg, dus een geteste back-up hoort bij beveiliging. Een goede back-uproutine volgt de 3-2-1-regel: drie kopieen van je data, op twee verschillende soorten opslag, waarvan een weg van de webserver. Een back-up die alleen op de gehackte server staat, wordt samen met de site versleuteld of verwijderd.

10.2 Wat een Joomla-back-up moet bevatten

  • Alle bestanden, inclusief configuration.php, templates en de map images.
  • Een dump van de complete database.

Gereedschappen zoals Akeeba Backup verpakken beide in een herstelbaar archief en kunnen het automatisch naar externe opslag sturen. Welk gereedschap je ook gebruikt: test een restore minstens een keer, op een aparte locatie. Een ongeteste back-up is een hoop, geen plan.

10.3 Back-ups na een incident

Bewaar meerdere generaties back-ups. Als een site al weken gecompromitteerd was voordat je het merkt, bevat de back-up van gisteren de backdoor ook, en ben je blij met een oudere, schone versie om mee te vergelijken.

10.4 Als het toch misgaat: incident response

Ontdek je een hack, weersta dan de neiging om meteen verdachte bestanden te gaan verwijderen. Werk vier fasen in volgorde af:

  1. Indammen: haal de site offline en vervang elk toegangsgegeven - Joomla-wachtwoorden, API-tokens, het databasewachtwoord, hosting-, FTP- en SSH-accounts. Ga ervan uit dat ze allemaal bekend zijn.
  2. Onderzoeken: gebruik de actielogs, de log van mislukte logins en de toegangslogs van de server om te achterhalen wanneer en hoe de aanvaller binnenkwam. Noteer de tijdstempels van gewijzigde bestanden.
  3. Opruimen: zet een back-up terug van voor de inbraak, of maak de bestanden schoon aan de hand van een verse Joomla-download en een schone extensieset. Update daarna alles, want het oorspronkelijke gat zit er meestal nog.
  4. Herstellen en leren: breng de site weer online, houd de logs een paar weken scherp in de gaten, en repareer de kernoorzaak - de verouderde extensie, het zwakke wachtwoord, de ontbrekende MFA.

De meest gemaakte fout is stap 2 overslaan: een site die wordt schoongemaakt zonder het toegangspunt te kennen, raakt meestal binnen dagen opnieuw besmet via dezelfde deur.

Naar boven

11. Onder de motorkap (ontwikkelaarsblik)

11.1 Wat Joomla al beschermt

De Joomla core verdedigt tegen de klassieke webaanvallen, en weten hoe helpt je die bescherming intact te houden:

AanvalVerdediging in de core
SQL-injectie De database-API met prepared statements en parameter binding.
Cross-site scripting (XSS) Invoerfiltering (InputFilter), uitvoer-escaping en de CSP header-plugin.
Cross-site request forgery (CSRF) Een formuliertoken per sessie, gecontroleerd bij elk verzoek dat iets wijzigt.
Wachtwoorddiefstal uit de database Gezouten bcrypt-hashes; platte wachtwoorden worden nooit opgeslagen.
Timing-aanvallen op tokens Vergelijkingen in constante tijd via Crypt::timingSafeCompare().

11.2 CSRF-tokens in je eigen code

Elk formulier dat data wijzigt heeft het token nodig. In de formulierlayout:

<?php echo Joomla\CMS\HTML\HTMLHelper::_('form.token'); ?>

En in de controller die het verzoek ontvangt:

$this->checkToken();   // throws on a missing or invalid token

Sla je dit over, dan kan elke willekeurige website jouw formulier versturen namens een ingelogde gebruiker.

11.3 Veilig query'en

Plak gebruikersinvoer nooit in SQL. Bind hem:

use Joomla\Database\ParameterType;

$query = $db->getQuery(true)
    ->select($db->quoteName('id'))
    ->from($db->quoteName('#__content'))
    ->where($db->quoteName('created_by') . ' = :userId')
    ->bind(':userId', $userId, ParameterType::INTEGER);

11.4 Escape bij uitvoer

Invoer filteren is niet genoeg; escape op het moment van uitvoer, in de layout:

<?php echo $this->escape($item->title); ?>

De vuistregel: filter invoer, escape uitvoer, en laat de databaselaag waarden quoten. Elke verdediging vangt gevallen op die de andere missen.

11.5 Controleer rechten, geen aannames

Controleer in componenten de autorisatie expliciet voordat je iets doet:

$user = $this->getUserFactory()->loadUserById($userId);

if (!$user->authorise('core.edit', 'com_example')) {
    throw new \Exception(Text::_('JERROR_ALERTNOAUTHOR'), 403);
}

Een knop verbergen is cosmetica; de controle in de code is de beveiliging.

11.6 Waar de beveiligingsdata staat

TabelRol
#__users Accounts, bcrypt-wachtwoordhashes, blokkeer- en activatievlaggen.
#__user_mfa Aangemelde multi-factor authenticatiemethoden per gebruiker.
#__action_logs De regels van de gebruikersactielog.
#__session Actieve sessies (met de database-sessiehandler).
#__extensions Welke extensies en plugins ingeschakeld zijn.
Naar boven

12. De Web Services API beveiligen

12.1 Tokens, geen wachtwoorden

De Joomla API authenticeert met de plugin-groep api-authentication. Kies de Token-plugin boven Basic-authenticatie: een token kun je los intrekken, terwijl een gelekt Basic-wachtwoord het hele account compromitteert. Een typische aanroep:

curl -H "X-Joomla-Token: <token>" \
     https://example.test/api/index.php/v1/users

12.2 Houd de token-kring klein

Standaard mogen alleen Super Users met een token authenticeren. De parameter allowedUserGroups van de plugin User - Joomla API Token verruimt dat; verruim zo min mogelijk, en maak voor elke integratie een aparte gebruiker met weinig rechten in plaats van een Super User-token uit te delen. Een API-gebruiker heeft exact dezelfde rechten als dezelfde gebruiker op de website, dus least privilege geldt ook hier.

12.3 Gebruik je de API niet?

Schakel de API- en Web Services-plugins dan helemaal uit. Een toegangspunt dat uit staat, kan niet worden aangevallen. Je zet ze weer aan op de dag dat je echt headless toegang nodig hebt.

Naar boven

13. SEO en metadata

Beveiliging en SEO hangen sterker samen dan het lijkt. Een gehackte site is een SEO-ramp: zoekmachines herkennen geinjecteerde spamlinks, doorway-pagina's en malware snel, markeren de site met een waarschuwing, en posities waar je jaren aan bouwde verdwijnen in dagen. De blocklist-status daarna opruimen duurt veel langer dan de hack zelf.

De positieve kant: HTTPS is een bevestigd rankingsignaal, en de redirect naar HTTPS bundelt je URL's. Security headers zoals HSTS laten browsers je domein vertrouwen. En een bijgewerkte, snelle, stabiele site is precies waar zoekmachines bezoekers naartoe willen sturen. Elk uur dat je aan hardening besteedt, beschermt stilletjes ook je zoekverkeer.

Naar boven

14. Veelvoorkomende fouten en valkuilen

14.1 "De site werkt, dus ik blijf eraf"

Symptoom: een site draait jaren zonder updates omdat iedereen bang is iets te breken.

Oplossing: hoe langer je wacht, hoe riskanter de uiteindelijke update wordt, en hoe langer bekende kwetsbaarheden open blijven. Update in kleine, frequente stappen met back-up, in plaats van een grote riskante sprong.

14.2 Debug-modus aan in productie

Symptoom: bezoekers zien databasequery's, bestandspaden of PHP-meldingen onderaan pagina's.

Oplossing: zet Debug systeem uit en zet Foutrapportage op Geen in de Algemene configuratie. Onderzoek fouten in de logbestanden.

14.3 Back-ups opgeslagen in de webroot

Symptoom: backup.zip of dump.sql is downloadbaar voor iedereen die de naam raadt, en geeft je hele site weg inclusief configuration.php.

Oplossing: bewaar back-ups buiten de webroot en buiten de server. Verwijder verdwaalde archieven nu; scanners zoeken er continu naar.

14.4 Iedereen is Super User

Symptoom: vijf mensen delen twee Super User-accounts, "omdat dat makkelijker is".

Oplossing: een account per persoon, minimale rechten per rol, MFA op elk backend-account. Logs worden betekenisvol en een gestolen redacteurswachtwoord betekent niet langer een gestolen site.

14.5 Extensies uitgeschakeld in plaats van verwijderd

Symptoom: de extensielijst staat vol uitgeschakelde restanten van experimenten van jaren geleden.

Oplossing: deinstalleer ze. Bestanden van uitgeschakelde extensies staan nog op de schijf en sommige blijven direct bereikbaar. Deinstalleren verwijdert de code en de update-zorgen.

14.6 Een CSP die de site ooit brak, dus hij blijft uit

Symptoom: iemand schakelde de Content-Security-Policy-header in, het template brak, en de hele HTTP Headers-plugin ging voorgoed uit.

Oplossing: schakel de plugin met de veilige headers (X-Frame-Options, Referrer-Policy, HSTS) meteen weer in, en rol CSP apart uit in report-only-modus tot de browserconsole schoon blijft.

Naar boven

15. Best practices

Als je maar een paar dingen uit dit artikel onthoudt, onthoud dan deze:

  • Update Joomla, extensies en PHP snel. Deze ene gewoonte voorkomt de meeste hacks.
  • Verplicht MFA voor elk backend-account, en houd het aantal Super Users minimaal.
  • Forceer HTTPS op de hele site, en schakel de HTTP Headers-plugin in.
  • Deinstalleer ongebruikte extensies; check de Vulnerable Extensions List voordat je nieuwe kiest.
  • Houd foutrapportage en debug-modus uit in productie.
  • Bewaar back-ups extern volgens de 3-2-1-regel, en test een restore.
  • Zet de gebruikersactielog en het loggen van mislukte logins aan, en lees ze ook echt.
  • Laat de taakplanner de terugkerende klusjes doen: update-notificaties, logrotatie, sessie-opruiming.
  • Ontwikkelaars: controleer CSRF-tokens, bind queryparameters, escape uitvoer, en controleer rechten in code.
Naar boven

16. In het kort

UPDATES      Systeem > Update > Joomla / Extensies
             Task - Update Notification plugin + taakplanner
             Joomla 6 verifieert core-updates met TUF-ondertekening

ACCOUNTS     Gebruikers > Beheren > Opties
             wachtwoordregels: minimum_length 12+
             MFA-plugins: TOTP, Passkeys, YubiKey, E-mail, Vast
             MFA per groep verplicht; weinig Super Users; geen gedeelde accounts

CONFIG       force_ssl        Gehele site
             error_reporting  Geen        debug  Uit
             sessieduur kort              shared_session Uit

SERVER       hernoem htaccess.txt > .htaccess   (-Indexes, nosniff)
             bestanden 644 / mappen 755, configuration.php 444
             tmp- + log-mappen buiten de webroot
             geen back-ups/dumps in de webroot
             php.ini: display_errors Off, expose_php Off,
                      allow_url_include Off, open_basedir ingesteld
             DB: eigen gebruiker per site, minimale rechten,
                 alleen localhost
             WAF: Cloudflare of ModSecurity + OWASP Core Rule Set

HEADERS      System - HTTP Headers plugin
             X-Frame-Options, HSTS, Referrer-Policy, COOP
             CSP: start Report-Only → repareer → afdwingen

MONITOR      Gebruikers > Gebruikersactielog   (com_actionlogs)
             System - Log plugin               (mislukte logins)
             taakplanner: rotatelogs, deleteactionlogs, sessiongc

API          kies Token boven Basic auth
             smalle allowedUserGroups, aparte API-gebruikers
             ongebruikt? schakel de API-plugins uit

DEV          checkToken() op elk formulier
             bind() parameters, escape() uitvoer
             $user->authorise() voordat je iets doet

HERSTEL      3-2-1 back-ups, meerdere generaties, geteste restore
             gehackt? indammen > onderzoeken > opruimen > herstellen
             ruim nooit op zonder het toegangspunt te vinden
Naar boven

17. Samenvatting

Een Joomla-site hardenen is geen heldendaad in een keer, maar een stapel verstandige gewoonten:

  • Updates eerst: core (ondertekend met TUF, optioneel automatisch), extensies en PHP. Verouderde software veroorzaakt de meeste hacks.
  • Accounts: sterke wachtwoordregels, multi-factor authenticatie met de ingebouwde plugins, weinig Super Users, least privilege voor iedereen.
  • Configuratie: overal HTTPS, fouten en debug verborgen, korte sessies.
  • Server: de meegeleverde .htaccess-regels, verstandige rechten, geen restanten of back-ups in de webroot.
  • Headers: de HTTP Headers-plugin levert bescherming tegen clickjacking, plus HSTS en CSP, zonder aan de server te komen.
  • Zichtbaarheid: actielogs, logs van mislukte logins, geplande onderhoudstaken en externe monitoring.
  • Herstel: externe, geteste back-ups in meerdere generaties voor de dag dat er toch iets misgaat.
  • Code: de Joomla core verdedigt tegen SQL-injectie, XSS en CSRF; ontwikkelaars houden die belofte in stand met tokens, gebonden parameters en uitvoer-escaping.

Geen van deze stappen is op zichzelf moeilijk. Samen veranderen ze je site van een makkelijk doelwit in een die aanvallers overslaan voor zachtere prooi.

Weet je niet zeker waar je site vandaag staat, dan is een gestructureerde security review de logische eerste stap: controleer de versies, de accounts, de instellingen en de logs in precies de volgorde van dit artikel. Zo'n methodische audit is exact het werk dat een Joomla-specialist regelmatig doet, en die vindt meestal de twee of drie deuren die ertoe doen voordat iemand anders dat doet.

Naar boven
Joomla beveiligen: security hardening in de diepte
Peter Martin
Peter Martin
Joomla Specialist

Peter is Joomla specialist en Linux admin voor snelle, veilige en schaalbare websites.

Gerelateerde artikelen