webForumDet fria alternativet

Det eviga problemet med säker data

11 svar · 1 053 visningar · startad av Qimen

QimenMedlem sedan juni 20015 009 inlägg
#1

Hej!

Varje gång jag sätter mig ned och börjar på ett nytt projekt kommer jag alltid fram till samma sak. Jag behöver en funktion som jag kan köra all data igenom (som ska till eller från databasen).

Samtidigt vill jag ha det lagrat på ett smart sätt, vill ju inte fylla dbn med en massa htmlkoder.

Det jag tänkt på som kan vara bra att ta en titt på är:

- Om det är en array?
- Om det är post/get-data?
- Om magic quotes är på eller ej?
- Om det är det blandade tecken eller endast nummer?
- Om datan är på väg in till dbn eller på väg ut från dbn?
- Om det finns farliga tecken som bör säkras med t.ex. addslashes?
- Om det finns landsspecifika tecken som bör kodas om (åäö)?

Som ni ser finns det en hel del man bör tänka på. Det jag har kört fast på är hur jag ska lagra specifika tecken som åäö, vill samtidigt inte låsa funktionen till endast svenska. Att köra htmlspecialchars på allt känns som lite overkill, lär öka upp storleken på dbn. Kanske räcker det med att köra htmlspecialchars? Eller är det bättre om jag kör addslashes (alt. mysql_real_escape_string) och skapar en egen liten tabell med tecken som kan vara bra att koda om?

Det hela leder till en annan intressant fråga. Bör man ur säkerhetens syn koda om ovanliga tecken som t.ex. åäö eller är det lugnt att lagra dem som det är? :)
Kom gärna med förslag på hur jag kan göra det hela ännu mer säkert.

Mvh
Joakim

colioneMedlem sedan juni 20014 421 inlägg
#2

Prepared statements via PDO eller mysqli samt unicode i dbn bör lösa majoriteten av dina problem. Bara att se till att köra super globals genom stripslashes högst upp i t.ex en include-fil du alltid har med.

QimenMedlem sedan juni 20015 009 inlägg
#3

Mysqli och unicode (utf-8) är vad jag brukar köra. Har tittat en del på prepared statements med mysql 5 men tycker det känns överdrivet/för resurskrävande för att köra på enkla frågor. Iof är det kanske inga problem med att köra med förbereda frågor där det behövs och på övriga på det tradionella sättet. Fast är det att koda på ett snyggt sätt?

Hur menar du med super globals i php? Mina tankar för mig till structs i C men tror inte det är så du menar?

colioneMedlem sedan juni 20014 421 inlägg
#4

Super globals = $_GET, $_POST, $_COOKIE, $_SESSION.

mysqlis prepared statements är inte alls speciellt mer resurskrävane än det vanliga mysql-grännssnittet. Dock, det du förlorar på den lilla extra tid det tar mot databasen vi selects, vinner du på inserts SAMT att du slipper tänka på hur du ska escapea datan rätt.

Jag brukar tycka att den säkerhetsvinst du får vid prepared statements är helt klart värt det, det brukar bli ugefär en rad mer kod per fråga. Dessutom tar det tid och energi att skriva ett skydd, denna energi kan du istället lägga på andra förbättringar.

Personligen använder jag PDO, vid såväl prepared statements som vind vanliga frågor. Dock så ställer jag bara vanliga frågor när jag inte har någon data utifrån inblandad.

QimenMedlem sedan juni 20015 009 inlägg
#5

Efter att ännu en gång tittat och testat med mysqlis prepared statements så har jag kommit fram till samma sak som förr.

Om jag använder det gamla sättet behöver jag inte ha någon "mysql"-kod ute i den vanliga koden, bara i klassen vilket gör att jag kan byta dbms utan större problem. Bara till att anpassa den nya klassen så att den tar samma argument och retunerar på ett likadant sätt. Väldigt bra om det är stora projekt.

