Bli ren med PHP

Datasikkerhet er viktig og ofte undervurdert av designere, utviklere og kunder. Siden PHP 5.2.0 har data sanitisering og validering blitt gjort betydelig lettere med innføring av datafiltrering. I dag skal vi se nærmere på disse filtrene, hvordan du bruker dem, og bygge noen tilpassede funksjoner.

Opplæringsdetaljer

  • Program: PHP
  • Versjon: 5.2.0+
  • Vanskelighet: Nybegynner
  • Anslått sluttid: 20 minutter

Introduksjon

Jeg har alltid følt at det er lett å skrive kode i PHP, og enda enklere å skrive dårlig kode i PHP. Spredning av PHP på nettet har virkelig blitt hjulpet ved bruk i populære open source programvarepakker som WordPress, Drupal og Magento, samt store webapplikasjoner som Facebook; med PHP brukes i så mange varierte tilfeller (dynamiske nettsteder, dybdegående webapplikasjoner, bloggingplattformer, innholdshåndteringssystemer og e-handel er bare en delmengde av de mange applikasjonene i PHP) mulighetene for skitten data og usikre systemer er mange. Denne opplæringen vil forklare noen metoder for Bli ren med PHP: Data Sanitization and Validation ved å fokusere på flere forskjellige former for datainnganger og hvordan du bruker PHP-filtre og tilpassede funksjoner.

Hvorfor Sanitize og validere?

I denne veiledningen er vi veldig fokusert på datainnganger som brukere eller eksterne kilder kan gi. Dette betyr at vi ikke kontrollerer dataene vi mottar. Alt vi kan gjøre, er å kontrollere hva som er gjort med det etter at vi mottar det. Det er alle slags trusler knyttet til datasikkerhet fra brukerinnganger og tredjepartsdata.

Noen un-populære datasikkerhetstrusler:

  • Cross-Site Scripting (XSS): En form for kodeinjeksjon hvor et skript injiseres på et nettsted fra en helt annen nettside. Dette er langt det vanligste sikkerhetsproblemet på nettet. To siste, fremtredende eksempler på denne teknikken er Stalk Daily og Mikeyy Twitter Worms fra tidligere i år som brukte dårlig sanitiserte innganger for å starte Javascript via et "infisert" Twitter-webgrensesnitt.
  • SQL Injection: Det nest vanligste sikkerhetsproblemet på nettet, dette er en annen form for kodeinjeksjon der et skript brukes til å delta i en av mange utfordrende oppføringer, inkludert (men ikke begrenset til) å utsette og / eller få uautorisert tilgang til data, endre data inni av en database, eller bare å injisere kode som skal gjengis eller utføres på et nettsted, og dermed bryte eller endre nettstedet.
  • Kryss-site Request Forgery (CSRF / XSRF): En mindre vanlig utnyttelse som avhenger mer av datakilder som nettlesere og øktkaker enn dårlig sanitert og validert datainngang, CSRF (uttalt "sjø-surf") kan brukes til å utføre kommandoer på et nettsted uten brukerens tillatelse. En populær CSRF-metode bruker en feilformet bildedata URI eller src-verdi for å utføre et skript i stedet for å vise et bilde.
  • Feil data: Ikke egentlig et "sikkerhetsproblem" i seg selv, Feil data kan føre til feilproblemer for en nettstedseier eller databaseadministrator. Ofte kan feilaktige data ødelegge dårlig kodede nettsteder eller føre til at automatiserte systemer krasjer. Et eksempel på dette var evnen til å endre hele MySpace profilsider ved å legge ut alle typer HTML / CSS hackery (Merk: dette kan fortsatt fungere, jeg har ikke brukt MySpace på lenge).
Bildekilde: XKCD

For våre formål skal vi bare fokusere på server-side metoder for å forbedre datasikkerhet med PHP, så la oss se hvordan begrepet "sanitization" og "validering" er definert i forhold til PHP. Ifølge PHP manualen:

Validering brukes til å validere eller kontrollere om dataene oppfyller visse kvalifikasjoner. For eksempel bestemmer passering i FILTER_VALIDATE_EMAIL om dataene er en gyldig e-postadresse, men vil ikke endre dataene selv.

