Securitate în PHP

Când scrieți cod PHP, este foarte important să țineți cont de următoarele vulnerabilități de securitate pentru a evita scrierea unui cod nesigur.

Tipuri de vulnerabilități

Acestea sunt vulnerabilitățile comune pe care le veți întâlni atunci când scrieți cod PHP. Vom discuta câteva mai jos mai jos.

  • Solicitare de falsificare a site-urilor încrucișate O vulnerabilitate în aplicație cauzată de faptul că programatorul nu a verificat de unde a fost trimisă o cerere – acest atac este trimis unui utilizator cu un nivel de privilegiu ridicat pentru a obține un acces de nivel superior la aplicație.
  • Cross Site Scripting O vulnerabilitate în aplicație cauzată de faptul că programatorul nu dezinfectează intrarea înainte de a trimite intrarea în browser (de exemplu, un comentariu pe un blog). Este folosit în mod obișnuit pentru a rula javascript rău intenționat în browser pentru a efectua atacuri, cum ar fi furtul cookie-urilor de sesiune, printre alte acțiuni rău intenționate, pentru a obține privilegii de nivel superior în aplicație.
  • Includerea fișierelor locale O vulnerabilitate în aplicație cauzată de programator care necesită o intrare de fișier furnizată de utilizator și care nu dezinfectează intrarea înainte de a accesa fișierul solicitat. Acest lucru duce la includerea unui fișier acolo unde nu ar fi trebuit să fie.
  • Includerea fișierelor la distanță O vulnerabilitate în aplicație cauzată de programator care necesită o intrare de fișier furnizată de utilizator și care nu dezinfectează intrarea înainte de a accesa fișierul solicitat. Acest lucru duce la extragerea unui fișier de pe un server la distanță și inclus acolo unde nu ar fi trebuit să fie.
  • Sechestrarea sesiunii O vulnerabilitate cauzată de accesul unui atacator la identificatorul de sesiune al unui utilizator și de posibilitatea de a utiliza contul unui alt utilizator care îl identifica. Aceasta este adesea utilizată pentru a avea acces la contul unui utilizator administrativ.
  • Cerința identificatorului de sesiune Cerința identificatorului de sesiune este o vulnerabilitate cauzată de faptul că un atacator poate fie să ghicească identificatorul de sesiune al unui utilizator, fie să exploateze vulnerabilitățile din aplicația în sine sau din browserul utilizatorului pentru a obține un identificator de sesiune.
  • Injecție SQL O vulnerabilitate în aplicație cauzată de faptul că programatorul nu dezinfectează intrarea înainte de a o include într-o interogare în baza de date. Acest lucru face ca atacatorul să aibă acces complet la citire și, de cele mai multe ori, la scriere la baza de date. Cu acest tip de acces, un atacator poate face lucruri foarte rele.

Acum să analizăm mai detaliat câteva vulnerabilități comune.

Sechestrarea sesiunii

Session Hijacking este o vulnerabilitate cauzată de accesul unui atacator la identificatorul de sesiune al unui utilizator și de posibilitatea de a utiliza contul unui alt utilizator care îl identifica. Aceasta este adesea utilizată pentru a avea acces la contul unui utilizator administrativ.

Apărarea împotriva atacurilor Session Hijacking în PHP

Pentru a vă apăra împotriva atacurilor Session Hijacking, trebuie să verificați browserul utilizatorului curent și informațiile despre locație împotriva informațiilor stocate despre sesiune. Mai jos este un exemplu de implementare care poate ajuta la atenuarea efectelor unui atac de deturnare a sesiunii. Verifică adresa IP, agentul utilizatorului și dacă sesiunea a expirat eliminând o sesiune înainte de a fi reluată.

<?php
session_start();

// Does IP Address match?
if ($_SERVER['REMOTE_ADDR'] != $_SESSION['ipaddress'])
{
session_unset();
session_destroy();
}

// Does user agent match?
if ($_SERVER['HTTP_USER_AGENT'] != $_SESSION['useragent'])
{
  session_unset();
  session_destroy();
}

