Avatar billede JJ77 Juniormester
14. marts 2006 - 22:53 Der 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?
Avatar billede pidgeot Nybegynder
14. marts 2006 - 23:22 #1
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.
Avatar billede JJ77 Juniormester
14. marts 2006 - 23:42 #2
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?

if ($s >= $pr_side) {
    $previous_s = $s-$pr_side;

WHERE artikelid=" . $row["Id"];
Avatar billede pidgeot Nybegynder
14. marts 2006 - 23:59 #3
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.
Avatar billede JJ77 Juniormester
15. marts 2006 - 10:01 #4
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'];

WHERE artikelid=" .$row["Id"];
Avatar billede pidgeot Nybegynder
15. marts 2006 - 16:12 #5
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.
Avatar billede JJ77 Juniormester
15. marts 2006 - 17:07 #6
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";
             
    $result = mysql_query($query);
    error_log(mysql_error());

    if($result && mysql_num_rows($result) ==1)
    {
       
        $row = mysql_fetch_row($result);

        return $row[0];
    }
    return 0;
}



/**
* check the referer to minimize abuse..
* todo: a more vigourous check.
*/

function is_valid_referer()
{
    global $site_url;
    return (strstr($_SERVER['HTTP_REFERER'],$site_url));
}           



function on_session_start($save_path, $session_name) {
    error_log($session_name . " ". session_id());

}


function on_session_end() {
    // Nothing needs to be done in this function
    // since we used persistent connection.
}

function on_session_read($key) {
    error_log($key);
    $stmt = "select session_data from sessions ";
    $stmt .= "where session_id ='$key' ";
    $stmt .= "and unix_timestamp(session_expiration) > unix_timestamp(date_add(now(),interval 1 hour))";
    $sth = mysql_query($stmt);

    if($sth)
    {
        $row = mysql_fetch_array($sth);
        return($row['session_data']);
    }
    else
    {
        return $sth;
    }
}

/**
* 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)))";

    $update_stmt  = "update sessions set session_data ='$val', ";
    $update_stmt .= "session_expiration = unix_timestamp(date_add(now(), interval 1 hour))";
    $update_stmt .= "where session_id ='$key '";
   
    // 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");


}
session_start();
?>
Avatar billede pidgeot Nybegynder
15. marts 2006 - 19:37 #7
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.
Avatar billede JJ77 Juniormester
15. marts 2006 - 20:30 #8
takker mange gange for hjælpen.. det sku super :)
Avatar billede Ny bruger Nybegynder

Din løsning...

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.

Loading billede Opret Preview
Kategori
Vi tilbyder markedets bedste kurser inden for webudvikling

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester