Schoon worden met PHP

Gegevensbeveiliging is belangrijk en vaak ondergewaardeerd door ontwerpers, ontwikkelaars en klanten. Sinds PHP 5.2.0 is data-sanering en -validatie aanzienlijk eenvoudiger gemaakt met de introductie van data-filtering. Vandaag gaan we deze filters van dichterbij bekijken, gebruiken en enkele aangepaste functies bouwen.

Zelfstudiedetails

  • Programma: PHP
  • Versie: 5.2.0+
  • Moeilijkheidsgraad: Beginner
  • Geschatte voltooiingstijd: 20 minuten

Invoering

Ik heb altijd het gevoel gehad dat het gemakkelijk is om code te schrijven in PHP, en nog makkelijker om slechte code te schrijven in PHP. De verspreiding van PHP op het web is echt geholpen door het gebruik in populaire open-source softwarepakketten zoals WordPress, Drupal en Magento, evenals grote webapps zoals Facebook; waarbij PHP in zoveel verschillende gevallen wordt gebruikt (dynamische websites, diepgaande webapplicaties, blogplatforms, contentmanagementsystemen en e-commerce die slechts een deelverzameling is van de vele toepassingen van PHP) bieden de mogelijkheden voor vuil data en onveilige systemen zijn talrijk. Deze tutorial zal enkele methoden van Schoon worden met PHP: Data Sanitization and Validation door te focussen op verschillende vormen van data-invoer en het gebruik van PHP-filters en aangepaste functies.

Waarom Sanitize and Validate?

In deze zelfstudie concentreren we ons echt op gegevensinvoer die gebruikers of externe bronnen mogelijk bieden. Dit betekent dat we geen controle hebben over de gegevens die we ontvangen. Het enige wat we kunnen doen is controleren wat er mee gebeurt nadat we het hebben ontvangen. Er zijn allerlei bedreigingen met betrekking tot gegevensbeveiliging van gebruikersinputs en gegevens van derden.

Sommige un-populaire databeveiliging bedreigingen:

  • Cross-Site Scripting (XSS): Een vorm van code-injectie waarbij een script wordt geïnjecteerd op een website vanaf een geheel andere website. Dit is veruit de meest voorkomende beveiligingslek online. Twee recente, zeer prominente voorbeelden van deze techniek zijn de Stalk Daily en Mikeyy Twitter Worms van eerder dit jaar die slecht gesanitiseerde inputs gebruikten om Javascript te starten via een "geïnfecteerde" Twitter-webinterface.
  • SQL injectie: De tweede meest voorkomende beveiligingslek online, dit is een andere vorm van code-injectie waarbij een script wordt gebruikt om deel te nemen aan een van de vele uitbuitende gedragingen, inclusief (maar niet beperkt tot) het blootstellen en / of verkrijgen van ongeautoriseerde toegang tot gegevens, het wijzigen van gegevens binnenin van een database, of eenvoudigweg het injecteren van code die moet worden weergegeven of uitgevoerd binnen een website, waardoor de website wordt verbroken of gewijzigd.
  • Cross-Site Request Forgery (CSRF / XSRF): Een minder algemene exploit die meer afhankelijk is van gegevensbronnen zoals browser- en sessiecookies dan slecht gedesinfecteerde en gevalideerde gegevensinvoer, CSRF (uitgesproken als "sea-surf") kan worden gebruikt om opdrachten uit te voeren op een website zonder toestemming van de gebruiker. Een populaire CSRF-methode is het gebruik van een onjuist gevormde afbeeldingsgegevens URI of src-waarde om een ​​script uit te voeren in plaats van een afbeelding weer te geven.
  • Onjuiste gegevens: Niet echt een "beveiligingsrisico" per se, onjuiste gegevens kunnen leiden tot problemen met een website-eigenaar of databasebeheerder. Onjuiste gegevens kunnen vaak slecht gecodeerde websites doorbreken of ervoor zorgen dat geautomatiseerde systemen vastlopen. Een voorbeeld hiervan was de mogelijkheid om hele MySpace-profielpagina's te wijzigen door deze met allerlei soorten HTML / CSS-hacking te plaatsen (let op: dit kan nog steeds werken; ik heb MySpace al lange tijd niet gebruikt).
Afbeeldingsbron: XKCD

Voor onze doeleinden gaan we ons alleen richten op methoden op de server om de gegevensveiligheid met PHP te verbeteren, dus laten we eens kijken hoe de termen "sanering" en "validatie" worden gedefinieerd met betrekking tot PHP. Volgens de PHP-handleiding:

Validatie wordt gebruikt om te valideren of om te controleren of de gegevens aan bepaalde kwalificaties voldoen. Doorgeven in FILTER_VALIDATE_EMAIL bepaalt bijvoorbeeld of de gegevens een geldig e-mailadres zijn, maar de gegevens zelf niet wijzigen.

Ontsmetting zal de gegevens opschonen, zodat deze kan veranderen door ongewenste tekens te verwijderen. Als u bijvoorbeeld FILTER_SANITIZE_EMAIL doorgeeft, worden tekens verwijderd die niet geschikt zijn om als e-mailadres te worden gebruikt. Dat gezegd hebbende, het valideert de gegevens niet.

Als uw website de nachtclub is waar iedereen naar toe wil, controleert de validatie de gastenlijst en identiteitsbewijzen aan de deur, terwijl ontsmetting fungeert als de uitsmijter die ongewenst gedrag weggooit. Met dit in gedachten, laten we eens kijken naar PHP Filters Extension.

Welke filters heb ik?

Alle PHP-installaties zijn niet gelijk gemaakt. Hoewel PHP 5.2.0 de introductie van filters was, hebben niet alle installaties dezelfde filters in hun filterextensie. De meeste installaties hebben alle filters die we gaan gebruiken, maar om u iets over de Filters-extensie te leren, gaan we ontdekken wat u op uw server hebt. In de brondownload heb ik een bestand opgenomen met de naam getfilters.php dat, eenmaal geïnstalleerd en uitgevoerd op uw server, al uw filters zal weergeven (beide gegevensfilters beschikbaar via de filter_var functie- en stroomfilters beschikbaar via stream_filter_append).

 echo "

Gegevensfilters

\ n\ n\ n "; echo"\ n "; echo"\ n"; foreach (filter_list () als $ id => $ filter) echo"\ n "; echo"
Filter IDNaam filteren
$ filter".Filter_id ($ filter)."
\ N ";

Eerst krijgen we de array met de lijst met alle beschikbare filters bij filter_list, dan lus-sen we door de array en geven we de filternaam uit, vinden we de toegewezen ID van het filter en geven ook deze ID weer.

Hoe gebruik ik een filter?

PHP-filters voor validatie en ontsmetting worden geactiveerd door ten minste twee waarden door te geven aan de PHP Filters-uitbreidingsfunctie filter_var. Laten we als voorbeeld het Sanitize-filter gebruiken voor een geheel getal zoals:

 $ waarde = '123abc456def'; echo filter_var ($ waarde, FILTER_SANITIZE_NUMBER_INT);

In het voorbeeld hebben we een variabele $ value die wordt doorgegeven via de functie Filtersverlenging filter_var de ... gebruiken FILTER_SANITIZE_NUMBER_INT filter. Dit resulteert in de volgende uitvoer:

 123456

Het Sanitize-filter voor een geheel getal verwijdert alle niet-gehele tekens uit de uitvoer en produceert een schoon geheel getal. In de downloadbroncode kunt u verschillende ingangen uitproberen en een aantal algemene filters toepassen op uw invoerwaarde. Ik heb een aantal verschillende voorbeeldreeksen toegevoegd die u ook kunt uitproberen.

Wat doen de verschillende filters?

De onderstaande lijst is niet compleet, maar bevat wel de meeste filters die standaard bij installaties met 5.2.0+ worden geleverd. Aangepaste filters en filters die zijn toegevoegd vanuit aangepaste extensies zijn hier niet opgenomen.

FILTER_VALIDATE_BOOLEAN: Controleert of de gegevens die zijn doorgegeven aan het filter een Booleaanse waarde hebben van TRUE of VALSE. Als de waarde een niet-booleaanse waarde is, wordt deze geretourneerd VALSE. Het onderstaande script zou "TRUE" voor de voorbeeldgegevens weergeven $ value01 maar zou "FALSE" voor de voorbeeldgegevens weergeven $ value02:

 $ value01 = TRUE; if (filter_var ($ value01, FILTER_VALIDATE_BOOLEAN)) echo 'TRUE';  else echo 'FALSE';  echo '

'$ value02 = TRUE; if (filter_var ($ value02, FILTER_VALIDATE_BOOLEAN)) echo 'TRUE'; else echo 'FALSE';