Sanitisering vil sanitisere dataene, slik at det kan endre det ved å fjerne uønskede tegn. For eksempel vil passering i FILTER_SANITIZE_EMAIL fjerne tegn som er upassende for en e-postadresse som skal inneholde. Når det er sagt, bekrefter det ikke dataene.

I hovedsak, hvis nettstedet ditt er nattklubben som alle ønsker å komme inn, kontrollerer validering gjestelisten og ID-er ved døren, mens sanitisering fungerer som bouncer som kaster ut eventuelle uønskede ting som kommer til å knirke forbi. Med dette i tankene, la oss ta en titt på PHP Filters Extension.

Hvilke filtre har jeg?

Alle PHP-installasjoner er ikke opprettet like. Mens PHP 5.2.0 var innføring av filtre, har ikke alle installasjoner det samme settet av filtre i deres Filters Extension. De fleste installasjoner vil ha alle filtene vi skal gå over, men for å lære deg litt om filtreutvidelsen, skal vi finne ut akkurat hva du har på serveren din. I kildedownloaden har jeg tatt med en fil som heter getfilters.php som, når installert og kjører på serveren din, vil vise alle filtre (begge datafilter tilgjengelig via filter_var funksjon og strøm filtrene tilgjengelig gjennom stream_filter_append).

 ekko "

Datafilter

\ n\ n\ n "; ekko"\ n "; ekko"\ n"; foreach (filter_list () som $ id => $ filter) echo"\ n "; ekko"
Filter IDFilternavn
$ filter".Filter_id ($ filter)."
\ N ";

Først får vi oppstillingen som inneholder listen over alle tilgjengelige filtre med filter_list, så løper vi gjennom arrayet og ekkjer ut filternavnet, finner ut filterets tildelte ID, og ​​ekko også denne ID-en.

Hvordan bruker jeg et filter?

PHP-filtre for validering og sanitisering aktiveres ved å sende minst to verdier til PHP Filters Extension-funksjonen filter_var. Som et eksempel, la oss bruke Sanitize Filter for et heltall slik:

 $ value = '123abc456def'; ekko filter_var ($ verdi, FILTER_SANITIZE_NUMBER_INT);

I eksemplet har vi en variabel $ verdi som går gjennom filtreutvidelsesfunksjonen filter_var bruker FILTER_SANITIZE_NUMBER_INT filter. Dette resulterer i følgende utgang:

 123456

Sanitize-filteret for et integernummer fjerner alle ikke-heltallige tegn fra utgangen og produserer et rent heltall. Innen nedlastingskilden kan du prøve forskjellige innganger, og det vil gjelde en rekke vanlige filtre til din inngangsverdi. Jeg har tatt med en rekke forskjellige eksempelstrenger som du også kan teste ut.

Hva gjør de forskjellige filtrene?

Listen nedenfor er ikke fullført, men den inneholder de fleste filtene som kommer standard med 5.2.0+ installasjoner. Egendefinerte filtre og de som er lagt til fra egendefinerte utvidelser, er ikke inkludert her.

FILTER_VALIDATE_BOOLEAN: Kontrollerer om dataene som sendes til filteret, er en boolsk verdi av EKTE eller FALSK. Hvis verdien er en ikke-boolsk verdi, kommer den tilbake FALSK. Skriptet nedenfor vil ekko "SANT" for eksempeldataene $ value01 men vil ekko "FALSE" for eksempeldataene $ value02:

 $ value01 = TRUE; hvis (filter_var ($ value01, FILTER_VALIDATE_BOOLEAN)) echo 'TRUE';  ellers echo 'FALSE';  ekko '

'$ value02 = TRUE; hvis (filter_var ($ value02, FILTER_VALIDATE_BOOLEAN)) echo 'TRUE'; ellers echo 'FALSE';

FILTER_VALIDATE_EMAIL: Kontrollerer om dataene som sendes til filteret, er en potensielt gyldig e-postadresse. Det kontrollerer ikke om e-postadressen egentlig eksisterer, bare at formatet til e-postadressen er gyldig. Skriptet nedenfor vil ekko "SANT" for eksempeldataene $ value01 men vil ekko "FALSE" for eksempeldataene $ value02 (fordi den andre mangler det nødvendige @ domain.tld-delen av e-postadressen):

 $ value01 = '[email protected]'; hvis (filter_var ($ value01, FILTER_VALIDATE_EMAIL)) echo 'TRUE';  ellers echo 'FALSE';  ekko '

