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.
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.
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:
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.
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
Filter ID | \ n "; ekko"Filternavn | \ n
$ filter | ".Filter_id ($ filter)." |
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.
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.
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 or from an input string:
$value = ''; 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
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.
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:
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);
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.