// Is the last access over an hour ago?
if (time() > ($_SESSION['lastaccess'] + 3600))
{
  session_unset();
  session_destroy();
}
else
{
  $_SESSION['lastaccess'] = time();
}

Cross Site Scripting

Cross Site Scripting este un tip de vulnerabilitate într-o aplicație web cauzată de faptul că programatorul nu dezinfectează intrarea înainte de a trimite intrarea în browserul web (de exemplu, un comentariu pe un blog). Este folosit în mod obișnuit pentru a rula javascript rău intenționat în browserul web pentru a efectua atacuri, cum ar fi furtul cookie-urilor de sesiune, printre alte acțiuni rău intenționate, pentru a obține privilegii de nivel superior în aplicația web.

Exemplu Atac de scriptare pe site-uri

Un blog permite utilizatorilor să își modifice comentariile cu etichete HTML, totuși scriptul care alimentează blogul nu este eliminat <script> etichete care permit oricărui utilizator să ruleze javascript pe pagină. Un atacator poate folosi acest lucru în avantajul său pentru a rula javascript rău intenționat în browser. Ar putea infecta utilizatorii cu programe malware, fura cookie-uri de sesiune și multe altele.

<script>
  alert('Cross Site Scripting!');
</script>

Apărarea site-ului dvs. web de atacurile de scripturi cross site în PHP

În PHP există două funcții principale, htmlspecialchars() și strip_tags(), încorporat pentru a vă proteja de atacurile de scriptare între site-uri.

htmlspecialchars($string) funcția va împiedica redarea unui șir HTML ca HTML și afișarea acestuia ca text simplu în browserul web. htmlspecialchars () exemplu de cod

<?php
$usercomment = "<string>alert('Cross Site Scripting!');</script>";
echo htmlspecialchars($usercomment);

Cealaltă abordare este strip_tags($string, $allowedtags) funcție care elimină toate etichetele HTML, cu excepția etichetelor HTML pe care le-ați adăugat pe lista albă. Este important să rețineți că cu strip_tags() funcție trebuie să fiți mai atenți, această funcție nu împiedică utilizatorul să includă javascript ca link, va trebui să-l igienizați pe cont propriu.

strip_tags () exemplu de cod

<?php
$usercomment = "<string>alert('Cross Site Scripting!');</script>";
$allowedtags = "<p><a><h1><h2><h3>";
echo strip_tags($usercomment, $allowedtags);

Setarea antetului de protecție X-XSS:

În PHP puteți trimite fișierul X-XSS-Protection Antet care le va spune browserelor să verifice dacă există un atac Cross Site Scripting reflectat și să blocheze încărcarea paginii. Acest lucru nu împiedică toate atacurile de cross site scripting doar cele reflectate și ar trebui să fie utilizate în combinație cu alte metode.

<?php
header("X-XSS-Protection: 1; mode=block");

Scrierea propriei funcții de igienizare O altă opțiune, dacă doriți mai mult control asupra modului de funcționare a igienizării, este să scrieți propria funcție de igienizare HTML, acest lucru nu este recomandat pentru începători PHP, deoarece o greșeală ar face site-ul dvs. vulnerabil.

Apărarea site-ului dvs. web împotriva atacurilor de scriptare între site-uri printr-o politică de securitate a conținutului

O abordare eficientă pentru prevenirea atacurilor de cross site scripting, care poate necesita o mulțime de ajustări la designul aplicației dvs. web și la baza de coduri, este utilizarea unei politici de securitate a conținutului.

Setați o politică de securitate a conținutului ca antet HTTP

Cel mai comun mod de a seta o politică de securitate a conținutului este setarea acesteia direct în antetul HTTP. Acest lucru poate fi realizat de serverul web modificând configurația acestuia sau trimițându-l prin PHP.

Exemplu de politică de securitate a conținutului setată într-un antet HTTP

<?php
header("content-security-policy: default-src 'self'; img-src https://*; child-src 'none';");

Setați o politică de securitate a conținutului ca metaetichete