'$ value02 =' nettuts '; hvis (filter_var ($ value02, FILTER_VALIDATE_EMAIL)) echo 'TRUE'; ellers echo 'FALSE';

FILTER_VALIDATE_FLOAT: Kontrollerer om dataene som sendes til filteret, er en gyldig flyteverdi. Skriptet nedenfor vil ekko "SANT" for eksempeldataene $ value01 men vil ekko "FALSE" for eksempeldataene $ value02 (fordi komma-separatorer ikke er tillatt i flytverdier):

 $ value01 = '1,234'; hvis (filter_var ($ value01, FILTER_VALIDATE_FLOAT)) echo 'TRUE';  ellers echo 'FALSE';  ekko '

'$ value02 =' 1,234 '; hvis (filter_var ($ value02, FILTER_VALIDATE_FLOAT)) echo 'TRUE'; ellers echo 'FALSE';

FILTER_VALIDATE_INT: Kontrollerer om dataene som sendes til filteret, er en gyldig heltallverdi. Skriptet nedenfor vil ekko "SANT" for eksempeldataene $ value01 men vil ekko "FALSE" for eksempeldataene $ value02 (fordi fraksjoner / desimaltall ikke er heltall):

 $ value01 = '123456'; hvis (filter_var ($ value01, FILTER_VALIDATE_INT)) echo 'TRUE';  ellers echo 'FALSE';  ekko '

'$ value02 =' 123.456 '; hvis (filter_var ($ value02, FILTER_VALIDATE_INT)) echo 'TRUE'; ellers echo 'FALSE';

FILTER_VALIDATE_IP: Kontrollerer om dataene som sendes til filteret, er en potensielt gyldig IP-adresse. Det kontrollerer ikke om IP-adressen vil løse, bare at den passer til den nødvendige datastrukturen for IP-adresser. Skriptet nedenfor vil ekko "SANT" for eksempeldataene $ value01 men vil ekko "FALSE" for eksempeldataene $ value02:

 $ value01 = '192.168.0.1'; hvis (filter_var ($ value01, FILTER_VALIDATE_IP)) echo 'TRUE';  ellers echo 'FALSE';  ekko '

'$ value02 =' 1.2.3.4.5.6.7.8.9 '; hvis (filter_var ($ value02, FILTER_VALIDATE_IP)) echo 'TRUE'; ellers echo 'FALSE';

FILTER_VALIDATE_URL: Kontrollerer om dataene som sendes til filteret, er en potensielt gyldig nettadresse. Det kontrollerer ikke om nettadressen vil løse, bare at den passer til den nødvendige datastrukturen for nettadresser. Skriptet nedenfor vil ekko "SANT" for eksempeldataene $ value01 men vil ekko "FALSE" for eksempeldataene $ value02:

 $ value01 = 'http://net.tutsplus.com'; hvis (filter_var ($ value01, FILTER_VALIDATE_URL)) echo 'TRUE';  ellers echo 'FALSE';  ekko '

'$ value02 =' nettuts '; hvis (filter_var ($ value02, FILTER_VALIDATE_URL)) echo 'TRUE'; ellers echo 'FALSE';

FILTER_SANITIZE_STRING: Som standard fjerner dette filteret data fra en streng som er ugyldig eller ikke tillatt i den aktuelle strengen. Dette vil for eksempel fjerne eventuelle HTML-koder, som '; ekko filter_var ($ verdi, FILTER_SANITIZE_STRING);

Dette skriptet fjerner kodene og returnerer følgende:

 varsling ('FEIL HER');

FILTER_SANITIZE_ENCODED: Mange programmerere bruker PHP urlencode () funksjon for å håndtere deres URL-koding. Dette filteret gjør i hovedsak det samme. For eksempel vil dette kode for eventuelle mellomrom og / eller spesialtegn fra en inntastingsstreng:

 $ verdi = ''; ekko filter_var ($ verdi, FILTER_SANITIZE_ENCODED);

Dette skriptet vil kode inn tegnsetting, mellomrom og parentes, og returner deretter følgende:

 % 3Cscript% 3Ealert% 28% 27TROUBLE% 20HERE% 27% 29%% 3B 3C% 2Fscript% 3E

