OWASP Top 10 omalla 20 vuotta vanhalla verkkosivustollani
Auditoin omat vanhat verkkosivustoni OWASP Top 10:2025 -listaa vasten ja löysin yhdeksän kymmenestä luokasta. Mitä löysin ja miten korjasin.
Tietoturva-arkkitehdit käyttävät päivänsä muiden järjestelmien arviointiin. Syksyllä 2026 tein vihdoin sen, mitä suosittelen jokaiselle asiakkaalle: auditoin omani. Henkilökohtainen sivustoni sai alkunsa vuonna 1999 ja kasvoi kahden vuosikymmenen ajan: XML-pohjainen ASP.NET-portaali, PHP-kokeiluja, muutama WordPress-asennus, vanha .NET-julkaisujärjestelmä ja monta pientä projektia, jotka olin yksinkertaisesti unohtanut.
Tulos oli nöyryyttävä ja hyvin opettavainen. Yhdeksän OWASP Top 10:2025 (avautuu uuteen välilehteen) -listan kymmenestä luokasta oli edustettuna. Tässä on se, mitä löysin OWASP-luokkiin jaoteltuna, ja mitä tein asialle.
Opetus yhdellä lauseella: verkkosivuston suurin riski ei ole koodi, jota ylläpidät, vaan koodi, jonka olet unohtanut.
Miten tein sen
- Ensin kopio. Latasin koko palvelimen FTPS:llä paikalliseen Git-repositorioon. Sain haettavan kopion ja kumoa-painikkeen. Repositorio on vain paikallinen, koska asetustiedostoissa on tunnuksia.
- Hae, älä lue. Kymmeniätuhansia tiedostoja ei voi lukea läpi. Tekoälyavustajan avulla hain kuvioita:
phpinfo(,eval(base64_decode, koodiin kirjoitettuja salasanoja,.sql-,.bak- ja.zip-tiedostoja sekä asennuskansioita. Avustaja teki haut; jokainen päätös ja jokainen muutos palvelimella oli minun. - Tarkista, mikä on oikeasti julkista. Vaarallinen tiedosto levyllä on yksi asia; vaarallinen tiedosto, joka vastaa internetissä 200 OK, on toinen. Testasin jokaisen löydöksen tuotantosivustoa vasten.
- Karanteeni, ei poistoa. Kaikki poistettava siirrettiin ensin verkkosivuston ulkopuoliseen kansioon, testattiin ja poistettiin vasta myöhemmin.
Mitä löysin
| Löydös | OWASP Top 10:2025 | Korjaus |
|---|---|---|
| Vuoden 2007 PHP-sanakirja, jossa oli SQL-injektio ja sivu, jolla kuka tahansa pystyi muuttamaan sanoja kirjautumatta | A05 Injektio, A01 Rikkinäinen pääsynhallinta | Kirjoitettu uudelleen: valmistellut kyselyt, koodattu tuloste, vain luku |
Useita julkisia phpinfo()-sivuja, jotka näyttivät PHP-version, polut ja asetukset | A02 Virheelliset tietoturva-asetukset | Poistettu verkosta |
| WordPress-asennuksia vuosilta 2019–2020, vanha .NET-julkaisujärjestelmä, hylätty verkkokäyttöjärjestelmä ja vanha tekstieditori | A03 Ohjelmistotoimitusketjun virheet | Siirretty pois verkosta |
| HTTPS-uudelleenohjaus, joka virheellisen ehdon takia koski vain yhden hakukoneen robottia | A04 Kryptografiset virheet | Uudelleenohjaus kaikille sekä HSTS |
| Portaalin salasanat selväkielisinä ja julkinen tilastotiedosto käyttäjänimineen | A07 Tunnistautumisen virheet | Datakansiot estetty, salasanat vaihdettu, portaali poistettu käytöstä |
| "Muista minut" -eväste, jossa käyttäjän salasana oli palautettavasti salattuna | A04 / A07 | Poistettu portaalin mukana |
| Tietokannan tunnukset kirjoitettuna sovelluksen koodiin | A07 Tunnistautumisen virheet | Siirretty erilliseen asetustiedostoon, jota ei koskaan jaeta verkkoon |
| Vuoden 2013 roskapostisuoja, jonka virustorjunta tunnisti hämärretyksi haitalliseksi PHP:ksi | A08 Ohjelmiston tai datan eheysvirheet | Poistettu |
| Julkinen lokitiedosto kävijöiden IP-osoitteineen | A09 Tietoturvalokituksen ja hälytysten puutteet (ja GDPR) | Poistettu verkosta |
| Yksityiskohtaiset ASP.NET-virhesivut pinonjälkineen sekä debug-käännös ja jäljitys päällä | A10 Poikkeustilanteiden virheellinen käsittely, A02 | Yleiset virhesivut, debug="false", jäljitys pois |
| Ulkoisten rajapintojen tietoja (pelipalvelimien nimiä, chat-käyttäjien nimiä) tulostettiin HTML:ään ilman koodausta | A05 Injektio (XSS) | Tulosteen koodaus htmlspecialchars-funktiolla |
Ainoa luokka, jota en löytänyt, oli A06 Turvaton suunnittelu – vaikka salasanojen tallentaminen selväkielisinä oli pohjimmiltaan sekin suunnittelupäätös.
Viisi opetusta
1. Hyökkäyspintasi on kaikki, mikä vastaa portissa 443
Yksikään pahimmista löydöksistä ei ollut sivuilla, joilla käyn. Ne olivat kansioissa, joita en ollut avannut kymmeneen vuoteen. Inventaario on kaiken perusta.
2. Asetukset riippuvat alustasta
Useiden vanhojen projektien mukana oli Apachelle kirjoitettuja .htaccess-tiedostoja. Palveluntarjoajani käyttää IIS:ää, joka ohittaa ne kokonaan. Mitä sääntöjä luuletkin olevan voimassa, varmista ne alustalla, jolla ne todella toimivat.
3. Testaa kontrolli, älä asetusta
HTTPS-uudelleenohjaus oli asetuksissa, joten se näytti olevan kunnossa. Vasta tavallisena kävijänä testaaminen paljasti, ettei se koskaan lauennut. Sama pätee palomuureihin, MFA-käytäntöihin ja varmuuskopioihin: testaa lopputulos.
4. Selväkieliset salasanat eivät ole koskaan "vain testisivusto"
Lyhyet selväkieliset salasanat ja julkinen käyttäjälista tekevät unohdetusta testisivustosta sisäänpääsyreitin. Tallenna salasanat nykyaikaisella algoritmilla (Argon2id, scrypt tai bcrypt), tai mieluummin älä tallenna niitä lainkaan.
5. Turvallisin koodi on koodi, jonka poistat
Korvasin vanhan portaalin staattisella sivustolla: ei tietokantaa, ei kirjautumista, ei palvelinpuolen koodia, ei evästeitä ja tiukka sisällön tietoturvakäytäntö (CSP). Muokkaan sitä pienellä yksityisellä editorilla, jonka suojaavat pitkä salasana ja kertakäyttökoodi ja joka julkaisee pelkkää HTML:ää. Julkisella sivustolla ei ole juuri mitään hyökättävää, ja se on lisäksi nopeampi ja edullisempi ylläpitää.
Muistilista omalle sivustollesi
- Lataa täydellinen kopio ja ota se versionhallintaan (yksityisesti).
- Hae
phpinfo-sivuja, asennusohjelmia, varmuuskopioita, tietokantavedoksia jaeval(base64_decode(-rivejä. - Listaa kaikki sovellukset versioineen; poista se, mitä kukaan ei käytä.
- Kytke yksityiskohtaiset virheilmoitukset ja debug-tila pois tuotannosta.
- Pakota HTTPS kaikille ja lisää tietoturvaotsakkeet (HSTS, CSP, X-Content-Type-Options).
- Varmista, ettei yhtään data-, loki- tai asetuskansiota jaeta internetiin.
- Siirrä tunnukset pois koodista ja vaihda jokainen salasana, joka on joskus tallennettu selväkielisenä.
Minulta kaiken tämän löytäminen vei viikonlopun. Hyökkääjän skanneri tarvitsee muutaman minuutin.