Praegune olukord: PHP2Shell. Kaks kriitilist PHP turvaauku (CVSS 9,2) lubavad kahjulikku koodi ilma sisselogimata. Paigad alates 21.10.2026.Mida nüüd teha →

XSS-i vältimine PHP-s: Cross-Site-Scripting turvaliselt tõrjuda

Kuidas arendajad väldivad PHP rakendustes Cross-Site-Scriptingut: kontekstikohane kodeerimine, automaatne põgenemine mallides, HTML-i puhastamine ja Content Security Policy.

Seis Lugemisaeg 4 minJuhendid

Lühidalt: XSS-i PHP-s väldite, kodeerides iga väljundi vastavalt selle kontekstile: htmlspecialchars() HTML-i jaoks, json_encode() kaitsevalikutega JavaScripti jaoks, kontrollitud URL-id linkide jaoks. Automaatse põgenemisega mallid võtavad sellest suure osa teilt ära. Content Security Policy ja HttpOnly-küpsised piiravad kahju, kui mõni auk siiski alles jääb.

Miks tuleks Cross-Site-Scripting praegu kaasa kontrollida

  1. aasta oktoobris on tähelepanu PHP2Shellil, kahel kriitilisel turvaaugul PHP interpretaatoris, mille paigad on saadaval alates 21.10.2026. Paljud ettevõtted lasevad sellega seoses oma veebirakendusi üle kontrollida. See on hea põhjus vaadata ka oma koodi nõrkusi, mida ükski PHP uuendus ei kõrvalda.

Cross-Site-Scripting ehk XSS on üks neist. OWASP Top 10 loetleb XSS-i kategoorias Injection. Erinevalt serveri turvaaugust on rünnak siin suunatud teie veebisaidi külastajate ja kasutajate vastu, näiteks poe klientide või halduse töötajate vastu.

Tagajärjed võivad olla tõsised: üle võetud administraatorite sessioonid, manipuleeritud vormid, mis saadavad andmeid kolmandatele, või võltsitud sisu teie veebisaidil. Kui administraatori konto üle võetakse, võib see viia rakenduse üle täieliku kontrollini.

Kuidas XSS PHP rakendustes tekib?

XSS tekib, kui rakendus väljastab andmeid mitteusaldusväärsest allikast kontrollimata lehele. Brauser ei suuda siis enam eristada teie sisu ja sissetoodud koodi ning käivitab mõlemad.

Eristatakse kolme vormi. Peegeldatud XSS-i puhul pärineb sisu otse käimasolevast päringust, näiteks otsingusõnast URL-is. Salvestatud XSS-i puhul asub see andmebaasis, näiteks kommentaaris või profiiliväljal, ja tabab igaüht, kes lehe avab. DOM-põhine XSS tekib brauseri JavaScriptis, kui skriptid kirjutavad väärtusi URL-ist lehele.

Mitteusaldusväärsed on kõik andmed, mis ei ole koodis kindlalt kirjas: vormiväljad, URL-i parameetrid, küpsised, failinimed, väliste liideste vastused ja sisu oma andmebaasist, mis kunagi väljastpoolt tuli.

Väljund kontekstile vastavalt õigesti kodeerida

Tähtsaim reegel on: kodeerige väljastamisel ja just selle koha järgi, kuhu väärtus satub. HTML-i sisu ja jutumärkides atribuutide jaoks on htmlspecialchars() õige vahend. Väike abifunktsioon takistab valikute unustamist:

<?php
function e(?string $wert): string
{
    return htmlspecialchars($wert ?? '', ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML5, 'UTF-8');
}
?>
<h2><?= e($produkt['name']) ?></h2>
<input type="text" name="suche" value="<?= e($_GET['q'] ?? '') ?>">

Teised kontekstid vajavad teisi vahendeid:

Kontekst Turvaline meetod
HTML-i sisu, jutumärkides atribuut htmlspecialchars() valikuga ENT_QUOTES ja UTF-8
Andmed JavaScripti jaoks json_encode() valikutega JSON_HEX_TAG, JSON_HEX_AMP, JSON_HEX_APOS, JSON_HEX_QUOT
Parameeter URL-is rawurlencode() üksiku väärtuse jaoks
Täielik URL kasutaja sisendist skeem kontrollida, lubada ainult https ja http, seejärel htmlspecialchars()
Atribuudid ilma jutumärkideta, sündmuste käsitlejad, CSS vältida, väärtusi sinna mitte paigutada

Andmete jaoks, mida skript vajab, on andmeatribuut või JSON-plokk enamasti puhtaim tee:

<?php
$daten = json_encode($konfiguration, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT);
?>
<div id="app" data-konfig="<?= e($daten) ?>"></div>

JavaScriptis loete väärtuse seejärel andmeatribuudi kaudu välja ja seate sisu käsuga textContent, mitte innerHTML.

Mallid, HTML-i puhastamine ja raamistikud

Mallimootorid nagu Twig ja Blade kodeerivad väljundit vaikimisi automaatselt. See välistab suure osa tüüpilistest vigadest. Ohtlikuks muutub see seal, kus see käitumine teadlikult välja lülitatakse, näiteks Twigi filtriga raw või Blade'i süntaksiga {!! !!}. Selliseid kohti peaks koodis olema vähe ja neid tuleks igal ülevaatusel sihipäraselt kontrollida.

