14. august 2026
WordPress & WooCommerce Strategi & værdi
Da et WordPress-site gik ned – og fejlen viste sig at være måneders skjult malware
Et dansk WordPress-site gik pludselig ned. Undersøgelsen viste måneder med skjult malware, cloaking og geninfektion. Her er forløbet og de vigtigste læringer.

Et dansk indholdssite bygget i WordPress gik pludselig ned med en forholdsvis generisk PHP-fejl. På overfladen lignede det noget, der kunne løses med den sædvanlige værktøjskasse: et plugin, der var gået i stykker, en mislykket opdatering, en PHP-konflikt eller en fejl i temaet.
Det viste sig hurtigt, at problemet var langt større. WordPress-installationen var kompromitteret.
Der lå filer, som ikke hørte hjemme på et normalt WordPress-site. Centrale filer var ændret, og der var tydelige tegn på, at uvedkommende havde haft mulighed for at arbejde direkte i filsystemet.
På det tidspunkt ændrede opgaven fuldstændig karakter. Det handlede ikke længere om at finde den ene linje kode, som fik hjemmesiden til at fejle. Det handlede om at finde ud af, hvad vi overhovedet kunne stole på:
- Hvor længe havde kompromitteringen stået på?
- Hvor meget var blevet ændret?
- Var databasen berørt?
- Kunne vi stole på backup?
- Hvordan var angriberen kommet ind?
- Og hvis hjemmesiden kom til at virke igen, hvordan kunne vi så vide, at vi ikke bare havde gjort den samme bagdør aktiv igen?
Det blev begyndelsen på en sag, der strakte sig langt ud over den fejlbesked, kunden oprindeligt så. Og nogle af de vigtigste erkendelser kom først, efter jeg havde erklæret sitet rent.
Før jeg ændrede noget, sikrede jeg sporene
Det mest fristende, når en hjemmeside ligger nede, er at begynde at reparere med det samme. Slet den mistænkelige fil. Geninstaller WordPress. Kør en backup tilbage. Få siden online.
Problemet er, at hver eneste ændring samtidig kan fjerne information om, hvad der faktisk er sket.
Derfor var en af de første opgaver at sikre materiale fra den eksisterende installation. Blandt andet blev der lavet et komplet inventar over filsystemet med filnavne, størrelser og tidsstempler, relevante mistænkelige filer blev gemt, og databasen blev sikret.
Først derefter blev den kompromitterede løsning isoleret, og der blev lagt en enkel midlertidig landingsside op, så besøgende ikke længere blev mødt af en grim PHP-fejl – eller risikerede at ramme kompromitteret indhold.
Det kan lyde som en lille forskel i rækkefølgen. Det var det ikke. Senere viste netop det oprindelige filinventar sig at være en af de mest værdifulde datakilder i hele analysen.
Ikke-nørdet forklaring
Hvis nogen har haft indbrud i et hus, begynder man heller ikke med at vaske gulvet og smide alt det mærkelige ud. Man tager først billeder. Man forsøger at se, hvordan nogen er kommet ind. Man undersøger, hvad der er rørt. Først bagefter rydder man op.
Et kompromitteret website bør behandles på nogenlunde samme måde.
Nedbruddet var ikke begyndelsen på angrebet
Det første store aha kom, da jeg begyndte at kigge bagud.
Sitet var gået ned nu. Men sporene viste, at kompromitteringen sandsynligvis havde stået på i omkring tre måneder.
Det ændrede hele perspektivet. Når en WordPress-installation pludselig fejler, spørger man naturligt: Hvad skete der i dag? Men det interessante spørgsmål var snarere: Hvad har stået på i flere måneder, uden at nogen har opdaget det?
Nedbruddet var ikke nødvendigvis angrebet. Det var blot det første tidspunkt, hvor angrebet blev synligt for de mennesker, der normalt brugte hjemmesiden.
Hjemmesiden kunne se helt normal ud – og stadig være kompromitteret

