14. marts 2006 - 22:53Der er
7 kommentarer og 1 løsning
Globals til og fra
Som udgangspunkt er der i php ver. 5 slået globals fra.. Det er bare sådan at jeg har en del kode hvor det skal være slået til. Det kan jeg også, men er jeg så helt fucked med hensyn til sikkerhed, eller er det bare bagateller?.. og hvad er det et hacker kan gøre ved min hjemmeside hvis de er slået til?
Der bliver investeret massivt i AI. Teknologien er mere tilgængelig end nogensinde, og ambitionerne er høje. Alligevel oplever mange virksomheder, at resultaterne udebliver.
Afhængig af hvad dine scripts gør, kan han muligvis intet han ikke kunne med det slået fra - men forestil dig følgende kode:
<?PHP if ($status=='admin') { //admin-adgang } ?>
Med register_globals slået til, kunne man eksempelvis bruge dette til at checke værdien af en cookie, altså $_COOKIE['status']. Men hvad nu hvis $_COOKIE['status'] ikke er defineret? Så vil man kunne tilgå siden med ?status=admin - og vupti, så har man admin-adgang, da $_GET['status'] bliver kopieret ud i $status, og der ikke er noget til at overskrive den.
Hvis jeg var dig ville jeg omskrive koden, eller kigge mig om efter en ny udgave der IKKE bruger Register Globals (heller ikke via emulering af den indstilling). Hvis det er din egen kode burde det ikke tage alt for lang tid at komme i tanke om hvor det er meningen dine variable skal komme fra, og så initialisere dem i begyndelsen af scriptet - så slipper du for at skulle rette alle forekomster af den i koden.
I øvrigt, så har jeg for nylig hørt at muligheden for at bruge Register Globals helt er fjernet fra og med PHP 6, hvilket du måske bør være opmærksom på - der går nok en rum tid før den udkommer, men det er værd at tage i betragtning.
Nedenstående er noget fra min kode, og efter hvad jeg har forstået kan det ikke bruges med globals = off... ell. kan det hvis jeg initialiserer dem i begyndelsen af scriptet? slipper jeg så for at ændre alle $ i hele scriptet?
Hvis du initialiserer alle variable hvor værdierne kommer fra $_ENV, $_GET, $_POST, $_COOKIE og $_SERVER, er det ikke nødvendigt at foretaget andet for at det kan fungere uden Register Globals. For det meste er det dog kun værdier fra $_GET, $_POST og $_COOKIE man bruger.
Med andre ord, så skulle mit eksempel ændres til følgende:
<?PHP $status=$_COOKIE['status']; if ($status=='admin') { //admin-adgang } ?>
Bemærk dog at den kode stadig ikke er sikker mod angreb, da der kan være rodet med cookien - men det er i det mindste en angrebsvinkel mindre.
hvad hvis jeg ændrer alle variabler til fx $_GET['navn'] eller $_POST['navn'].. kan skal jeg så ikke initialisere dem i starten af dokumentet? og er jeg så på den sikre side.. Jeg har lige prøvet på de små eksempler jeg har skrevet i sidste spørgsmål.. er det rigtigt gjort? .. eller er jeg helt ude i hampen nu?
if ($_GET['s'] >= $_GET['pr_side']){ $_GET['previous_s'] = $_GET['s']-$_GET['pr_side'];
Det der har præcist samme effekt som hvis du initaliserer dine variable, så hvis du bruger det der i stedet, er det ikke nødvendigt at initialiserer variablene - men fordelen ved blot at bruge initialisering her er at du skal skrive lanfr mindre, da du kun skal tilføje et par linier øverst i scriptet - her skal du jo rette alle forekomster af variablene fra GPC.
Hvis du vil være 100% sikker mod angreb, så kræver det at du grundigt validerer indholdet af alt input som brugeren har noget kontrol over (dvs. GPC) - eks. skal du have en eller anden måde at kontrollere om en bruger er logget på, uden kun at stoel på et ID-nummer i en cookie, hvilket man eksempelvis kunne gøre ved også at gemme en hash af en tilfældigt generert streng i cookien - denne streng skulle så genereres når brugeren logger på, og gemmes i din database til kontrol. Det kræver dog en del større arbejde end det at få et script konverteret til ikke at være afhængig af Register Globals.
nedenfor kan du se hvad jeg har af sikkerhed når man skal logge ind og have rettigheder.. er det ok mht. globals og den slags, og giver dette sikkerhed nok?
/** * returns userId on success. 0 on failure. */ function is_valid($user,$password) { $query = "SELECT userId FROM users WHERE userName = '$user' and userPassword = password('$password') and userStatus > 0";
/** * The heart of the session manager. * * If you are load balancing your web site across several servers you cannot * store session information in files. You will either need to store the * information in a database or use cookies. Since many people are reluctant * to trust cookies your choices narrow down to exactly one. YOu need to use * database. * * Storing session information in a database makes sense if you are on a * shared hosting enviorenment and have concerns about security. * * To enabale this feature set the variable $session_in_db to 'db'; */ function on_session_write($key, $val) { error_log("$key = $value"); $val = addslashes($val); $insert_stmt = "insert into sessions values('$key', "; $insert_stmt .= "'$val',unix_timestamp(date_add(now(), interval 1 hour)))";
// First we try to insert, if that doesn't succeed, it means // session is already in the table and we try to update
mysql_query($insert_stmt);
$err = mysql_error();
if ($err != 0) { error_log( mysql_error()); mysql_query($update_stmt); } }
function on_session_destroy($key) { mysql_query("delete from sessions where session_id = '$key'"); }
function on_session_gc($max_lifetime) { mysql_query("delete from sessions where unix_timestamp(session_expiration) < unix_timestamp(now())"); }
error_log('=--------------- in session php' . $session_save . '-------------');
if($session_save == 'db') { error_log('setting save handler'); // Set the save handlers session_set_save_handler("on_session_start", "on_session_end", "on_session_read", "on_session_write", "on_session_destroy", "on_session_gc");
Om den er i orden med Globals er svært at sige uden hele koden - men hvis $session_save og $site_url initialiseres inden de bliver brugt her, ser det OK ud med den del - og grundet navnene, tror jeg ikke det er noget problem.
Der er dog et par kommentarer: Din is_valid funktion er *ikke* sikker, da der er en risiko for SQL injection. Det kunne eksempelvis misbruges til at slette indholdet af dine tabeller.
For at gøre is_valid sikker, skal du køre addslashes() eller mysql_real_escape_string() på $username og $password inden du bruger dem - det kan du dog vælge at gøre inden du sender dem til funktionen, så længe du sørger for at det gøres hver gang du kører funktionen.
Desuden er det ikke den bedste password-besykttelse du har - det frarådes at bruge PASSWORD() til at gemme kodeord, da dennes implementation kan ændres fra den ene MySQL-version til den anden (som den eksempelvis gjorde mellem 4.0 og 4.1) - brug hellere MD5 eller SHA1.
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.