Forhindre SQL-injeksjoner I PHP (og andre sårbarheter)

Hvis du har vært rundt webutvikling for en stund, har du nesten helt sikkert hørt begrepet «SQL-injeksjon» og noen skremmende historier om det.

PHP, som mange andre språk, er ikke immun mot denne typen trussel, noe som kan være veldig farlig. Men, heldigvis, beskytte nettsteder FRA SQL-injeksjon og andre lignende trusler er noe du kan ta konkrete skritt mot.

i dette innlegget lærer DU HVA SQL-injeksjon er, hva konsekvensene av et vellykket angrep er, hvordan en angriper kan dra nytte av sårbar PHP-kode, hva du kan gjøre for å forhindre det, og hvilke verktøy du kan bruke til å oppdage delene av koden din som kan være utsatt for denne typen trussel. I tillegg vil du lære om noen andre vanlige sårbarheter du bør være oppmerksom på for å skape sikrere applikasjoner.

hvordan FUNGERER EN SQL-injeksjon?

det første du trenger å vite for å beskytte koden din FRA SQL-injeksjon, er å forstå hvordan den kan utnyttes av en angriper.

ideen bak utnyttelsen er ganske enkel: en angriper kjører ondsinnet SQL-kode på databasen din via appen din.

Hvordan kunne noen oppnå det? Ved å misbruke din søknad innganger.

La oss se på et enkelt eksempel. Anta at du har et program som viser en liste over brukernavn, hvor hver bruker har en lenke til sine detaljer som dette:

og så, på user_details.php – filen, har du dette:

<?php $sql = "SELECT * FROM user WHERE id = ".$_GET;

hvis brukeren opptrer som forventet og klikker på noen brukers navn, vil forespørselsadressen se slik ut: http://domain.com/user_details.php?id=8.

Så hva er galt med det?

verdien av $sql vil være strengen "SELECT * FROM user WHERE id = 8" og spørringen vil kjøre helt fint.

problemet er i kursiv del av denne setningen: hvis brukeren opptrer som forventet og klikker på noen brukers navn, vil forespørselsadressen se slik ut:

http://domain.com/user_details.php?id=8.

hva om brukeren ikke fungerer som forventet?

Hva om noen skulle produsere EN URL som sendte noe annet enn et nummer som ID?

Produserte Nettadresser

hvis NETTADRESSEN var noe som http://domain.com/user_details.php?id=Peanuts, ville DEN RESULTERENDE SQL-strengen være: "SELECT * FROM user WHERE id = Peanuts".

i dette tilfellet vil problemet være for brukeren. Spørringen ville bare mislykkes, og i verste fall ville brukeren se en slags merkelig melding.

men hva om NETTADRESSEN så mer ut som dette:

http://domain.com/user_details.php?id=1+OR+1%3B? (Dette er resultatet av urlencode('1 OR 1;'), forresten.)

i dette tilfellet vil den resulterende SQL være "SELECT * FROM user WHERE id = 1 OR 1;". Det betyr at resultatet av spørringen vil være hver bruker i databasen i stedet for bare brukeren HVIS ID er lik 1. Au.

Men det er fortsatt ikke så ille, ikke sant?

la Oss nå prøve et mer ekstremt eksempel.

la oss anta AT NETTADRESSEN var noe som

http://domain.com/user_details.php?id=1%27%3B+DROP+TABLE+users%3B--+, som oversetter til id=1; DROP TABLE users;--, som effektivt produserer DENNE SQL-kommandoen:

"SELECT * FROM users WHERE id = 1; DROP TABLE users;-- ". Og hvis du kjører denne spørringen … big ouch.

hvis du ikke er 100% kjent MED SQL-syntaks, vil DROP TABLE helt slette tabellen. Det ville være som om det aldri eksisterte.

selvfølgelig vil en nylig sikkerhetskopi bidra til å redusere skaden, men fortsatt. Dette er ille.

hvis du vil lære mer om denne typen angrep, er det et flott innlegg her.

men jeg tror det er nok dårlige nyheter. La oss gå videre til et mer muntert sted: hvordan du kan forhindre disse TYPER SQL-injeksjoner i PHP-appene dine.

slik forhindrer DU SQL-injeksjoner i PHP

som du så, er problemet når en angriper har muligheten til å kjøre SQL-kode uten at du er klar over det.

denne situasjonen presenterer seg som en konsekvens av å ha spørringer opprettet på fly via streng sammenkobling og inkludert data samlet fra eksterne innganger(vanligvis brukerinngang, men også andre eksterne kilder som filer, svar PÅ API-kall, og så videre).

Så, For å forhindre dette sikkerhetsproblemet i koden din, må du fikse kildene til potensielle problemer.

Valider inngangene

en enkel måte å fikse sikkerhetsproblemet på i eksemplet ovenfor, er å sjekke OM ID-parameteren er det som faktisk forventes fra den (dvs., et positivt heltall):

En annen måte å gjøre denne typen validering på er å utnytte PHPS innebygde filtre:

<?php
$id = filter_input( INPUT_GET, 'id', FILTER_VALIDATE_INT);

så, ved å validere inngangene dine, forhindrer du angripere i å utføre ondsinnet kode sammen med din egen.

Det er ingen enkel måte å hindre dem i å prøve, men så lenge deres forsøk ikke lykkes, er du god til å gå.

Bruk forberedte setninger

en annen måte du kan beskytte koden mot SQL-injeksjoner, er ved å bruke forberedte setninger. Forberedte setninger er forhåndskompilerte SQL-kommandoer.