Et af de mere interessante elementer i sagen var cloaking. Kompromitteret kode kunne reagere forskelligt afhængigt af, hvem der besøgte hjemmesiden.
Den almindelige ejer fik det normale website. Danske besøgende fik det normale website. Redaktionen kunne arbejde videre uden at se noget mærkeligt. Men en søgemaskine eller besøgende med bestemte karakteristika kunne få noget helt andet.
I denne sag var der blandt andet tegn på, at søgemaskiner og visse udenlandske besøgende blev præsenteret for spamindhold, som de almindelige brugere aldrig så. Der var også manipulation omkring sitemap og robots.txt.
Det forklarer, hvordan kompromitteringen kunne leve relativt ubemærket i så lang tid.
Forestil dig en butik med to facader
Når ejeren kommer, står der det rigtige navn over døren. Varerne er på plads. Alt ser normalt ud. Men når en bestemt person går forbi, skifter facaden, skiltene og udstillingen.
Hvis ejeren aldrig bliver præsenteret for den alternative facade, kan det stå på længe.
Det er det farlige ved cloaking. Du kan åbne din hjemmeside hver morgen og se, at alt virker. Det er ikke det samme som, at alle andre bliver vist det samme.
Tegn på at et WordPress-site er hacket – også når forsiden ser fin ud
Netop fordi malware kan skjule sig for ejeren, er det værd at kende de signaler, der kommer uden om hjemmesidens forside. I denne sag og i lignende sager er det typisk noget af det her, der først vækker mistanke:
- Google Search Console rapporterer pludselig sider eller søgeord, du ikke selv har lavet.
- Din side optræder i søgeresultater med titler eller tekst på fremmede sprog.
- Antallet af indekserede sider stiger kraftigt uden nogen redaktionel forklaring.
- robots.txt eller sitemap indeholder noget, ingen kan huske at have tilføjet.
- Hostingudbyderen skriver om usædvanligt ressourceforbrug, spam-mails eller malware-fund.
- Der er filer i WordPress-mapperne med underlige navne, forkerte datoer eller filendelser, der ikke passer til indholdet.
- Der findes administratorbrugere, som ingen kan sætte navn på.
- Siden fejler eller opfører sig anderledes for besøgende udefra end for dig selv.
Ingen af punkterne er i sig selv bevis. Men flere af dem samtidig er en god grund til at kigge nærmere – i stedet for at vente på den fatale fejl.
Databasen var faktisk ren
Når man finder omfattende malware i et WordPress-site, er det let at begynde at mistænke alt. Men en vigtig del af arbejdet er også at fastslå, hvad der ikke er kompromitteret.
I denne sag var der ikke tegn på, at angriberen havde brugt databasen som opholdssted:
- Ingen skjulte administratorbrugere.
- Ingen injicerede WordPress-indstillinger.
- Ingen skjulte planlagte opgaver i databasen.
- Ingen egne tabeller eller anden persistens gemt dér.
Aktiviteten lå primært i filsystemet. Det var både teknisk interessant og praktisk vigtigt. Det reducerede mængden af data, jeg behøvede at betragte som mistænkelig, og det fortalte samtidig noget om angrebets karakter: angriberen havde allerede de muligheder, der var nødvendige, gennem filerne på serveren. Der var simpelthen ikke behov for at rode mere med databasen.
På et tidspunkt blev kompromitteringen meget mindre diskret
I den tidlige fase var kompromitteringen god til at gemme sig. Senere blev den langt mere aggressiv. Centrale WordPress-komponenter forsvandt, og der blev lagt en større webshell på serveren.
En webshell er groft sagt kode, som kan give en angriber mulighed for at interagere med serveren og udføre handlinger uden at skulle gennem WordPress' normale administration.
Det var omkring dette tidspunkt, hjemmesiden for alvor brød sammen. Paradoksalt nok var nedbruddet derfor også det, der endelig udløste undersøgelsen. Hvis kompromitteringen var fortsat med kun at vise spam til søgemaskiner og andre udvalgte besøgende, kunne den muligvis have stået på endnu længere.
En backup gjorde situationen mere kompliceret
Midt under forløbet blev der iværksat en backupgendannelse. Det var naturligvis gjort med ønsket om at få sitet tilbage. Men det introducerede et nyt problem.
Databasen og filerne blev ikke nødvendigvis gendannet til præcis samme tidspunkt. I en periode stod vi derfor med filer fra ét tidspunkt og databaseindhold fra et andet. Samtidig gik nogle dages redaktionelt indhold tabt.
Det er en ret væsentlig læring, fordi “vi har backup” ofte bliver betragtet som slutningen på diskussionen. Det er det ikke. En brugbar backupstrategi handler også om, hvorvidt man ved, hvad man gendanner. Hvis databasen er fra mandag og filerne fra torsdag, kan man ende med en installation, der aldrig reelt har eksisteret i den kombination.
Senere skete der noget, der illustrerede problemet endnu bedre. Der blev taget et helt nyt databasedump direkte fra produktionen. Backupfilen var frisk. Men indholdet i databasen var allerede blevet rullet tilbage. Man stod altså med en ny backupfil, som indeholdt gamle data.
En ny fil er ikke nødvendigvis nye data. Det lyder banalt, men det er først vigtigt den dag, man faktisk skal bruge den.
Første oprydning: så meget som muligt blev bygget op fra kilden igen

