/ Forside / Teknologi / Udvikling / PHP / Nyhedsindlæg
Login
Glemt dit kodeord?
Brugernavn

Kodeord


Reklame
Top 10 brugere
PHP
#NavnPoint
rfh 3959
natmaden 3372
poul_from 3310
funbreak 2700
stone47 2230
Jin2k 1960
Angband 1743
Bjerner 1249
refi 1185
10  Interkril.. 1146
Sikkerhed ved SQL og PHP
Fra : Bertel Lund Hansen


Dato : 19-12-04 15:16

Hej alle

Jeg stillede et spørgsmål i databasegruppen, men jeg blev klar
over at jeg er nødt til (også) at have specifikke PHP-svar.

Jeg er ved at opbygge en database der skal styres via PHP og
HTML. Fra en side med en formular sendes inputtet til en anden
side (eller den samme) som sammensætter en sQL som den så fyrer
afsted til en MySQL-database.

Jeg er nu klar over at det setup er åbent for injektion. Hvordan
garderer jeg mig imod det?

--
Bertel
http://bertel.lundhansen.dk/   FIDUSO: http://fiduso.dk/

 
 
Michael Rasmussen (19-12-2004)
Kommentar
Fra : Michael Rasmussen


Dato : 19-12-04 16:04

On Sun, 19 Dec 2004 15:16:24 +0100, Bertel Lund Hansen wrote:

> Jeg er nu klar over at det setup er åbent for injektion. Hvordan
> garderer jeg mig imod det?
Denne side giver dig vist dine svar:
http://php.planetmirror.com/manual/en/security.database.sql-injection.php

--
Hilsen/Regards
Michael Rasmussen
http://keyserver.veridis.com:11371/pks/lookup?op=get&search=0xE3E80917


Christian Hansen (19-12-2004)
Kommentar
Fra : Christian Hansen


Dato : 19-12-04 17:08

Bertel Lund Hansen wrote:
> Jeg er nu klar over at det setup er åbent for injektion. Hvordan
> garderer jeg mig imod det?

Du skal så vidt muligt tjekke alt input, som du får retur. Ved du
eksempelvis, at der kun skal optræde tal i et felt, så tjek om det rent
faktisk er tilfældet ( if(preg_match("/^[0-9]+$/",$inputvar)) ).
Derudover kan du kigge lidt på funktionern
http://www.php.net/addslashes, som du kan anvende på alle modtagne
parametre. Derved sørges for at alle " og ' bliver slashed ( :) ) med et \.

Nogle steder gøres det automatisk og andre ikke.

Vi lavede følgende til Fundanemt CMS for at undgå problemer med addslashes:


//addslashes to get at post input if not done automaticly:
if(!get_magic_quotes_gpc()) {
foreach($_GET as $key=>$value) {
$_GET[$key] = addslashes($value);
}//foreach
foreach($_POST as $key=>$value) {
$_POST[$key] = addslashes($value);
}//foreach
foreach($_REQUEST as $key=>$value) {
$_REQUEST[$key] = addslashes($value);
}//foreach
}//if

Mvh Christian

Christian Hansen (19-12-2004)
Kommentar
Fra : Christian Hansen


Dato : 19-12-04 17:18

Christian Hansen wrote:
> Bertel Lund Hansen wrote:
>
>> Jeg er nu klar over at det setup er åbent for injektion. Hvordan
>> garderer jeg mig imod det?

Du skal ligeledes være opmærksom på at tjekke for html-indhold i felter.
Visse kreative brugere har det med at fylde html og/eller javascript ind
i formularfelter. Især i gæstebøger, hvor man ofte kan lave et lille
javascript, der så bevirker at alle, som efterfølgende går ind på
gæstebogen redeligeres til en anden side.

Mvh Christian

Peter Brodersen (20-12-2004)
Kommentar
Fra : Peter Brodersen


Dato : 20-12-04 00:12

On Sun, 19 Dec 2004 15:16:24 +0100, Bertel Lund Hansen
<nospamius@lundhansen.dk> wrote:

>Jeg er ved at opbygge en database der skal styres via PHP og
>HTML. Fra en side med en formular sendes inputtet til en anden
>side (eller den samme) som sammensætter en sQL som den så fyrer
>afsted til en MySQL-database.
>
>Jeg er nu klar over at det setup er åbent for injektion. Hvordan
>garderer jeg mig imod det?

Du har måske på nuværende tidspunkt fundet ud af, at en default PHP
automatisk afvikler addslashes() på al input udefra. Funktionen hedder
"magic_quotes_gpc", og kan rettes i php-konfigurationen, hvis du har
adgang til denne.