De kan brukes med et bestemt databasetilgangsbibliotek (for eksempel mysqli) eller med DET mer generiske biblioteket PUD.

La oss se på et eksempel med mysqli:

hvis du prøver denne koden (erstatter databasens legitimasjon, selvfølgelig), vil du se at hvis du får tilgang til en juridisk URL som http://domain.com/user_details.php?id=1, får du det samme resultatet som noen av de ondsinnede Nettadressene ovenfor (som er informasjonen om brukeren knyttet TIL ID 1 og ingenting annet).

hvis du foretrekker Å bruke PUD, vil koden se mer ut som dette:

Ikke veldig mye forskjell, ikke sant?

oppsummert tilbyr preparerte utsagn en flott måte å forhindre SQL-injeksjoner på. Også, de utfører vanligvis bedre enn ON-the-fly SQL.

Nå som du kjenner verktøyet, trenger du bare å bruke det.

hvordan oppdage PHP-kode som er sårbar for SQL-injeksjoner

når sårbarheten er funnet, er det ikke veldig komplisert å fikse det. Men hvordan finner du disse typer sårbarheter i koden din i utgangspunktet?

vel, hvis du er heldig og kodebasen din er liten nok, vil en enkel gjennomgang av koden gjøre.

men hvis søknaden din er mellomstor til stor, trenger du ekstra hjelp.

en svært populær (og åpen kildekode) verktøy du kan bruke til dette formålet er sqlmap, en enkel Python script som vil prøve å angripe NOEN URL du mate til det og rapportere tilbake på sine funn.

Her er en prøveutgang fra et løp mot ET PHP-basert nettsted av meg:

Et annet open source-verktøy du kan bruke Er Arachni, et mer sofistikert verktøy som inkluderer en web GUI og ble skrevet I Ruby.

her er en prøveutgang fra å kjøre den gjennom CLI:

Utover kodegjennomgang og testing, bør du vurdere å bruke EN RASP-løsning, for eksempel Sqreen, for å overvåke produksjonsmiljøene for å stoppe utførelsen av eventuelle utnyttelser som gjør det gjennom gjennomgang og testing stadier.

Hvilke andre sårbarheter bør du være oppmerksom på?

Kodeinjeksjoner

SQL-injeksjon er bare ett medlem av en større familie av sårbarheter: kodeinjeksjon.

ideen bak ulike kodeinjeksjonsteknikker er alltid den samme. Det handler om å lure et uskyldig program til å kjøre ondsinnet kode.

Dette kan gjøres på flere måter.

I PHP er det funksjoner designet for å bare utstede kommandoer rett inn i operativsystemet, for eksempel funksjonen exec.

her er et enkelt eksempel på hvordan dette kan utnyttes:

<?php
exec( 'cp uploads/'.$_GET.' /secure/');

hvis noen skulle be om http://domain.com/exec.php?file=a.txt%3B+rm+-Rf+%2A+%23, ville resultatet være utførelsen av denne kommandoen:

cp uploads/a.txt; rm -Rf * # /secure/

Og dette kan tørke ut hele disken på serveren-uvalidert inngang slår igjen!

skripting på tvers av nettsteder

ET annet svært vanlig sikkerhetsproblem er skripting på tvers AV nettsteder (XSS). I dette tilfellet er offeret brukeren som besøker nettstedet ditt.

XSS er NÅR en angriper injiserer skadelig JavaScript-kode i et vanlig HTML-skjema, som senere gjengis av en annen brukers nettleser.

Se PÅ DETTE PHP-skriptet:

<?php
echo "<html><p>Hello {$_GET}!</p></html>";

Klart, hensikten her er å lage en enkel side som hilser brukeren.

Men når skurkene kommer til det, hva hindrer dem i å be om

http://domain.com/greet.php?name=Mauro%3Cscript+language%3D%22javascript%22%3Ealert%28%22You+are+hacked%21%22%29%3B%3C%2Fscript%3E? Denne forespørselen vil produsere FØLGENDE HTML som utgang:

<html><p>Hello Mauro<script language="javascript">alert("You are hacked!");</script></p></html>

dette er helt klart en veldig naiv utnytte—tross alt, hva er skade i å vise noen en enkel » Du er hacket!»melding? Men ting kan bli ganske alvorlig med litt fantasi. Bare husk at hver forespørsel til en server inkluderer session cookie, så dette sikkerhetsproblemet kan være den skyldige bak brukernes økter å bli kapret.

så igjen, mens problemene ser stygg ut, er reparasjonene veldig enkle: Det handler om validering og sanitisering.

I TILFELLE AV XSS, vil en enkel samtale til htmlentities før du produserer den faktiske utgangen, gjøre.

Å Fikse vs oppdage sikkerhetsproblemer

som du så i dette innlegget, er det ikke den største utfordringen å fikse sikkerhetsproblemer—BÅDE SQL—injeksjoner og andre typer. Å innse at koden din er sårbar, og hvor den kan utnyttes, er. Du har et par alternativer her:

  • Har veldig sterk kodingsdisiplin
  • Test programmene dine grundig for sikkerhetsproblemer
  • Utnytt overvåkings-og beskyttelsesverktøy For å forhindre utnyttelser og få varsler i tide

Hvilken du velger, er opp til deg. Det viktigste er å være oppmerksom på disse problemene og handle på den kunnskapen. Hold deg trygg.

Leave a Reply

Din e-postadresse vil ikke bli publisert.