Når en WordPress-fil er kompromitteret, kan man selvfølgelig åbne den og forsøge at fjerne den skadelige kode. Men hvis filen kan hentes igen fra den oprindelige, verificerbare kilde, er det normalt langt mere tillidsvækkende.
Derfor blev WordPress-kernen erstattet med en ren kopi. Størstedelen af plugins kunne ligeledes geninstalleres direkte fra officielle kilder. Sikkerhedsnøglerne blev udskiftet, så eksisterende WordPress-sessioner blev ugyldige. De mest åbenlyse skadelige filer blev fjernet, og installationen blev kontrolleret igen.
På det tidspunkt havde jeg et site, som kunne verificeres som rent. Det virkede. Scanningerne var rene. De kompromitterede filer var væk.
Og så gik der cirka to dage.
Malwaren kom tilbage

Der dukkede nye webshells op. Et falsk plugin. Forsiden blev kompromitteret igen. Hostingudbyderen reagerede og suspenderede sitet.
Det var selvfølgelig ikke det resultat, man ønsker efter en omfattende oprydning. Men set bagefter var geninfektionen et af de bedste diagnostiske værktøjer i hele sagen.
Før første oprydning stod jeg med en installation, der havde været kompromitteret i flere måneder. Alt var blandet sammen: legitime ændringer, gamle filer, nye filer, malware, opdateringer, cache, uploads. Hundredtusindvis af elementer.
Efter første oprydning havde jeg derimod et kendt udgangspunkt. Når noget nyt dukkede op kun få dage senere, kunne jeg langt bedre spørge: Hvad er kommet tilbage, og hvilke mulige indgange havde jeg stadig ikke fjernet?
Geninfektionens indgang kunne jeg finde – den oprindelige kunne jeg ikke
Det er vigtigt at holde de to ting adskilt.
Den senere geninfektion kunne med rimelig høj sikkerhed kobles til et fjernstyringsplugin, der havde en offentligt kendt sårbarhed. Den konkrete sårbarhed gjorde det muligt at omgå normal autentificering og nå frem til installation af kode. Samtidig var single sign-on aktiveret.
Det plugin var netop ét af de plugins, der ikke kunne hentes på ny fra det almindelige WordPress-repository. Det var derfor blevet genbrugt fra den tidligere installation. Dermed var det sårbare komponent blevet lagt tilbage under oprydningen. Det forklarer geninfektionen meget godt.
Men det er ikke det samme som, at årsagen til det oprindelige angreb tre måneder tidligere dermed er kendt. Det er den ikke.
Tidsstemplerne viste faktisk, at dette plugin først var til stede efter de tidligste spor af malware. Der fandtes andre mulige kandidater – blandt andet en anden alvorlig sårbarhed, som tidsmæssigt passede langt bedre med starten på kompromitteringen. Men det kunne ikke bevises. Efter flere måneders kompromittering, efter ændringer på serveren og efter backupgendannelser var de nødvendige spor simpelthen ikke længere stærke nok.
Det er ikke et hul, der bør skjules i historien. Det er en af de vigtigste læringer: Jo længere et kompromitteret system får lov til at stå, desto sværere bliver det bagefter at fastslå præcist, hvordan det begyndte.
Oprydningen havde også et hul: adgangskoderne blev ikke skiftet
Der blev skiftet WordPress-sikkerhedsnøgler under første oprydning. Det var rigtigt at gøre. Det tvang eksisterende sessioner til at udløbe og gjorde gamle sessionscookies ugyldige.
Men selve administratorernes adgangskoder blev ikke skiftet på det tidspunkt. Det skete først senere.
Det viste sig ikke at være årsagen til geninfektionen. Men metodisk var det stadig en fejl. Når man ikke kender angrebsvejen med sikkerhed, bør man heller ikke antage, at legitimationsoplysninger ikke kan være kompromitteret. En ordentlig oprydning skal lukke alle rimelige veje tilbage – også dem, man bagefter finder ud af ikke blev brugt.
Det er værd at skrive åbent om, fordi sikkerhedsarbejde sjældent foregår med perfekt information. Man træffer beslutninger på baggrund af de spor, man har. Og bagefter skal man være villig til at sige: Den del skulle jeg have gjort anderledes.
WordPress-malware kan ligne næsten hvad som helst
Noget af skadekoden lå ikke pænt placeret i filer med navne som evil-malware.php. Tværtimod.
Nogle kopier havde filendelser, som normalt forbindes med billeder eller JavaScript. Andre havde navne, der bevidst lignede legitime WordPress-filer, men med små stavefejl. Et ekstra bogstav. To bogstaver byttet rundt. Noget, øjet let glider hen over.
Det er en vigtig pointe, fordi mange hurtige malwarekontroller netop leder efter bestemte filtyper og kendte mønstre. Hvis du kun scanner PHP-filer, men den interessante kopi ligger gemt som noget andet, kan du få et meget overbevisende grønt resultat, uden at installationen er ren.
Et uventet spor: filstørrelsen
En af de mere effektive teknikker i sagen kom ikke fra filnavnet. Den kom fra størrelsen.
Flere af de aktive malwarekomponenter havde helt karakteristiske filstørrelser. Da jeg begyndte at søge på tværs af hele filsystemet efter filer med præcis de størrelser, dukkede kopier op, som andre søgemetoder ikke havde fanget.
Det var en god påmindelse om, at kompromitteringsanalyse sjældent kan baseres på én egenskab. Filnavn kan snyde. Filendelse kan snyde. Tidsstempel kan manipuleres. En scanner kan tage fejl. Men når flere indikatorer peger samme vej, begynder billedet at blive stærkere.
Malwaren nøjedes ikke med at overleve – den modarbejdede oprydningen
Det mest interessante lag i kompromitteringen var måske dens persistens. Der fandtes ikke bare én skadelig fil. Der var flere komponenter med forskellige roller.
Nogle kunne genskabe kompromitterede filer fra skjulte kopier. Andre overvågede bestemte filer og lagde malwaren tilbage, hvis noget blev fjernet. Og én komponent gjorde noget endnu mere aggressivt: den gennemgik kørende processer og kunne afslutte andre PHP-processer, før den fortsatte sit eget arbejde.
I praksis betød det, at malwaren ikke bare passivt ventede på at blive slettet. Den kunne aktivt modarbejde processer omkring sig, gendanne sit eget miljø og fortsætte.
Ikke-nørdet forklaring
Forestil dig, at du forsøger at reparere et hus. Men inde i huset står en person, som hele tiden slukker dit værktøj, monterer den ødelagte dør igen, flytter sig til et nyt rum – og har gemt fire ekstra kopier af døren rundt omkring.
Så er løsningen ikke bare at være hurtigere til at fjerne døren. Man skal forstå hele systemet omkring den.
Angriberen havde endda “sikret” sine egne filer
En særlig .htaccess-konfiguration skilte sig ud. Den blokerede aggressivt eksekvering af PHP. Ved første øjekast kunne det næsten ligne en sikkerhedsforanstaltning.
Men nogle få specifikke filer blev whitelistet. De filer var relevante for angriberen.
Det vendte hele fortolkningen om. Formålet var ikke nødvendigvis at beskytte kundens WordPress-installation. Det lignede langt mere en måde at sørge for, at angriberens egne indgange fortsat kunne fungere, mens anden kode blev holdt ude.
Det er en ret fin illustration af, hvorfor man ikke altid kan afgøre, om noget er “sikkert”, bare ved at se på reglen isoleret. Konteksten betyder alt.
5 GB hjemmeside blev til et filinventar på få megabyte
Hele installationen fyldte omkring 5 GB og bestod af cirka 281.000 poster. Det er en upraktisk størrelse at analysere igen og igen.
Men en simpel liste med filnavn, sti, størrelse og tidsstempel kunne komprimeres til få megabyte. Og den fil blev ekstremt værdifuld. Med den kunne jeg undersøge tidsmønstre, finde bestemte størrelser, gruppere ændringer og sammenligne mapper – uden konstant at ændre den oprindelige installation.
Det er noget af det, jeg især tager med videre fra sagen. Når kompromitteringen opdages: sikr et inventar tidligt. Et filinventar kan ikke fortælle alt. Men det kan bevare et øjebliksbillede af systemet, før oprydningen begynder at ændre det.
Tidsstemplerne begyndte at fortælle en historie
Når hundredtusindvis af filer bliver til en struktureret liste, kan man begynde at se mønstre. Et af dem var tidspunktet.
Mistænkelige ændringer faldt igen og igen inden for det samme relativt snævre tidsrum tidligt om morgenen. Ikke den ene dag klokken 14, den næste klokken 22 og den tredje klokken 09. Det samme mønster gik igen.
Det pegede i retning af automatisering. Et menneske rammer før eller siden en eftermiddag. En planlagt proces gør ikke.
Da det tidsvindue først var kendt, kunne det bruges som endnu et filter og finde filer, som ikke nødvendigvis havde et mistænkeligt navn eller en kendt malware-signatur. Det er netop den type analyse, der bliver mulig, når man har bevaret det oprindelige materiale.
Hostingudbyderen havde den bedste historik over sårbarhederne
Et af de stærkeste spor kom overraskende nok ikke fra malwarefilerne.
Hostingudbyderen havde selv kørt sårbarhedsscanninger af WordPress-installationen. Historikken var gemt i databasen. Den viste blandt andet versioner, fund, tidspunkter og alvorlighed. Pludselig kunne jeg se:
- Hvornår havde forskellige sårbarheder stået åbne?
- Hvilke pluginversioner var aktive?
- Hvilke sårbarheder passede tidsmæssigt med kompromitteringens tidligste spor?
- Hvad fandtes stadig, da geninfektionen skete?
Det blev vigtigere end flere af de traditionelle malware-scanninger.
Der er en god generel læring i det: Hvis du står med et kompromitteret site, så spørg hostingudbyderen om mere end bare “Har I en backup?”. Spørg også efter de data, de allerede har opsamlet. De kan have logs og sikkerhedshistorik, som aldrig har været synlige i WordPress-administrationen.
Et sikkerhedsplugin kan give falsk tryghed