FILTER_VALIDATE_EMAIL: Controleert of de gegevens die aan het filter zijn doorgegeven een mogelijk geldig e-mailadres zijn. Het controleert niet of het e-mailadres daadwerkelijk bestaat, alleen dat het formaat van het e-mailadres geldig is. Het onderstaande script zou "TRUE" voor de voorbeeldgegevens weergeven $ value01 maar zou "FALSE" voor de voorbeeldgegevens weergeven $ value02 (omdat de tweede het vereiste @ domain.tld gedeelte van het e-mailadres mist):

 $ value01 = '[email protected]'; if (filter_var ($ value01, FILTER_VALIDATE_EMAIL)) echo 'TRUE';  else echo 'FALSE';  echo '

'$ value02 =' nettuts '; if (filter_var ($ value02, FILTER_VALIDATE_EMAIL)) echo 'TRUE'; else echo 'FALSE';

FILTER_VALIDATE_FLOAT: Controleert of de gegevens die naar het filter zijn doorgegeven, een geldige waarde zijn. Het onderstaande script zou "TRUE" voor de voorbeeldgegevens weergeven $ value01 maar zou "FALSE" voor de voorbeeldgegevens weergeven $ value02 (omdat komma-scheidingstekens niet zijn toegestaan ​​in zwevende waarden):

 $ value01 = '1.234'; if (filter_var ($ value01, FILTER_VALIDATE_FLOAT)) echo 'TRUE';  else echo 'FALSE';  echo '

'$ value02 =' 1,234 '; if (filter_var ($ value02, FILTER_VALIDATE_FLOAT)) echo 'TRUE'; else echo 'FALSE';

FILTER_VALIDATE_INT: Controleert of de gegevens die zijn doorgegeven aan het filter een geldige integerwaarde hebben. Het onderstaande script zou "TRUE" voor de voorbeeldgegevens weergeven $ value01 maar zou "FALSE" voor de voorbeeldgegevens weergeven $ value02 (omdat breuken / decimale getallen geen gehele getallen zijn):

 $ value01 = '123456'; if (filter_var ($ value01, FILTER_VALIDATE_INT)) echo 'TRUE';  else echo 'FALSE';  echo '

'$ value02 =' 123.456 '; if (filter_var ($ value02, FILTER_VALIDATE_INT)) echo 'TRUE'; else echo 'FALSE';

FILTER_VALIDATE_IP: Controleert of de gegevens die zijn doorgegeven aan het filter een mogelijk geldig IP-adres zijn. Het controleert niet of het IP-adres zou worden opgelost, alleen dat het geschikt is voor de vereiste gegevensstructuur voor IP-adressen. Het onderstaande script zou "TRUE" voor de voorbeeldgegevens weergeven $ value01 maar zou "FALSE" voor de voorbeeldgegevens weergeven $ value02:

 $ value01 = '192.168.0.1'; if (filter_var ($ value01, FILTER_VALIDATE_IP)) echo 'TRUE';  else echo 'FALSE';  echo '

'$ value02 =' 1.2.3.4.5.6.7.8.9 '; if (filter_var ($ value02, FILTER_VALIDATE_IP)) echo 'TRUE'; else echo 'FALSE';

FILTER_VALIDATE_URL: Controleert of de gegevens die zijn doorgegeven aan het filter een mogelijk geldige URL zijn. Er wordt niet gecontroleerd of de URL zou worden opgelost, alleen dat deze geschikt is voor de vereiste gegevensstructuur voor URL's. Het onderstaande script zou "TRUE" voor de voorbeeldgegevens weergeven $ value01 maar zou "FALSE" voor de voorbeeldgegevens weergeven $ value02:

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

'$ value02 =' nettuts '; if (filter_var ($ value02, FILTER_VALIDATE_URL)) echo 'TRUE'; else echo 'FALSE';

FILTER_SANITIZE_STRING: Standaard verwijdert dit filter alle gegevens uit een reeks die ongeldig is of niet is toegestaan ​​in die reeks. Hiermee worden bijvoorbeeld alle HTML-tags verwijderd, zoals '; echo filter_var ($ waarde, FILTER_SANITIZE_STRING);

Dit script zou de tags verwijderen en het volgende retourneren:

 alert ('PROBLEEM HIER');