Men med prepared statements blir det lite svårare att göra så. Vill inte låsa mig till just mysql. Försöker jag då flytta över det hela till en klass fastnar jag på hur jag ska binda värdena. bind_param tar inte en array som argument.

Som jag skulle vilja ha det (om jag inte tänkt helt fel).

1. En fråga, t.ex. "select ett, två from test where a = ? and b = ?)
2. En array med argument, t.ex. array("ss", "hej", "banan")

Som sedan skickas till funktion, ex. query($sql, $values). I denna funktion körs då prepare, bind_param, execute, bind_result, fetch (alternativt lagrar det och hämtar det med en seperat funktion) och close.

Har jag tänkt rätt eller är jag helt ute och cyklar? :)

Lite hur jag har tänkt:

	function test($db, $sql, $values) {
		if ($stmt = $db->prepare($sql)) {
		
			$stmt->bind_param(); // ("ss", "hej", "banan")
			
			$stmt->execute();		
			$stmt->bind_result($name);
			$stmt->fetch();
			
			printf("%s it is!", $name);
			
			$stmt->close();
			
		}
	}

	$sql = "SELECT name FROM pw_users WHERE name = ? AND temp = ?";
	$values = array("ss", "hej", "banan");
	
	test($mysqli, $sql, $values);
colioneMedlem sedan juni 20014 421 inlägg
#6

PDO har däremot stöd för det. Dessutom får du ett renare objektorienterat grännssnitt.

Här har du ett antal olika exempel på hur du kan exekvera ett PDO-statement. Intressantast för dig är nog:
Example#3 Execute a prepared statement with an array of insert values (placeholders)
http://se.php.net/manual/sv/function.PDOStatement-execute.php

QimenMedlem sedan juni 20015 009 inlägg
#7

Hur bra fungerar PDO idag? Har inte vågat använda det skarpt då det var rätt ostabilt för några år sedan samt det känns väldigt overkill i de flesta fallen. Går det använda mysqli med pdo? :)

colioneMedlem sedan juni 20014 421 inlägg
#8

PDO fungerar bra, annars hade jag inte rekomenderat det - flera gånger i rad.

Vad menar du med om det går att använda mysqli med pdo? Om det går att använda dem parallellt? Ja det går men jag förstår inte vitsen...annars har inte mysqli och PDO så mycket med varandra att göra, du använder inte mysqli extensionen i PDO. mysqli och PDOs likheter är väl att båda erbjuder prepared statements och ett objektorientearad grännssnitt. Dock är PDOs något bättre och du kan abstrahera så mycket att det hela funkar till vilken databas som helst.

QimenMedlem sedan juni 20015 009 inlägg
#9

colione skrev:

du använder inte mysqli extensionen i PDO.

Åhå där ser man, trodde PDO bara var ett par välskrivna klasser som utnyttjade befintliga extensions. Kanske borde ta en titt på det då. :)

itpastornMedlem sedan feb. 2007278 inlägg
#10

Principsvar

Qimen skrev:

Varje gång jag sätter mig ned och börjar på ett nytt projekt kommer jag alltid fram till samma sak. Jag behöver en funktion som jag kan köra all data igenom (som ska till eller från databasen).

Faktum är att du behöver en massa saker, beroende på ambitionsgrad.

(Alla svar i dett inlägg bygger på artiklar och böcker av Ilia Ashanetsky och Chris Schifflett, samt PHP Security Consortium.)

Vill du validera teckenkodningen (området 128-159 är otillåtet i ISO, flera områden är otillåtna för UTF-8)?

Vill du validera värden? Max- och minimimilängd på strängar? MySQL - om du använder det - klipper normalt bara bort överskjutande tecken. Är det ett önskvärt beteende? (Själv sätter jag alltid MySQL att vägra INSERT eller UPDATE om strängar är för långa eller heltal för höga)

Vilken HTML vill du tillåta användaren skicka - om någon? Det skiljer sig från variabel till variabel för mig.

Qimen skrev:

Samtidigt vill jag ha det lagrat på ett smart sätt, vill ju inte fylla dbn med en massa htmlkoder.

Bra tänkt. man bör ha sin data lagrad i så enkel form som möjligt. Nästa gång kanske den skall inkluderas i en PDF?

Qimen skrev:

Det jag tänkt på som kan vara bra att ta en titt på är:

- Om det är en array?

Kan behöva behandlas rekursivt.

Qimen skrev:

- Om det är post/get-data?

Också innehållet i $_COOKIE och många värden i $_SERVER och $_ENV skall behandlas som potentiella risker.

Qimen skrev:

- Om magic quotes är på eller ej?

Om på: Tag bort dem direkt, innan all annan bearbetning sker. Men lägg inte på någon annan "eskejpning" innan den behövs.

Qimen skrev:

- Om det är det blandade tecken eller endast nummer?

Varje värde bör prövas för sig.

Qimen skrev:

- Om datan är på väg in till dbn eller på väg ut från dbn?

Om databasen står till 100% under din kontroll kan du behandla utdata som säker - men den skall i rätt ögonblick naturligtvis ändå "eskejpas", t.ex. med htmlspecialchars. Försvar på djupet. Om du inte vet att databasen är orörd, hantera dess innehåll - med omdöme - som användarindata.

Qimen skrev:

- Om det finns farliga tecken som bör säkras med t.ex. addslashes?

Addslashes är den sämsta metoden. Den missar många tecken som erfarna hackers kan tänkas skicka. Prepared statements - eller i värsta fall mysql_real_escape_string.

Qimen skrev:

- Om det finns landsspecifika tecken som bör kodas om (åäö)?

Teckenkodningen fixar åäö, japanska och kyrilliska. Du använder väl inte US-ASCII?

Qimen skrev:

Som ni ser finns det en hel del man bör tänka på. Det jag har kört fast på är hur jag ska lagra specifika tecken som åäö, vill samtidigt inte låsa funktionen till endast svenska. Att köra htmlspecialchars på allt känns som lite overkill, lär öka upp storleken på dbn. Kanske räcker det med att köra htmlspecialchars? Eller är det bättre om jag kör addslashes (alt. mysql_real_escape_string) och skapar en egen liten tabell med tecken som kan vara bra att koda om?

Du skall välja funktion efter omständighet. Det är skillnad på att stoppa SQL-injektion och XSS.

Qimen skrev:

Det hela leder till en annan intressant fråga. Bör man ur säkerhetens syn koda om ovanliga tecken som t.ex. åäö eller är det lugnt att lagra dem som det är? :)

Koda aldrig om tecken som inte kan vara skadliga - och lagra inte din data kodad, utan i råformat. Escape output inte input.

Prepared statements - i värsta fall mysql_real_escape_string om du måste använda gammal kod - sker alltså precis innan man kör sin fråga. htmlspecialchars körs precis innan man ekar ut sin utdata till en webbläsare. escapeshellcmd och escapeshellarg körs precis innan exec eller passthru och liknande. Indata skall filtreras, inte "eskejpas". Utdata skall "eskejpas".

FuelMedlem sedan okt. 20001 285 inlägg
#11

Pastorn har bra grejjer här http://www.webforum.nu/showthread.php?t=157890 ;) som jag själv använder

QimenMedlem sedan juni 20015 009 inlägg
#12

Rejält svar där, det tackar man för. :)
Angående ambitionsgrad så skulle jag vilja påstå att ribban ligget rätt högt. Vill ha en bra lösning som jag sedan kan återanvända i flera projekt. Har ett eget större projekt där jag testar en del nya saker och det är bland annat där jag söker efter en bra lösning på databasbiten.

134 ms totalt · 3 externa anrop · v20260731065814-full.fb544a5a
0 ms — hämta forumlista (cache)
0 ms — hämta statistik (cache)
132 ms — hämta tråd, inlägg och bilagor (db)