FILTER_SANITIZE_SPECIAL_CHARS: Dette filteret vil som standard HTML-kode spesialtegn som sitater, ampersands og parentes (i tillegg til tegn med ASCII-verdi mindre enn 32). Selv om demo-siden ikke gjør det rikelig klart uten å se kilden (fordi de HTML-kodede spesialtegnene blir tolket og gjengitt), ser du kilden på koden, ser du kodingen på jobb:

 $ verdi = ''; ekko filter_var ($ verdi, FILTER_SANITIZE_SPECIAL_CHARS);

Den konverterer spesialtegnene til deres HTML-kodede selv:

 

FILTER_SANITIZE_EMAIL: Dette filteret gjør akkurat det man tror det gjør. Det fjerner eventuelle tegn som er ugyldige i e-postadresser (som parenteser, parenteser, kolonner osv.). For eksempel, la oss si at du ved et uhell lagt til parentes rundt et brev av din e-postadresse (ikke spør hvordan du bruker fantasien din):

 $ value = 't (e) [email protected]'; ekko filter_var ($ verdi, FILTER_SANITIZE_EMAIL);

Det fjerner disse parentesene, og du får din vakre e-postadresse tilbake:

 [email protected]

Dette er et flott filter å bruke på e-postskjemaer i samspill med FILTER_VALIDATE_EMAIL for å redusere brukerfeil eller forhindre XSS-relaterte angrep (som noen tidligere XSS-angrep innebar retur av de opprinnelige dataene som ble levert i et ikke-sanitisert e-postfelt direkte til nettleseren).

FILTER_SANITIZE_URL: I likhet med e-postadressen sanitiser filter, gjør dette filteret nøyaktig det man ville tro det også. Det fjerner eventuelle tegn som er ugyldige i en nettadresse (som visse UTF-8 tegn osv.). For eksempel, la oss si at du ved et uhell lagt til et "®" i webområdet ditt URL (igjen, ikke spør hvordan, la som om en velociraptor gjorde det):

 $ value = 'http: //net.tuts®plus.com'; ekko filter_var ($ verdi, FILTER_SANITIZE_URL);

Den fjerner uønsket "®", og du får din kjekk URL tilbake:

 http://net.tutsplus.com

FILTER_SANITIZE_NUMBER_INT: Dette filteret ligner på FILTER_VALIDATE_INT, men i stedet for å bare sjekke om det er et heltall eller ikke, fjerner det faktisk alt ikke heltall fra verdien! Handy, faktisk, for pesky spambots og tricksters i noen inngangsformer:

 $ value01 = '123abc456def'; ekko filter_var ($ verdi01, FILTER_SANITIZE_NUMBER_INT); ekko '
'; $ value02 = '1.2.3.4.5.6.7.8.9'; ekko filter_var ($ value02, FILTER_SANITIZE_NUMBER_INT);

De dumme bokstavene og decimaler blir kastet rett ut:

 123456 123456789

FILTER_SANITIZE_NUMBER_FLOAT: Dette filteret ligner på FILTER_VALIDATE_INT, men i stedet for å bare sjekke om det er et heltall eller ikke, fjerner det faktisk alt ikke heltall fra verdien! Handy, faktisk, for pesky spambots og tricksters i noen inngangsformer:

 $ value01 = '123abc456def'; ekko filter_var ($ value01, FILTER_SANITIZE_NUMBER_FLOAT); ekko '
'; $ value02 = '1.2.3.4.5.6.7.8.9'; ekko filter_var ($ value02, FILTER_SANITIZE_NUMBER_FLOAT);

Igjen blir alle de dumme bokstavene og decimaler kastet rett ut:

 123456 123456789

Men hva om du ønsket å holde et desimal som i neste eksempel:

 $ verdi = '1,23'; ekko filter_var ($ verdi, FILTER_SANITIZE_NUMBER_FLOAT);

Det ville fortsatt fjerne det og returnere:

 123

En av hovedgrunnene til at FILTER_SANITIZE_NUMBER_FLOAT og FILTER_SANITIZE_INT er separate filtre, er å tillate dette via en spesiell flagg "FILTER_FLAG_ALLOW_FRACTION" som legges til når en tredje verdi overføres til filter_var:

 $ verdi = '1,23'; ekko filter_var ($ verdi, FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION);