FILTER_SANITIZE_ENCODED: Veel programmeurs gebruiken PHP's urlencode () functie om hun URL-codering af te handelen. Dit filter doet in essentie hetzelfde. Dit codeert bijvoorbeeld alle spaties en / of speciale tekens uit een invoertekenreeks:

 $ value = ''; echo filter_var ($ waarde, FILTER_SANITIZE_ENCODED);

Dit script codeert de interpunctie, spaties en haakjes en retourneert vervolgens het volgende:

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

FILTER_SANITIZE_SPECIAL_CHARS: Dit filter codeert standaard speciale tekens zoals aanhalingstekens, ampersands en haakjes (naast tekens met een ASCII-waarde van minder dan 32). Hoewel de demopagina het niet overduidelijk maakt zonder de bron te bekijken (omdat de HTML-gecodeerde speciale tekens worden geïnterpreteerd en weergegeven), als u de broncode bekijkt, ziet u de codering op het werk:

 $ value = ''; echo filter_var ($ waarde, FILTER_SANITIZE_SPECIAL_CHARS);

Het converteert de speciale tekens naar hun HTML-gecodeerde zelf:

 

FILTER_SANITIZE_EMAIL: Dit filter doet precies wat men denkt dat het doet. Het verwijdert tekens die ongeldig zijn in e-mailadressen (zoals haakjes, haakjes, dubbele punten, enz.). Laten we bijvoorbeeld zeggen dat je per ongeluk een paar haakjes hebt toegevoegd rond een letter van je e-mailadres (vraag niet hoe, gebruik je fantasie):

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

Het verwijdert deze haakjes en u krijgt uw mooie e-mailadres terug:

 [email protected]

Dit is een geweldig filter om te gebruiken op e-mailformulieren in samenwerking met FILTER_VALIDATE_EMAIL om gebruikersfouten te verminderen of XSS-gerelateerde aanvallen te voorkomen (aangezien sommige eerdere XSS-aanvallen de teruggave van de oorspronkelijke gegevens in een niet-gezuiverd e-mailveld rechtstreeks betroffen naar de browser).

FILTER_SANITIZE_URL: Net als het e-mailadres filter reinigen, doet dit filter ook precies wat je zou denken. Het verwijdert tekens die ongeldig zijn in een URL (zoals bepaalde UTF-8-tekens, enzovoort). Laten we bijvoorbeeld zeggen dat u per ongeluk een "®" in de URL van uw website hebt toegevoegd (nogmaals, vraag niet hoe, doe alsof een velociraptor het deed):

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

Het verwijdert de ongewenste "®" en je krijgt je mooie URL terug:

 http://net.tutsplus.com

FILTER_SANITIZE_NUMBER_INT: Dit filter is vergelijkbaar met FILTER_VALIDATE_INT maar in plaats van eenvoudig te controleren of het een geheel getal is of niet, wordt feitelijk alles niet-geheel getal verwijderd uit de waarde! Handig, inderdaad, voor vervelende spambots en bedriegers in sommige invoervormen:

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

Die domme letters en decimalen worden er meteen uit gegooid:

 123456 123456789

FILTER_SANITIZE_NUMBER_FLOAT: Dit filter is vergelijkbaar met FILTER_VALIDATE_INT maar in plaats van eenvoudig te controleren of het een geheel getal is of niet, wordt feitelijk alles niet-geheel getal verwijderd uit de waarde! Handig, inderdaad, voor vervelende spambots en bedriegers in sommige invoervormen:

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

Nogmaals, al die domme letters en decimalen worden eruit gegooid:

 123456 123456789

Maar wat als u een decimaal wilt behouden zoals in het volgende voorbeeld:

 $ waarde = '1,23'; echo filter_var ($ waarde, FILTER_SANITIZE_NUMBER_FLOAT);

Het zou het nog steeds verwijderen en terugkeren:

 123

Een van de belangrijkste redenen waarom FILTER_SANITIZE_NUMBER_FLOAT en FILTER_SANITIZE_INT afzonderlijke filters zijn, is om dit toe te staan ​​via een speciale vlag "FILTER_FLAG_ALLOW_FRACTION" die is toegevoegd als een derde waarde die is doorgegeven aan filter_var:

 $ waarde = '1,23'; echo filter_var ($ waarde, FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION);

Het zou de komma behouden en terugkeren:

 1.23

Opties, vlaggen en matrixbesturing, OH MY!