Sitet havde et sikkerhedsplugin. Det lyder umiddelbart betryggende. Problemet var konfigurationen.
Flere relevante scanningstyper var slået fra – blandt andet scanning af plugins og temaer. Og mailadressen til sikkerhedsadvarsler var tom.
Dermed havde man noget af infrastrukturen til at opdage ændringer. Men opsætningen gjorde, at det i praksis ikke fungerede som den sikkerhedsline, man kunne tro.
Det er måske værre end slet ikke at have et sikkerhedsplugin. For det lille grønne ikon i WordPress kan få en organisation til at tænke: Så er det klaret.
Men hvem får alarmen? Hvad scanner den? Hvor ofte? Hvilke filer springer den over? Hvad sker der, når den finder noget? Det er de interessante spørgsmål.
Her er forskellen på en installeret sikkerhedsløsning og løbende drift

Det er også dér, en serviceaftale kommer ind i billedet.
Jeg vil ikke påstå, at en serviceaftale kan gøre et WordPress-site umuligt at kompromittere. Det ville være useriøst. Men den kan ændre tidspunktet, hvor problemet opdages. Og det er enormt vigtigt.
I denne sag fandtes der flere forhold, som kunne have givet anledning til handling længe før den fatale PHP-fejl:
- Der var et stort antal ventende opdateringer.
- Der fandtes plugins med kendte sårbarheder.
- Der var gamle administratorbrugere.
- Sikkerhedsovervågningen var utilstrækkeligt konfigureret.
- Og kompromitteringen fik lov til at udvikle sig over måneder.
Med en aktiv WordPress-serviceaftale hos mig bliver den slags ikke kun kontrolleret den dag, hjemmesiden går ned. Opdateringer, sikkerhed og kendte sårbarheder bliver fulgt løbende. Ændringer i installationen kan fanges tidligere. Backup kontrolleres. Alarmer bliver sendt til nogen, der faktisk reagerer.
Det betyder, at vi kan arbejde proaktivt i stedet for reaktivt:
- En kritisk sårbarhed opdages, før den nødvendigvis bliver misbrugt.
- En mærkelig filændring kan undersøges, før sitet begynder at fejle.
- En gammel administrator kan fjernes, før kontoen bliver et problem.
- En fejlbehæftet backup kan opdages, før den skal redde hele hjemmesiden.
Det er efter min mening den største værdi i en serviceaftale. Ikke at nogen en gang om måneden klikker på “Opdater”. Men at nogen faktisk holder øje.
Opdag problemet, før dine besøgende gør
Med en WordPress-serviceaftale bliver opdateringer, sikkerhed, kendte sårbarheder og centrale ændringer fulgt løbende. Det gør det muligt at reagere langt tidligere, hvis noget begynder at se forkert ud.
Forensiske kopier blev selv opdaget som malware
Der opstod undervejs en lidt absurd situation.
Mistænkelige filer blev naturligvis bevaret til analyse og dokumentation. De blev placeret uden for den aktive webroot, så de ikke kunne afvikles som en del af hjemmesiden. Det er normalt fornuftigt.
Men hostingudbyderens malware-scanner undersøgte ikke kun webroot. Den scannede hele kontoen. Resultatet var, at flere af de “malware-fund”, som senere blev rapporteret, faktisk var mine egne isolerede kopier.
Filerne kunne ikke bruges til at kompromittere hjemmesiden dér, hvor de lå. Men scanneren kunne naturligvis kun se: Her ligger malware. Ikke: Denne malware ligger her, fordi nogen analyserer den.
Sitet blev derfor holdt nede på grund af materiale, der var gemt som bevis. Det er et godt eksempel på, at automatiske sikkerhedsværktøjer kan være både nyttige og blinde på samme tid.
Falske positiver kostede også rigtig tid
Når først man ved, at en installation har været kompromitteret, ændrer ens blik sig. Pludselig ser enhver mærkelig fil mistænkelig ud. Det er nødvendigt at være kritisk. Men det kan også skabe støj.
En legitim WordPress-kernefil blev mistænkt. En legitim pluginfil blev markeret af en scanner. En cache-struktur havde mappenavne, der lignede WordPress-filer og ved første øjekast lignede et rede af malware. Ingen af dem var problemet.
Det, der afgjorde dem, var sammenligning mod kendte originale filer og checksums. Det er langt stærkere end “den ser god nok ud” – eller “scannerens navn er rødt, så den må være malware”.
Sikkerhedsarbejde er ikke bare at finde flest mulige mistænkelige ting. Det er at kunne skelne mellem de farlige og de legitime.
Jeg lavede også selv analysefejl
Det vil være meget nemt at skrive en case som denne bagefter og få processen til at se lineær ud. Det var den ikke. Der var blindgyder. Der var antagelser, som viste sig at være forkerte. Og der var værktøjer, der gjorde præcis, hvad jeg bad dem om – men ikke det, jeg troede, jeg havde bedt dem om.
En kopieringskommando blev eksempelvis konfigureret til at ekskludere mapper med et bestemt navn. Den ekskluderede flere legitime pluginmapper længere nede i træet. Resultatet var, at gode filer forsvandt, og WordPress begyndte at fejle. I første omgang lignede det endnu et malwareproblem.
En anden søgning havde for lav dybde og gav et resultat, der kunne læses som “filen findes ikke”. Sandheden var: jeg havde ikke kigget langt nok ned.
Der var også en cloaking-test, hvor to parametre blev ændret samtidig. Det gav et resultat, men gjorde det umuligt bagefter at sige, hvilken af ændringerne der havde udløst det.
Og cacheområder blev i perioder holdt ude af scanningerne for at reducere støj. Dermed var der samtidig skabt et stort område, som ikke var blevet undersøgt.
Det er ikke de dele af en teknisk case, der får processen til at se mest elegant ud. Men de er nogle af de mest værdifulde. For hver fejl lærte jeg noget om, hvordan kontrollen burde bygges:
- Et negativt søgeresultat skal verificeres.
- Ekskluderinger skal dokumenteres.
- Én variabel bør ændres ad gangen.
- Og en kommando, der “virkede”, er ikke nødvendigvis bevis for, at den gjorde det, man troede.
Hvorfor skulle nogen hacke netop denne hjemmeside?
Det spørgsmål kommer ofte. Svaret er sandsynligvis: Det skulle de heller ikke.
Der var ikke meget, der tydede på et målrettet angreb mod en bestemt virksomhed. Langt mere pegede mod automatiseret scanning.
Robotter kan konstant afsøge internettet efter kendte versioner af WordPress, plugins og andre systemer. Når en ny sårbarhed bliver offentligt kendt, kan den automatiseres. Find versionen. Test hullet. Hvis det virker, fortsæt.
Det betyder, at en mindre virksomhed ikke nødvendigvis er uinteressant for en angriber. Den behøver ikke være interessant. Den skal bare være sårbar.
Mange ventende opdateringer ændrer risikobilledet
Sitet havde et betydeligt efterslæb af opdateringer. Det bliver let behandlet som almindelig teknisk vedligeholdelse: Vi tager lige opdateringerne, når vi får tid.
Men ikke alle opdateringer er lige. Når en kendt sikkerhedssårbarhed bliver offentliggjort, er situationen en anden. Der kan nu både eksistere offentlig viden om, hvordan komponenten fejler, og tusindvis af hjemmesider, som stadig kører den gamle sårbare version. Det er netop den slags situationer, automatiske scannere elsker.
Det betyder ikke, at alle opdateringer ukritisk skal installeres i produktion fem minutter efter release. En opdatering kan også ødelægge funktionalitet. Men den skal vurderes.
Et stort efterslæb gør det langt sværere at skelne mellem almindelige funktionsopdateringer, kompatibilitetsændringer og kritiske sikkerhedsrettelser. Det er endnu en grund til at behandle opdateringer som en løbende driftsopgave og ikke som et projekt hvert halve år.
Det samme gælder plugins og administratorer
Mange plugins er ikke automatisk et problem. Men hvert plugin er mere kode, der skal vedligeholdes.
Der var funktioner på sitet, som ikke længere blev brugt. Et plugin uden reel funktion giver stadig en opdateringsopgave, en ekstra leverandør og en mulig ny sårbarhed. Det er ikke et argument for at installere så få plugins som muligt for enhver pris. Det er et argument for, at hvert plugin skal kunne forklare sin eksistens.
Det samme gælder administratorbrugere. Der fandtes flere administratorer, herunder tidligere eksterne samarbejdspartnere, som ikke havde været aktive i meget lang tid. Hvis en person ikke længere har behov for administratoradgang, skal vedkommende heller ikke have den.
Det er grundlæggende oprydning. Men grundlæggende oprydning er ofte sikkerhed.
Og ja – 2FA skal stadig bruges
To-faktor-login er stadig en af de ting, jeg klart anbefaler til administratorer. Men den her sag viser samtidig, hvorfor man ikke må gøre 2FA til et magisk skjold.
Hvis et plugin har en sårbarhed, der gør det muligt at omgå den normale autentificeringsproces, hjælper det ikke nødvendigvis, at administratorens almindelige login er beskyttet af 2FA.
2FA beskytter især mod blandt andet stjålne og genbrugte adgangskoder. Patch management beskytter mod noget andet. Serverkonfiguration mod noget tredje. Overvågning mod noget fjerde. Sikkerhed består af lag.
Sådan ville jeg gribe WordPress-sikkerheden an efter denne sag