I det omfang, at du bruger variable direkte, og i øvrigt quoter
strenge, så er der ingen problemer. Der er heller ikke noget galt med
strenge i stil med .. WHERE id = '{$_REQUEST['id']}' .. - i MySQL,
også selvom id er et talfelt.

Dog, magic_quotes kan være lidt noget hø. For hvis du fx vil bruge
inputtet til at forudfylde et INPUT-felt i en form, fx <input
type="text" name="fornavn" value="Peter" /> , så har du ikke brug for
en addslashed udgave, men en htmlspecialchars'ed udgave - og bliver
derfor nødt til at afvikle
htmlspecialchars(stripslashes($_REQUEST['navn']))

Du kan læse meget mere om magic_quotes-problemstillingen i
<news:bfhnpv$a0j$1@dknews.tiscali.dk>
(hvor længe mon www.php-faq.dk skal være nede?)

Endnu en gang vil jeg dog gerne slå et salg for at man slår
magic_quotes fra, og så bruger PEAR DB:
http://pear.php.net/manual/en/package.database.db.php


FORDEL #1: Placeholders.
Man behøver ikke at bekymre dig om escape-metoder. Man skal ikke
klippeklistre queries.
$db->query("SELECT name FROM table WHERE id = ?",$_REQUEST['id']);
   eller
$sth = $db->prepare("SELECT name FROM table WHERE id = ?");
$res = $db->execute($sth,$_REQUEST['id']);
$res = $db->execute($sth,20);
$res = $db->execute($sth,600);


FORDEL #2: Ingen magic_quotes
Inputtet er rent, og skal ikke altid igennem stripslashes(), uanset
hvad man skal gøre ved det (fx hælde det igennem htmlspecialchars(),
sende inputtet i en mail, indsætte det i et billede i en GD-funktion,
etc.).

magic_quotes kan man dog selvfølgelig godt slippe for uden at bruge
PEAR DB :)


FORDEL #3: Gode kvikfunktioner til simple queries, fx:
$name = $db->getone("SELECT name FROM table WHERE id =
?",$_REQUEST['id']);
   eller
$row = $db->getrow("SELECT name, birthday, zip FROM table WHERE id =
?",$_REQUEST['id']);

Der er også getall() (multidimensionelt array), getcol() (evt. som
associativt array), m.m.

I mange tilfælde har man ikke behov for at jonglere med resultatsæt,
men er alligevel kun interesseret i en enkelt værdi. Koden kan blive
mere overskuelig på den måde, og generelt vil man alligevel have glæde
over flere funktioner til behandling af arrays, end specifikke
funktioner til behandling af et resultatsæt.


FORDEL #4: Udbredt API
Skifter man fx fra/til perl, er interfacet velkendt og stort set
identisk.


FORDEL #4b: Database-abstraktion
Skifter man fra MySQL til en anden (nær kompatibel) database, skal man
ikke ændre så meget.

Man skal måske rette MySQL-specifikke funktioner (fx LIMIT og
lignende), men man har ikke vendor-specifikke funktioner mange steder
i koden (fx tusindevis af linjer indeholdende mysql_query() og andre
mysql_*-funktioner).

Andre fremhæver dette som den største årsag til at bruge et
abstraktionslag, omend jeg synes at de andre fordele taler mere for
det.


FORDEL #4c: MySQL-opgraderingsfordele
Selv hvis man har besluttet sig for aldrig at bruge andet end PHP og
MySQL, så kunne man stadigvæk have gjort sig en stor tjeneste ved at
have brugt PEAR DB, når man endelig opgraderer til MySQL 4.1.

Vil man benytte MySQL 4.1s fordele som fx prepared statements, etc.,
kommer man til at skulle rette alle sine mysql-funktionskald fra
mysql_* til mysqli_* og omskrive kode. Hvis man i stedet har benyttet
PEAR DB, skal der kun rettes ét sted for at overgå til
mysqli-funktionerne. Hvis man har brugt prepare-statements i API'et
(hvor API'et blot har emuleret det for MySQL 4.0-servere), vil man
pludselig få den fulde udnyttelse ud af det, når man går over til 4.1
og bruger mysqli.

--
- Peter Brodersen

Søg
Reklame
Statistik
Spørgsmål : 177501
Tips : 31968
Nyheder : 719565
Indlæg : 6408527
Brugere : 218887

Månedens bedste
Årets bedste
Sidste års bedste