Īsi: XSS PHP novērš, katru izvadi kodējot atbilstoši tās kontekstam: htmlspecialchars() HTML, json_encode() ar aizsardzības opcijām JavaScript, pārbaudīti URL saitēm. Veidnes ar automātisku eskēpēšanu daudz no tā paņem jūsu vietā. Content Security Policy un HttpOnly sīkdatnes ierobežo zaudējumus, ja tomēr paliek robs.
Kāpēc Cross-Site Scripting tagad jāpārbauda līdzi
- gada oktobrī uzmanība pievērsta PHP2Shell, divām kritiskām ievainojamībām PHP interpretatorā, kurām ielāpi pieejami kopš 21.10.2026. Daudzi uzņēmumi šajā sakarā liek pārbaudīt savas tīmekļa lietojumprogrammas. Tas ir labs iemesls aplūkot arī ievainojamības savā kodā, ko nelabo neviens PHP atjauninājums.
Cross-Site Scripting, īsi XSS, ir viena no tām. OWASP Top 10 XSS min kategorijas Injection ietvaros. Atšķirībā no ievainojamības serverī uzbrukums šeit vērsts pret jūsu vietnes apmeklētājiem un lietotājiem, piemēram, pret klientiem veikalā vai darbiniekiem administrēšanas sadaļā.
Sekas var būt būtiskas: pārņemtas administratoru sesijas, manipulētas veidlapas, kas sūta datus trešajām personām, vai viltots saturs jūsu vietnē. Ja tiek pārņemts administratora konts, tas var novest līdz pilnīgai kontrolei pār lietojumprogrammu.
Kā PHP lietojumprogrammās rodas XSS?
XSS rodas, kad lietojumprogramma datus no neuzticama avota izvada lapā bez pārbaudes. Pārlūks tad vairs nevar atšķirt jūsu saturu no ievadīta koda un izpilda abus.
Izšķir trīs veidus. Atstarotajam XSS saturs nāk tieši no pašreizējā pieprasījuma, piemēram, no meklēšanas vārda URL. Saglabātajam XSS tas atrodas datubāzē, piemēram, komentārā vai profila laukā, un skar ikvienu, kas atver lapu. DOM balstīts XSS rodas pārlūka JavaScript, kad skripti raksta vērtības no URL lapā.
Neuzticami ir visi dati, kas nav fiksēti kodā: veidlapu lauki, URL parametri, sīkdatnes, failu nosaukumi, ārēju saskarņu atbildes un saturs no paša datubāzes, kas kādreiz nācis no ārpuses.
Izvades pareiza kodēšana pēc konteksta
Svarīgākais noteikums: kodēt izvadē, un tieši atbilstoši vietai, kur vērtība nonāk. HTML saturam un atribūtiem pēdiņās htmlspecialchars() ir izvēles līdzeklis. Neliela palīgfunkcija neļauj aizmirst opcijas:
<?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'] ?? '') ?>">
Citiem kontekstiem vajadzīgi citi līdzekļi:
| Konteksts | Droša metode |
|---|---|
| HTML saturs, atribūts pēdiņās | htmlspecialchars() ar ENT_QUOTES un UTF-8 |
| Dati JavaScript | json_encode() ar JSON_HEX_TAG, JSON_HEX_AMP, JSON_HEX_APOS, JSON_HEX_QUOT |
| Parametrs URL | rawurlencode() atsevišķai vērtībai |
| Pilns URL no lietotāja ievades | Pārbaudīt shēmu, atļaut tikai https un http, pēc tam htmlspecialchars() |
| Atribūti bez pēdiņām, notikumu apstrādātāji, CSS | izvairīties, vērtības tur neievietot |
Datiem, kas vajadzīgi skriptam, datu atribūts vai JSON bloks parasti ir tīrākais ceļš:
<?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>
JavaScript vērtību tad nolasāt no datu atribūta un saturu iestatāt ar textContent, nevis ar innerHTML.
Veidnes, HTML tīrīšana un ietvari
Veidņu dzinēji, piemēram, Twig un Blade, izvadi pēc noklusējuma kodē automātiski. Tas izslēdz lielu daļu tipisku kļūdu. Bīstami kļūst tur, kur šī uzvedība tiek apzināti izslēgta, piemēram, ar filtru raw Twig vai sintaksi {!! !!} Blade. Šādām vietām kodā jābūt retām, un tās katrā pārskatā jāpārbauda mērķtiecīgi.
Ja jūsu lietojumprogrammai apzināti jāatļauj lietotāju HTML, piemēram, formatējums komentāros vai redakcijas sistēmā, ar kodēšanu nepietiek, jo HTML taču jāattēlo. Tad vajadzīga pārbaudīta tīrīšanas bibliotēka, piemēram, HTML Purifier, kas laiž cauri tikai fiksētu atļauto elementu un atribūtu sarakstu. Paši savi filtri ar regulārajām izteiksmēm pieredzē ir nepilnīgi.
Pārbaudiet īpaši administrēšanas zonas. XSS skatos, ko redz tikai administratori, bieži tiek nenovērtēts, bet skar tieši kontus ar visvairāk tiesību.
XSS atrašana esošajā PHP kodā
Izaugušās lietojumprogrammās pirmais jautājums parasti nav, kā pareizi kodēt, bet gan kur tas līdz šim ir aizmirsts. Pragmatisks sākums ir meklēt vietas, kur mainīgie tiek izvadīti tieši:
# Pieprasījuma datu tieša izvade
grep -rnE "(echo|print|<\?=)\s*\\\$_(GET|POST|REQUEST|COOKIE|SERVER)" src/ templates/ --include="*.php"
# Izslēgta automātiskā eskēpēšana Twig un Blade
grep -rnE "\|raw|\{!!" templates/ resources/views/
Atradumi ir pārbaudes uzdevumi, nevis gatavi secinājumi. Saglabāto XSS šāda meklēšana atrod tikai ierobežoti, jo vērtības tur nāk no datubāzes. Tāpēc papildus pārbaudiet visus skatus, kas rāda lietotāju saturu: komentārus, profilus, pasūtījumu piezīmes, atbalsta biļetes. CMS un veikalos skaidri pieder arī trešo pušu spraudņi un motīvi, jo tur atrodas liela daļa izvades loģikas.
Otrā aizsardzības līnija: CSP un drošas sīkdatnes
Pat rūpīgā kodā kāda vieta var tikt palaista garām. Tad zaudējumus ierobežo divi pasākumi. Content Security Policy pārlūkam atļauj tikai skriptus no noteiktiem avotiem un aizliedz iegultus skriptus, ja tie nav skaidri atļauti:
Header always set Content-Security-Policy "default-src 'self'; script-src 'self'; object-src 'none'; base-uri 'self'; frame-ancestors 'self'"
Šādu politiku ieviesiet pakāpeniski, vispirms tīri ziņošanas režīmā ar Content-Security-Policy-Report-Only, jo esošās analītikas vai maksājumu pakalpojumu iegulšanas parasti jāpapildina. Citas galvenes apraksta ceļvedis Drošības galvenes vietnēm.
Papildus sesiju sīkdatnēm jānes atribūts HttpOnly, lai skripti tās nevarētu nolasīt. Kā sesijas nodrošināt kopumā, rakstīts ceļvedī Sesiju nodrošināšana PHP. Radniecīgu ievainojamību datubāzes pusē aplūko SQL injekcijas novēršana PHP.
Kā PHP SOS palīdz konkrēti?
- Pārbaudām jūsu lietojumprogrammas veidnes un izvadi uz trūkstošu vai nepareizu kodēšanu.
- Atradumus vērtējam pēc sasniedzamības un skartajiem kontiem un parādām konkrētus labojumus.
- Content Security Policy ieviešam pakāpeniski, netraucējot veikala vai maksājumu funkcijas.
- Pēc labošanas pārbaudām vēlreiz un dokumentējam rezultātu.
Neatkarīgu pārbaudi apraksta pakalpojums Drošības audits un penetrācijas tests.
Biežāk uzdotie jautājumi
Vai htmlspecialchars pietiek pret XSS?
Parastam tekstam HTML saturā un atribūtos pēdiņās jā, ja norādāt ENT_QUOTES un rakstzīmju kopu UTF-8. JavaScript, URL vai CSS ir citi noteikumi, tur vajadzīga sava, piemērota kodēšana.
Vai ievadi filtrēt saglabājot vai izvadot?
Kodējiet izvadē, atbilstoši mērķim. Ievadi saņemot pārbaudiet uz ticamību, piemēram, garumu un formātu. Kas filtrē tikai saglabājot, palaiž garām datus no citiem avotiem un apgrūtina vēlāku izmantošanu citos kontekstos.
Ko dod Content Security Policy?
Content Security Policy nosaka, no kādiem avotiem pārlūks drīkst ielādēt un izpildīt skriptus. Tā var būtiski ierobežot nepamanītas XSS ievainojamības ietekmi, bet neaizstāj pareizu kodēšanu.
Kā komentāros atļaut formatējumu, piemēram, treknrakstu vai saites?
Izmantojiet pārbaudītu HTML tīrīšanas bibliotēku ar atļauto elementu un atribūtu baltā saraksta. Paša rakstītas regulārās izteiksmes skriptu noņemšanai ir kļūdainas, un tās nevajadzētu lietot.