Sikkerhet er et varmt emne. Å sørge for at nettsteder er sikre er ekstremt viktig for alle webapplikasjoner. Faktisk bruker jeg 70% av tiden min sikrer mine applikasjoner. En av de viktigste tingene vi må sikre er former. I dag skal vi gjennomgå en metode for å forhindre XSS (Cross-site scripting) og Cross-site-forespørsel forfalskning på skjemaer.
Postdata kan sendes fra ett nettsted til et annet. Hvorfor er dette dårlig? Et enkelt scenario ...
En bruker som er logget på nettstedet ditt, besøker et annet nettsted under sin økt. Dette nettstedet vil kunne sende POST-data til nettstedet ditt - for eksempel med AJAX. Fordi brukeren er logget inn på nettstedet ditt, vil den andre nettsiden også kunne sende innleggsdata til sikrede skjemaer som kun er tilgjengelige etter en pålogging..
Vi må også beskytte våre sider mot angrep ved hjelp av cURL
Med skjema taster! Vi legger til en spesiell hash (en formnøkkel) til alle former for å sikre at dataene bare blir behandlet når det er sendt fra nettstedet ditt. Etter at et skjema er sendt, vil vårt PHP-skript validere den innsendte skjema nøkkelen mot skjema nøkkelen vi har satt i en økt.
Først trenger vi en enkel form for demonstrasjonsformål. En av de viktigste formene vi må sikre er påloggingsskjemaet. Påloggingsskjemaet er sårbare kraftbruddstilfeller. Opprett en ny fil, og lagre den som index.php i webroten din. Legg til følgende kode i kroppen:
Sikring av skjemaer med formtastene
Nå har vi en enkel XHTML-side med et påloggingsskjema. Hvis du vil bruke skjema taster på nettstedet ditt, kan du erstatte skriptet ovenfor med din egen påloggingsside. Nå, la oss fortsette den virkelige handlingen.
Vi skal lage en PHP klasse for våre skjema taster. Fordi hver side bare kan inneholde en form nøkkel, kunne vi lage en singleton av vår klasse for å sikre at vår klasse er brukt riktig. Fordi å skape singletoner er et mer avansert OOP-emne, hopper vi over den delen. Opprett en ny fil som heter formkey.class.php og legg den i webroten din. Nå må vi tenke på de funksjonene vi trenger. Først trenger vi en funksjon for å generere en skjema nøkkel, slik at vi kan plassere den i vårt skjema. I din PHP-fil plasser du følgende kode:
Ovenfor ser du en klasse med tre deler: to variabler og en funksjon. Vi gjør funksjonen privat fordi denne funksjonen kun blir brukt av vår produksjonfunksjoner, som vi vil lage senere. I de to variablene lagrer vi formtastene. Disse er også private fordi de bare kan brukes av funksjoner i vår klasse.
Nå må vi tenke på en måte å generere vår skjema nøkkel på. Fordi skjema nøkkelen må være unik (ellers har vi ingen sikkerhet), bruker vi en kombinasjon av brukerens IP-adresse for å binde nøkkelen til en bruker, mt_rand () for å gjøre det unikt, og uniqid () -funksjonen for å gjøre det enda mer unikt. Vi krypterer også denne informasjonen med md5 () for å lage en unik hash som vi deretter kan sette inn på våre sider. Fordi vi brukte md5 (), kan en bruker ikke se hva vi pleide å generere nøkkelen. Hele funksjonen:
// Funksjon for å generere skjema nøkkel privat funksjon generereKey () // Få IP-adressen til brukeren $ ip = $ _SERVER ['REMOTE_ADDR']; // Vi bruker mt_rand () i stedet for rand () fordi det er bedre å generere tilfeldige tall. // Vi bruker "sant" for å få en lengre streng. // Se http://www.php.net/mt_rand for en presis beskrivelse av funksjonen og flere eksempler. $ uniqid = uniqid (mt_rand (), true); // Returner hash return md5 ($ ip. $ Uniqid);
Sett inn koden ovenfor i din formkey.class.php fil. Bytt funksjonen med den nye funksjonen.
For dette trinnet oppretter vi en ny funksjon som utdataer et skjult HTML-felt med skjemaetasten. Funksjonen består av tre trinn:
Vi heter vår funksjon outputKey () og gjør det offentlig, fordi vi må bruke det utenfor vår klasse. Vår funksjon vil ringe til den private funksjonen generateKey () å generere en ny skjema nøkkel og lagre den lokalt i en økt. Til slutt lager vi XHTML-koden. Legg nå følgende kode i vår PHP-klasse:
// Funksjon for å sende ut skjema nøkkelen offentlig funksjon outputKey () // Generer nøkkelen og lagre den inne i klassen $ this-> formKey = $ this-> generateKey (); // Lagre skjema nøkkelen i økten $ _SESSION ['form_key'] = $ this-> formKey; // Utfør skjema nøkkel ekko "formKey. "" /> ";
Nå skal vi legge til skjema nøkkelen til vårt innloggingsskjema for å sikre det. Vi må ta med klassen i vår index.php fil. Vi må også starte økten fordi vår klasse bruker økter til å lagre den genererte nøkkelen. For dette legger vi til følgende kode over doktypen og hovedetiketten:
Koden ovenfor er ganske selvforklarende. Vi starter sesjonen (fordi vi lagrer skjemaetasten) og laster PHP-klassefilen. Deretter starter vi klassen med ny formKey (), Dette vil skape vår klasse og lagre den i $ formkey. Nå må vi bare redigere skjemaet vårt slik at det inneholder skjema nøkkelen:
Og det er alt! Fordi vi opprettet funksjonen outputKey (), vi må bare inkludere det i vårt skjema. Vi kan bruke formtastene i alle former ved å bare legge til outputKey (); ?> Nå bare gjennomgå kilden til nettsiden din, og du kan se at det er en formnøkkel knyttet til skjemaet. Det eneste gjenværende trinnet er å validere forespørsler.
Vi vil ikke validere hele skjemaet; bare skjema nøkkelen. Validere skjemaet er grunnleggende PHP og opplæringsprogrammer finnes over hele nettet. La oss validere skjema nøkkelen. Fordi vår "generateKey" -funksjon overskriver sesjonsverdien, legger vi til en konstruktør i vår PHP-klasse. En konstruktør vil bli kalt når vår klasse er opprettet (eller konstruert). Konstruktøren lagrer den forrige nøkkelen inne i klassen før vi lager en ny; så vi har alltid den forrige skjema nøkkelen for å validere skjemaet vårt. Hvis vi ikke gjorde dette, ville vi ikke kunne validere skjema nøkkelen. Legg til følgende PHP-funksjon i klassen din:
// Konstruktøren lagrer skjema nøkkelen (hvis en finnes) i vår klassevariabel. funksjon __construct () // Vi trenger den forrige nøkkelen slik at vi lagrer den hvis (isset ($ _ SESSION ['form_key'])) $ this-> old_formKey = $ _SESSION ['form_key'];
En konstruktør skal alltid være navngitt __construct (). Når konstruktøren heter, kontrollerer vi om en økt er angitt, og i så fall lagrer vi den lokalt i vår old_formKey variabel.
Nå kan vi validere vår skjema nøkkel. Vi lager en grunnleggende funksjon i vår klasse som validerer skjema nøkkelen. Denne funksjonen bør også være offentlig fordi vi skal bruke den utenfor vår klasse. Funksjonen vil validere POST-verdien til skjema nøkkelen mot den lagrede verdien av skjema nøkkelen. Legg denne funksjonen til PHP-klassen:
// Funksjon som validerte skjema nøkkelen POST data offentlig funksjon validere () // Vi bruker den gamle formKey og ikke den nye genererte versjonen hvis ($ _ POST ['form_key'] == $ this-> old_formKey) // The nøkkelen er gyldig, returner sann. returnere sant; ellers // Nøkkelen er ugyldig, returner falsk. returner falsk;
Innenfor index.php, Vi validerer skjema nøkkelen ved å bruke funksjonen vi nettopp har opprettet i vår klasse. Selvfølgelig godkjenner vi bare etter en POST-forespørsel. Legg til følgende kode etter $ formKey = ny formKey ();
$ error = 'Ingen feil'; // Er forespørsel? hvis $ _ SERVER ['REQUEST_METHOD'] == 'post') // Valider skjema nøkkelen hvis (! isset ($ _ POST ['form_key']) ||! $ formKey-> validate ()) // Skjema nøkkelen er ugyldig, vis en feil $ error = 'Formuleringsnøkkelfeil!'; else // Gjør resten av valideringen din her $ error = 'Ingen skjema nøkkel feil!';
Vi opprettet en variabel $ error som lagrer vår feilmelding. Hvis en POST-forespørsel er sendt, bekrefter vi formeltasten med $ FormKey-> validere (). Hvis dette returneres falskt, er skjema nøkkelen ugyldig og vi viser en feil. Merk at vi bare validerer skjema nøkkelen - du forventes å validere resten av skjemaet selv.
I HTML-koden kan du plassere følgende kode for å vise feilmeldingen:
Dette vil ekko $ error variabel hvis den er innstilt.
Hvis du starter serveren din og går til index.php, Du vil se vårt skjema og meldingen 'Ingen feil'. Når du sender inn et skjema, vil du se meldingen "No form key error" fordi det er en gyldig POST-forespørsel. Prøv nå å laste siden og godta når nettleseren din ber om at POST-data sendes igjen. Du vil se at vårt skript utløser en feilmelding: 'Form-nøkkelfeil!' Skjemaet ditt er nå beskyttet mot innspill fra andre nettsteder og feil med sideopplasting! Feilen vises også etter en oppdatering fordi en ny skjema nøkkel ble generert etter at vi sendte inn skjemaet. Dette er bra fordi brukeren ikke kan tilfeldigvis legge inn et skjema to ganger.
Her er hele PHP og HTML-koden:
index.php
validere ()) // Skjema nøkkel er ugyldig, vis en feil $ error = 'Form nøkkel feil!'; else // Gjør resten av valideringen din her $ error = 'Ingen skjema nøkkel feil!'; ?>Sikring av skjemaer med formtastene fomrkey.class.php
old_formKey = $ _SESSION ['form_key']; // Funksjon for å generere skjema nøkkel privat funksjon generereKey () // Få IP-adressen til brukeren $ ip = $ _SERVER ['REMOTE_ADDR']; // Vi bruker mt_rand () i stedet for rand () fordi det er bedre å generere tilfeldige tall. // Vi bruker "sant" for å få en lengre streng. // Se http://www.php.net/mt_rand for en presis beskrivelse av funksjonen og flere eksempler. $ uniqid = uniqid (mt_rand (), true); // Returner hash return md5 ($ ip. $ Uniqid); // Funksjon for å sende ut skjemaetasten offentlig funksjon outputKey () // Generer nøkkelen og lagre den inne i klassen $ this-> formKey = $ this-> generateKey (); // Lagre skjema nøkkelen i økten $ _SESSION ['form_key'] = $ this-> formKey; // Utfør skjema nøkkel ekko "formKey. "" /> "; // Funksjon som validerte skjema nøkkelen POST data offentlig funksjon validere () // Vi bruker den gamle formKey og ikke den nye genererte versjonen hvis ($ _ POST ['form_key'] == $ this-> old_formKey) // Nøkkelen er gyldig, returner sann. return true; else // Nøkkelen er ugyldig, returner falsk. return false;?>>Konklusjon
Hvis du legger til denne koden i alle viktige former på nettstedet ditt, øker skjemaets sikkerhet dramatisk. Det stopper til og med forfriskende problemer, som vi så i trinn 4. Fordi skjema nøkkelen kun er gyldig for en forespørsel, er det ikke mulig med et dobbelt innlegg..
Dette var min første opplæring, jeg håper du liker den og bruker den til å forbedre sikkerheten din! Gi meg beskjed om dine tanker, via kommentarene. Har en bedre metode? Gi oss beskjed.
Videre lesning
- WordPress bruker også skjema taster (navngi det Nonces): Wordpress Nonces
- Syv vaner for å skrive sikre PHP-applikasjoner
- Følg oss på Twitter, eller abonner på NETTUTS RSS Feed for flere daglige webutviklingsverktøy og artikler.