De vlag in dit laatste voorbeeld is slechts een van de vele opties, vlaggen en arraycontroles waarmee u meer gedetailleerde controle hebt over welke typen gegevens worden verwijderd, definities van scheidingstekens, hoe arrays worden verwerkt door de filters en meer. Je kunt meer over deze vlaggen en andere filtergerelateerde functies vinden in de sectie Filters Extension van de PHP-handleiding.

Andere methoden om gegevens te identificeren met behulp van PHP

Nu bespreken we een paar belangrijke aanvullende methoden om gegevens te zuiveren met PHP om te voorkomen dat "vuile gegevens" schade aanrichten op uw systemen. Deze zijn vooral handig voor applicaties die nog steeds PHP 4 draaien, omdat ze allemaal beschikbaar waren toen deze werd vrijgegeven.

htmlspecialchars: Deze PHP-functie converteert 5 speciale tekens naar hun bijbehorende HTML-entiteiten:

  • '&' (ampersand) wordt '&'
  • '' '(dubbel aanhalingsteken) wordt' "'als ENT_NOQUOTES niet is ingesteld.
  • "(enkel aanhalingsteken) wordt alleen '' 'als ENT_QUOTES is ingesteld.
  • '<' (less than) becomes '<'
  • '>' (groter dan) wordt '>'

Het wordt gebruikt als elke andere PHP-tekenreeksfunctie:

 echo htmlspecialchars ('$ string');

htmlentities: Net als htmlspecialchars converteert deze PHP-functie tekens naar hun overeenkomstige HTML-entiteiten. Het grote verschil is dat ALLEMAAL tekens die kunnen worden geconverteerd, worden geconverteerd. Dit is een nuttige methode om e-mailadressen van sommige bots die e-mailadressen verzamelen te versluieren, omdat niet van hen zijn geprogrammeerd om htmlentities te lezen.

Het wordt gebruikt als elke andere PHP-tekenreeksfunctie:

 echo htmlentities ('$ string');

mysql_real_escape_string: Deze MySQL-functie helpt beschermen tegen SQL-injectie-aanvallen. Het wordt als een best practice (of zelfs een verplichte praktijk) beschouwd om alle gegevens die via deze functie naar een MySQL-query worden verzonden, door te geven. Het ontsnapt aan speciale tekens die problematisch zouden kunnen zijn en zou ervoor zorgen dat kleine Bobby-tabellen nog een andere schoolstudenten-database zouden vernietigen.

 $ query = 'SELECT * FROM tabel WHERE value = ". mysql_real_escape_string (" $ string'). ' LIMIT 1,1 '; $ runQuery = mysql_query ($ query);

Aangepaste functies

Voor veel mensen zijn deze ingebouwde filters en functies gewoon niet goed genoeg. Gegevensvalidatie van sommige gegevens, zoals telefoonnummers, postcodes of zelfs e-mails, vereist vaak striktere validatie en maskering. Om dit te doen, maken veel mensen aangepaste functies om te valideren en hun gegevens zijn echt. Een voorbeeld hiervan kan net zo eenvoudig zijn als het gebruik van een MySQL-query om de gegevens op te zoeken in een database met bekende waarden zoals:

 function checkZipCode ($ value) $ zipcheck = 'SELECT COUNT (*) FROM' database '.' zipcodes 'WHERE value = "'. filter_var (mysql_real_escape_string ($ value), FILTER_SANITIZE_NUMBER_INT). '"'; $ count = mysql_query ($ zipcheck); if ($ count == 1) return TRUE;  else return FALSE; 

Er kunnen andere aangepaste functies worden gemaakt die niet afhankelijk zijn van databases met bekende waarden en die kunnen worden gemaakt door magische aanhalingstekens, strippen van schuine strepen en escapen voor invoegen in een database te controleren:

 function cleanString ($ string) $ detagged = strip_tags ($ string); if (get_magic_quotes_gpc ()) $ stripped = stripslashes ($ detagged); $ escaped = mysql_real_escape_string ($ gestript);  else $ escaped = mysql_real_escape_string ($ detagged);  return $ escaped; 

De mogelijkheden zijn eindeloos, vooral als u reguliere expressies integreert, maar voor de meeste gelegenheden zou de PHP-filteruitbreiding de slag moeten slaan.

  • Volg ons op Twitter of abonneer je op de Nettuts + RSS-feed voor meer dagelijkse webontwikkelingen, tuts en artikelen.