Kui teie rakendus peab teadlikult lubama kasutajate HTML-i, näiteks kommentaaride vormindust või toimetussüsteemis, kodeerimisest ei piisa, sest HTML tuleb ju kuvada. Siis on vaja kontrollitud puhastamise teeki nagu HTML Purifier, mis laseb läbi ainult lubatud elementide ja atribuutide kindla nimekirja. Oma regulaaravaldistega filtrid on kogemuse järgi lünklikud.

Oluline

Kontrollige eriti halduspiirkondi. XSS vaadetes, mida näevad ainult administraatorid, alahinnatakse sageli, kuid tabab just kõige rohkem õigusi omavaid kontosid.

XSS-i leidmine olemasolevas PHP koodis

Kasvanud rakendustes ei ole esimene küsimus enamasti see, kuidas õigesti kodeerida, vaid kus on seda seni unustatud. Pragmaatiline algus on otsida kohti, kus muutujaid väljastatakse otse:

# Päringuandmete otsene väljastamine
grep -rnE "(echo|print|<\?=)\s*\\\$_(GET|POST|REQUEST|COOKIE|SERVER)" src/ templates/ --include="*.php"
# Välja lülitatud automaatne põgenemine Twigis ja Blade'is
grep -rnE "\|raw|\{!!" templates/ resources/views/

Tabamused on kontrolliülesanded, mitte valmis leiud. Salvestatud XSS-i selline otsing leiab vaid osaliselt, sest väärtused tulevad seal andmebaasist. Kontrollige seetõttu lisaks kõiki vaateid, mis kuvavad kasutajate sisu: kommentaarid, profiilid, tellimusmärkmed, tugipiletid. Sisuhaldussüsteemide ja poodide puhul kuuluvad kolmandate osapoolte pluginad ja teemad sõnaselgelt juurde, sest seal asub suur osa väljundiloogikast.

Teine kaitseliin: CSP ja turvalised küpsised

Ka hoolika koodi korral võib mõni koht märkamata jääda. Kaks meedet piiravad siis kahju. Content Security Policy lubab brauseril ainult kindlaksmääratud allikatest skripte ja keelab sisseehitatud skriptid, kui neid ei ole sõnaselgelt lubatud:

Header always set Content-Security-Policy "default-src 'self'; script-src 'self'; object-src 'none'; base-uri 'self'; frame-ancestors 'self'"

Võtke selline poliitika kasutusele järk-järgult, esmalt ainult aruandlusrežiimis päisega Content-Security-Policy-Report-Only, sest olemasolevaid analüüsi- või maksemeetodite integratsioone tuleb enamasti täiendada. Edasisi päiseid kirjeldab juhend Turvapäised veebisaitidele.

Lisaks peaksid sessiooniküpsised kandma atribuuti HttpOnly, et skriptid neid välja lugeda ei saaks. Kuidas sessioone tervikuna turvata, on kirjas juhendis Sessioonide turvamine PHP-s. Sugulasnõrkust andmebaasi poolel käsitleb SQL-injektsiooni vältimine PHP-s.

Kuidas PHP SOS konkreetselt aitab?

  • Kontrollime teie rakenduse malle ja väljundeid puuduva või vale kodeerimise suhtes.
  • Hindame leide kättesaadavuse ja mõjutatud kontode järgi ning näitame konkreetseid parandusi.
  • Võtame Content Security Policy kasutusele järk-järgult, poe- või maksefunktsioone segamata.
  • Testime pärast parandust uuesti ja dokumenteerime tulemuse.

Sõltumatut kontrolli kirjeldab teenus Turvaaudit ja penetratsioonitest.

Korduma kippuvad küsimused

Kas htmlspecialchars piisab XSS-i vastu?

Tavalise teksti jaoks HTML-i sisus ja jutumärkides atribuutides jah, kui märgite ENT_QUOTES ja märgistiku UTF-8. JavaScriptis, URL-ides või CSS-is kehtivad teised reeglid, seal on vaja oma sobivat kodeerimist.

Kas peaksin sisendit filtreerima salvestamisel või väljastamisel?

Kodeerige väljastamisel, sihtkohale vastavalt. Sisendi usutavust peaksite kontrollima vastuvõtul, näiteks pikkust ja vormingut. Kes filtreerib ainult salvestamisel, jätab märkamata andmed teistest allikatest ja raskendab hilisemat kasutamist teistes kontekstides.

Mida annab Content Security Policy?

Content Security Policy määrab, millistest allikatest tohib brauser skripte laadida ja käivitada. See võib märkamata jäänud XSS-i turvaauku mõju oluliselt piirata, kuid ei asenda korrektset kodeerimist.

Kuidas lubada kommentaarides vormindust nagu rasvane kiri või lingid?

Kasutage kontrollitud HTML-i puhastamise teeki, kus on lubatud elementide ja atribuutide lubatud nimekiri. Oma regulaaravaldised skriptide eemaldamiseks on veaaldid ja neid ei tohiks kasutada.

Allikad

Kohene kontakt

Iga tund loeb. Kirjutage meile kohe.

Kirjeldage lühidalt süsteemi, PHP versiooni ja tähelepanekut. Võtame teiega ühendust, selgitame olukorra välja ja töötame kaugtööna, kuni intsident on lõpetatud ja dokumenteeritud.

Kohene abi