Puteți include politica de securitate a conținutului în codul HTML al paginii și setați pe bază de pagină. Această metodă necesită setarea pe fiecare pagină sau pierdeți avantajul politicii.

Exemplu de politică de securitate a conținutului setată într-o metaetichetă HTML

<meta http-equiv="Content-Security-Policy" content="default-src 'self'; img-src https://*; child-s

Injecție SQL

Injecția SQL este o vulnerabilitate a aplicației cauzată de faptul că programatorul nu dezinfectează intrarea înainte de a o include într-o interogare în baza de date. Acest lucru face ca atacatorul să aibă acces complet la citire și, de cele mai multe ori, la scriere la baza de date. Cu acest tip de acces, un atacator poate face lucruri foarte rele.

Exemplu atac SQL Injection

Scriptul PHP de mai jos rulează o declarație SQL pentru a primi e-mailul unui utilizator prin ID. Cu toate acestea, intrarea nu este igienizată, ceea ce o face vulnerabilă la SQL Injection

<?php
$input = $_GET['id'];
$dbserver = "localhost";
$dbuser = "camper";
$dbpass = "supersecretcampsitepassword";
$dbname = "freecodecamp";

$conn = new mysqli($dbserver, $dbuser, $dbpass, $dbname);

if ($conn->connect_error) {
    die("Connection failed: " . $conn->connect_error);
}

$sql = "SELECT email FROM users WHERE id =" . $input;

$result = $conn->query($sql);

if ($result->num_rows > 0) {
    while($row = $result->fetch_assoc()) {
        echo $row["email"];
    }
} else {
    echo "no results";
}

$conn->close();
SELECT email FROM users WHERE id = `$input`;

Deci, cu cele de mai sus, intrarea nu este de tip casted (Adică aruncând intrarea cu (int), deci este permis doar un număr) și nici nu a scăpat, permițând cuiva să efectueze un atac SQL Injection – de exemplu, adresa URL getemailbyuserid.php?id=1'; My Query Here-- - vă va permite să executați interogări SQL arbitrare cu puțin efort.

Apărarea site-ului dvs. împotriva atacurilor de injectare sql în PHP

Există câteva abordări pentru a vă apăra site-ul web de atacurile SQL Injection. Aceste abordări sunt Listă albă, Distribuție tip și Scapare caractere

Listă albă: Abordarea pe lista albă este utilizată în cazurile în care sunt așteptate doar câteva intrări. Puteți afișa fiecare intrare așteptată într-un comutator PHP și apoi aveți o valoare implicită pentru intrarea nevalidă. Nu trebuie să vă faceți griji cu privire la o problemă de casting sau un bypass de evadare a caracterelor, dar intrarea permisă este extrem de limitată. Rămâne o opțiune, a se vedea exemplul de mai jos.

<?php
switch ($input) {
  case "1":
    //db query 1
    break;
  case "2":
    //db query 2
    break;
  default:
    // invalid input return error
}

Tip Casting: Abordarea de turnare tip este frecvent utilizată pentru o aplicație care utilizează intrare numerică. Pur și simplu aruncați intrarea cu (int) $input și numai o valoare numerică va fi permisă.

Caracterul care scapă: Abordarea de evadare a personajelor va scăpa de personaje precum ghilimele și barele oferite de utilizator pentru a preveni un atac. Dacă utilizați MySQL Server și biblioteca MySQLi pentru a accesa baza de date, fișierul mysqli_real_escape_string($conn, $string) funcția va lua două argumente, conexiunea MySQLi și șirul și va scăpa corect de intrarea utilizatorului pentru a bloca un atac de injecție sql. Funcția exactă pe care o utilizați depinde de tipul bazei de date și de biblioteca php pe care o utilizați verificați documentația bibliotecii php pentru mai multe informații despre scăparea intrării utilizatorului.

Mai multe despre PHP:

  • Cele mai bune practici PHP
  • Cele mai bune exemple de cod PHP
  • Cum se previne un atac lent de Loris pe un server PHP
  • Cum se configurează un mediu de depanare local în PHP