Det ville holde desimaltallet og returnere:

 1,23

Alternativer, Flagger og Array Controls, OH MY!

Flagget i dette siste eksempelet er bare en av mange flere alternativer, flagg og array kontroller som lar deg få mer granulær kontroll over hvilke typer data som blir sanitized, definisjoner av avgrensere, hvordan arrays blir behandlet av filtrene og mer. Du finner mer om disse flaggene og andre filterrelaterte funksjoner i PHP-håndbokens Filters Extension-seksjon.

Andre metoder for å sanse data med PHP

Nå skal vi gå over noen få viktige, supplerende metoder for å sanitere data med PHP for å hindre at "skitne data" forårsaker ødeleggelse på systemene dine. Disse er spesielt nyttige for applikasjoner som fortsatt kjører PHP 4, da de var tilgjengelige når det ble utgitt.

htmlspecialchars: Denne PHP-funksjonen konverterer 5 spesialtegn til deres tilsvarende HTML-enheter:

  • '&' (ampersand) blir '&'
  • '' '(dobbeltsatt) blir' '' når ENT_NOQUOTES ikke er angitt.
  • "(enkelt sitat) blir bare når ENT_QUOTES er angitt.
  • '<' (less than) becomes '<'
  • '>' (større enn) blir '>'

Den brukes som alle andre PHP-strengfunksjoner:

 ekko htmlspecialchars ('$ string');

htmlentities: Som htmlspecialchars konverterer denne PHP-funksjonen tegn til deres tilsvarende HTML-enheter. Den store forskjellen er det ALLE tegn som kan konverteres vil bli konvertert. Dette er en nyttig metode for å forvirre e-postadresser fra noen bots som samler e-postadresser, da ikke av dem er programmert for å lese htmlentiteter.

Den brukes som alle andre PHP-strengfunksjoner:

 ekko htmlentiteter ('$ string');

mysql_real_escape_string: Denne MySQL-funksjonen bidrar til å beskytte mot SQL-injeksjonsangrep. Det regnes som en best practice (eller til og med en obligatorisk praksis) for å overføre alle data som sendes til en MySQL-spørring gjennom denne funksjonen. Det unnslipper noen spesialtegn som kan være problematisk og ville føre til at små Bobby-tabeller destorierer enda en skoleeleverdatabase.

 $ query = 'VELG * FRA tabell WHERE value = ". mysql_real_escape_string (" $ string ").' LIMIT 1,1 '; $ runQuery = mysql_query ($ spørring);

Egendefinerte funksjoner

For mange mennesker er disse innebygde filtre og funksjoner bare ikke gode nok. Datavalidering av noen data som telefonnumre, postnummer eller e-post krever ofte strengere validering og maskering. For å gjøre dette skaper mange mennesker tilpassede funksjoner for å validere og deres data er ekte. Et eksempel på dette kan være så enkelt som å bruke en MySQL-spørring for å slå opp dataene i en database med kjente verdier som:

 funksjonen checkZipCode ($ verdi) $ zipcheck = 'VELG COUNT (*) FRA' database '.' zipcodes 'WHERE value = "'. filter_var (mysql_real_escape_string ($ verdi), FILTER_SANITIZE_NUMBER_INT). $ count = mysql_query ($ zipcheck); hvis ($ count == 1) return TRUE;  ellers returnere FALSE; 

Andre tilpassede funksjoner kan utføres som ikke stole på databaser med kjente verdier, og kan opprettes ved å sjekke magiske sitater, strippingstrekk og flykte for å sette inn i en database:

 funksjon cleanString ($ string) $ detagged = strip_tags ($ string); hvis (get_magic_quotes_gpc ()) $ stripped = stripslashes ($ detagged); $ escaped = mysql_real_escape_string ($ strippet);  ellers $ escaped = mysql_real_escape_string ($ detagged);  returner $ escaped; 

Mulighetene er uendelige, spesielt hvis du integrerer vanlige uttrykk, men for de fleste anledninger bør PHP Filters Extension gjøre trikset.

  • Følg oss på Twitter, eller abonner på Nettuts + RSS-feed for flere daglige webutviklinger og artikler.