WN

WN (https://www.wn.se/forum/index.php)
-   Serversidans teknologier (https://www.wn.se/forum/forumdisplay.php?f=4)
-   -   Skottsäkert skydd mot SQL-injection? (https://www.wn.se/forum/showthread.php?t=1041230)

Lando 2010-03-31 04:23

Skottsäkert skydd mot SQL-injection?
 
Hej alla!

Jag har kollat runt lite och hittar inget bra om SQL-injections. Finns det något Skottsäkert skydd emot detta?

Tex:

Bra:
$var = $_GET[var]; //1
$sql = "SELECT * FROM ex WHERE var='$var'"; //SELECT * FROM ex WHERE var='1'

Problem:
$var = $_GET[var]; //' OR 1=1
$sql = "SELECT * FROM ex WHERE var='$var'"; //SELECT * FROM ex WHERE var='1' OR 1=1

Tack för svar!

najk 2010-03-31 07:56

Kika på http://php.net/manual/en/function.my...ape-string.php

youheardit 2010-03-31 08:42

jag brukar använda:
PHP-kod:

$var mysql_real_escape_string(stripslashes(strip_tags($_GET['var']))); 

Fast jag använder bara strip_tags() om informationen ska skrivas ut utan html kodning osv.
Annars kan du ignorera den!

BjörnJ 2010-03-31 09:09

Om det är heltal kan man köra:
PHP-kod:

$var intval($_GET[var]); 

Om det är flyttal kan man köra floatval(). Annars alltid mysql_real_escape_string() som najk länkade till. Den senare kan användas även till numeriska värden.

En fördel med intval och floatval är om man ska använda datan på andra ställen också, och inte bara i databasanrop. Man behöver t.ex. inte använda htmlspecialchars() vid utskrift av data från intval() eller floatval().

Om man verifierar datan på något sätt (t.ex. för att se att ett formulär är rätt ifyllt) kan man i vissa fall skippa mysql_real_escape_string(), men då gäller det att man verkligen har ordentlig koll på vad man gör, och vara säker på att det inte kan leda till problem om man gör någon uppdatering av koden i framtiden.

Tänk på att all data som kommer från användaren kan vara försök till SQL-injection, inklusive bl.a. cookies och information om vilken webbläsare som används.

martine 2010-03-31 10:31

Jag för min del använder $var = (int)$_GET['var']; vilket gör samma sak som BjörnJ:s kod.
Det finns även andra fördelar med att betrakta siffervärden som just siffror och att genomföra en injektion med enbart siffror lär nog vara helt omöjligt.

Dessutom Lando, så finns det ingen anledning att använda ' med nummer i din query eftersom det inte handlar om strängar...

eliasson 2010-03-31 10:46

Min rekommendation är att endast använda mysql_real_escape_string() vid in-data, och sedan använder du nödvändiga funktioner (t ex stripslashes() osv) när du skriver ut informationen.

emilv 2010-03-31 10:52

Min rekommendation är att köra PDO så slipper du tänka på SQL-injektioner. Då får du även fördelen att det blir lättare vid ett eventuellt byte av databasmotor.

forngren 2010-03-31 12:33

Prepared statements eller PDO som emil redan tipsat om är the shit.

tartareandesire 2010-03-31 13:18

Just $_GET-variablerna är många som glömmer bort att skydda av någon anledning. mysql_real_escape_string är det som gäller "som vanligt".

Därutöver kan du alltid köra t.ex. intval när du ska ha ett heltal. Som martine påpekade är det onödigt att använda citattecken när det handlar om heltalsfält. Se istället till att du alltid skickar in ett heltal (den valideringen måste du ändå göra om sidan ska fungera som det är tänkt) så går sql-satsen något snabbare att exekvera. Det är bra att rutinoptimera kod så slipper man tänka på det när man väl arbetar med tyngre trafik.

Ara 2010-03-31 17:03

SQL-injection, det va vär typ 7-8 år sedan det funkade? Eller är folk/siter fortfarande kassa på att skydda sig?

emilv 2010-03-31 17:19

Citat:

Ursprungligen postat av Ara (Inlägg 20349042)
SQL-injection, det va vär typ 7-8 år sedan det funkade? Eller är folk/siter fortfarande kassa på att skydda sig?

Wordpress hade en ett hål senast i höstas som gjorde att en utomstående kunde byta lösenord på admin-kontot med hjälp av en SQL-injektion. Ja, folk har fortfarande sådana problem.

real_escape-funktionerna (som faktiskt pratar med MySQL för att utföra arbetet) är väl inte heller särskilt gamla? Många använder nog fortfarande mysql_escape_string som ju är välkänt osäker.

eliasson 2010-03-31 18:38

Citat:

Ursprungligen postat av Ara (Inlägg 20349042)
SQL-injection, det va vär typ 7-8 år sedan det funkade? Eller är folk/siter fortfarande kassa på att skydda sig?

Det handlar väl främst om att språket måste utvecklas och hantera detta korrekt, vilket det gör genom PDO.
Nybörjare är alltid nybörjare, eller hur?

taz76 2010-03-31 22:26

Codeigniters funktion XSS_Clean kanske är något..

patrikweb 2010-04-01 00:09

Citat:

Ursprungligen postat av Ara (Inlägg 20349042)
SQL-injection, det va vär typ 7-8 år sedan det funkade? Eller är folk/siter fortfarande kassa på att skydda sig?

Tar under 5 min hitta någon sida att göra SQL injection på, finns även en hel del kritiska sidor det funkar utmärkt på.

Så är fortfarande jävligt illa.

Lando 2010-04-01 01:58

Bra svar allihopa! Ska sätta mig ner och koda ihop en funktion utefter alla svar.

Självklart är detta fortfarande ett problem. Speciellt om man är nybörjare. En grej jag förlitat mig på innan var detta:
http://php.net/manual/en/security.magicquotes.php

Men många webbhotell kör inte på det.

emilv 2010-04-01 07:51

Citat:

Ursprungligen postat av Lando (Inlägg 20349128)
Bra svar allihopa! Ska sätta mig ner och koda ihop en funktion utefter alla svar.

Självklart är detta fortfarande ett problem. Speciellt om man är nybörjare. En grej jag förlitat mig på innan var detta:
http://php.net/manual/en/security.magicquotes.php

Men många webbhotell kör inte på det.

Du ska aldrig lita på magic_quotes_gpc.
* Det är en inställning man kan stänga av så även om du förlitar dig på det måste du skriva en egen funktion som gör samma sak ifall du tänker hosta din kod på servrar utanför din kotnroll (till exempel webbhotell).
* Magic_quotes_gpc är inte säker. Den missar många tecken, särskilt Unicode-tecken som knäckare gärna använder sig av.
* Det är drygt om man faktiskt tänkt använda datat direkt och inte i en databas.

Av ovanstående anledningar är magic_quotes_gpc på utdöende. I kommande versioner av PHP kommer funktionen att plockas bort helt och hållet så det är lika bra att börja göra det på egen hand på en gång, till exempel med PDO eller mysqli_real_escape_string.

Holger 2010-04-07 16:24

Skulle rekommendera att hämta alla in-parametrar med filter_input.
Det, tillsammans med mysql_real_escape_string, hjälper en hel del.

Norman 2010-04-07 22:32

prepared statements

och vill man kan man ju köra php sanitize libbet om man känner sig extra paranoid.
Kan styra och ställa i allt vad som tillåts som indata, undika XSS och liknande.

Draqir 2010-04-09 13:57

PHP-kod:

mysql_real_escape_string(htmlentities(XSS_CLEAN(filter_input('INPUT_POST'$strFILTER_SANITIZE_ENCODED )), ENT_QUOTES), $dbobj)); 

Kom ihåg: Att städa är mycket roligt...

SimonP 2010-04-09 14:36

Som en del redan nämnt, glöm inte av att skydda er mot XSS.

I dagläget är det nog mer vanligt med XSS-hål än med SQL-injection hål, även större företag missar XSS:en, det finns t.ex en svensk bank som har ett XSS-hål som innebär att man kan sno sessions-cookien :|

I PHP är htmlspecialchars() är det första steget man bör använda för att skydda sig mot XSS. Beroende på applikationen kan man även behöva komplettera med fler skydd.

Fredrik-s 2010-04-09 17:55

Citat:

Ursprungligen postat av Lando (Inlägg 20349128)
Bra svar allihopa! Ska sätta mig ner och koda ihop en funktion utefter alla svar.

Självklart är detta fortfarande ett problem. Speciellt om man är nybörjare. En grej jag förlitat mig på innan var detta:
http://php.net/manual/en/security.magicquotes.php

Men många webbhotell kör inte på det.

Kommer du upp med någon bra lösning får du jätte gärna dela med dig. Alltid bra att se säkerhetslösning utifrån någon annans perspektiv.

Jine 2010-04-09 22:46

Jag tror redan jag har haft denna diskussion med dig Joakim!
Tipsade dig om att kika på prepared statments för ett "bombsäkert" alternativ.

PHP-kod:

// ? är placeholders
$stmt $mysqli->prepare("INSERT INTO tabell VALUES (?, ?, ?, ?)");

// sssd står för "String, String, String, Digit"
$stmt->bind_param('sssd'$field$field$field$int);

// execute prepared statement
$result $stmt->execute();

echo 
$stmt->affected_rows.' påverkade rader.'



Alla tider är GMT +2. Klockan är nu 20:02.

Programvara från: vBulletin® Version 3.8.2
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Svensk översättning av: Anders Pettersson