Jeg ville først og fremmest undgå at gøre sikkerhed til en årlig oprydningsdag. Det er selve driften, der gør forskellen.
| Område | Hvad der skal ske | Hvor ofte |
|---|---|---|
| Opdateringer | Vurdér og installer WordPress-, tema- og pluginopdateringer, med sikkerhedsrettelser først | Løbende |
| Kendte sårbarheder | Hold øje med sårbarhedsmeldinger for de komponenter, der faktisk er installeret | Løbende |
| Plugins og temaer | Fjern det, der ikke længere bruges — hvert plugin skal kunne forklare sin eksistens | Kvartalsvis |
| Brugere | Gennemgå administratorlisten og fjern gamle konti og tidligere samarbejdspartnere | Kvartalsvis |
| Backup | Tag backup — og test, at den faktisk kan gendannes, med filer og database i takt | Dagligt / test jævnligt |
| Overvågning | Sørg for, at scanninger er slået til, og at alarmerne lander hos nogen, der læser dem | Løbende |
| Filændringer | Reagér på ændringer i kernefiler og nye filer, der ikke kan forklares | Løbende |
| Adgang | 2FA på administratorer, unikke adgangskoder og styr på, hvem der har server- og hostingadgang | Løbende |
Et sundt WordPress-site er et site, hvor nogen løbende holder øje med, hvad der ændrer sig. Det er præcis sådan, jeg arbejder med WordPress-serviceaftaler.
Målet er ikke at love, at intet nogensinde kan ske. Målet er at reducere risikoen og forkorte tiden fra noget går galt, til vi opdager det. Det sidste er ekstremt vigtigt. Tre måneders skjult kompromittering er en helt anden opgave end en mistænkelig filændring opdaget samme dag.
Til sidst handlede opgaven om tillid – ikke bare om at få WordPress til at starte
Man kan få et WordPress-site til at vise forsiden ret hurtigt. Det er ikke nødvendigvis det samme som at have løst en kompromittering.
Efter en sikkerhedshændelse er det relevante spørgsmål ikke kun “virker hjemmesiden?”. Det er: Hvorfor mener vi, at vi kan stole på den igen?
- Kan vi stole på WordPress-kernen?
- Kan vi stole på plugins?
- Kan vi stole på de resterende filer?
- Kan vi stole på databasen?
- Kan vi stole på vores backup?
- Har vi lukket den kendte geninfektionsvej?
- Har vi behandlet de adgangsoplysninger, der kan være kompromitteret?
- Er overvågningen sat korrekt op?
- Kan vi opdage det, hvis noget kommer igen?
Det er forskellen mellem reparation og genetablering. Den ene får hjemmesiden til at virke. Den anden forsøger at gøre det forsvarligt at tage den i brug igen.
Fejlbeskeden var faktisk det mindst interessante ved hele sagen
Kunden kom med en hjemmeside, der var gået ned. Det var det synlige problem. Men efterfølgende viste det sig, at den fatale fejl næsten var en hjælp. Den tvang os til at undersøge noget, der ellers havde været skjult i måneder.
Det tager jeg med videre fra sagen
- En hjemmeside kan se helt normal ud og stadig være kompromitteret.
- Et nyt backupdump kan indeholde gamle data.
- Et installeret sikkerhedsplugin kan være næsten værdiløst, hvis det ikke er konfigureret.
- En grundig oprydning kan stadig fejle, hvis én sårbar komponent bliver geninstalleret.
- Det kan være umuligt at bevise den oprindelige angrebsvej, når der er gået for lang tid.
- Scannere kan tage fejl — og man kan selv lave fejl under analysen.
- Sikr et filinventar, før oprydningen begynder at ændre systemet.
Og geninfektionen, som umiddelbart var den dårligste nyhed i hele forløbet, endte med at være det spor, der gjorde det muligt at identificere den konkrete vej tilbage ind i installationen.
Men den vigtigste pointe er nok mere enkel: Sikkerhed handler ikke kun om at forhindre alt. Det handler også om at opdage det hurtigt, når noget ikke længere ser rigtigt ud.
Og det er dér, løbende overvågning og vedligeholdelse gør en meget større forskel, end endnu et sikkerhedsplugin alene kan gøre.
Er du i tvivl om, dit WordPress-site er ordentligt sikret?
Du behøver ikke vente på, at hjemmesiden går ned. Jeg kan gennemgå installationen, brugere, plugins, temaer, backup, opdateringsstatus, kendte sårbarheder og den eksisterende sikkerhedsopsætning.
Og hvis du ønsker, at nogen også holder øje bagefter, kan det samles i en løbende serviceaftale, hvor målet netop er at kunne reagere, før et lille sikkerhedsproblem bliver en stor oprydningsopgave.
Få styr på WordPress, før noget går galt
Jeg hjælper med sikkerhedstjek, oprydning efter kompromittering og løbende WordPress-service, hvor opdateringer, sårbarheder og centrale ændringer bliver fulgt proaktivt.
Om casen: Casen er anonymiseret. Domæne, ejer, branche, hostingudbyder, IP-adresser, konkrete kontrolservere, plugin-navne og sårbarhedsnumre er udeladt. Den oprindelige angrebsvej kunne ikke fastslås med sikkerhed. Den senere geninfektionsvej kunne derimod indsnævres med væsentligt større sikkerhed. Formålet med artiklen er at dele de defensive og driftsmæssige erfaringer fra sagen.
Skriv en kommentar
Har du en erfaring, et modargument eller et spørgsmål? Skriv endelig med. Din mailadresse bliver ikke offentliggjort.