Avatar billede doncarnage Nybegynder
25. februar 2009 - 01:33 Der er 10 kommentarer og
1 løsning

Er denne oprettelsesformular "i orden"?

Godaften eksperter..

Situationen er den at jeg er påbegyndt et større projekt, nærmere betegnet programmeringen af et større community.. Da jeg langt fra selv er ekspert, tænkte jeg derfor at jeg hen ad vejen kunne høre jer ad med om tingene jeg fik lavet var sikre og jeg havde taget højde for det man bør..

Jeg kunne derfor godt tænke mig at vide om oprettelsesformularen nedenunder er sikker? Er brugen af de mange stripslashes, htmlspecialchars og mysql_real_escape_string overflødig? Jeg har fået fortalt at md5 kryptering ikke længere er så sikkert, men jeg venter lige med at kaste mig over i noget andet her i første omgang.. Jeg kunne ligeledes godt tænke mig at få svar på hvad der er smartest mht. mysql forbindelserne og handlingerne. Er det bedst at ligge dem i en fil for sig (som jeg har gjort her) eller inkludere dem på de aktuelle sider, hvor de bliver brugt? Jeg prøvede i første omgang at inkludere dem i min pågældende opret-bruger-fil, men der fik jeg nogle header-problemer, så det hoppede jeg hurtigt fra igen.. Men hvad er smartest (jeg tænker mest på server-belastning her)?

<?
// Forbinder til databasen
include_once('../../inc.config.php');
mysql_connect($cfg['mysql']['host'],$cfg['mysql']['username'],$cfg['mysql']['password']);
mysql_select_db($cfg['mysql']['database']);

// Navn på tabellen
$tbl_name="members"; 

// Brugernavn og Password bliver sendt og modtaget fra min form
$newusername=$_POST['newusername'];
$newpassword=$_POST['newpassword'];
$newname=$_POST['newname'];
$newage=$_POST['newage'];
$newpostnr=$_POST['newpostnr'];
$newcity=$_POST['newcity'];
$newemail=$_POST['newemail'];
$newhomepage=$_POST['newhomepage'];

// Til at forhindre MySQL "injections" og kryptere password benyttes nedenstående
$newusername = stripslashes($newusername);
$newusername = htmlspecialchars($newusername);
$newusername = mysql_real_escape_string($newusername);

$newpassword = stripslashes($newpassword);
$newpassword = htmlspecialchars($newpassword);
$newpassword = mysql_real_escape_string($newpassword);
$newpassword = md5($newpassword);

$newname = stripslashes($newname);
$newname = htmlspecialchars($newname);
$newname = mysql_real_escape_string($newname);

$newage = stripslashes($newage);
$newage = htmlspecialchars($newage);
$newage = mysql_real_escape_string($newage);

$newpostnr = stripslashes($newpostnr);
$newpostnr = htmlspecialchars($newpostnr);
$newpostnr = mysql_real_escape_string($newpostnr);

$newcity = stripslashes($newcity);
$newcity = htmlspecialchars($newcity);
$newcity = mysql_real_escape_string($newcity);

$newemail = stripslashes($newemail);
$newemail = htmlspecialchars($newemail);
$newemail = mysql_real_escape_string($newemail);

$newhomepage = stripslashes($newhomepage);
$newhomepage = htmlspecialchars($newhomepage);
$newhomepage = mysql_real_escape_string($newhomepage);

// Til at tjekke op på om brugernavn og email allerede eksisterer i databasen
$q1user = mysql_query("select * from members where username = '$_POST[newusername]'");
$q1mail = mysql_query("select * from members where email = '$_POST[newemail]'");

if ($_POST['referer'] == 'newuser') {
    if (empty($_POST['newusername']) or empty($_POST['newpassword']) or empty($_POST['newpassword2']) or empty($_POST['newname']) or empty($_POST['newemail'])) {
        header("location:".$_SERVER['HTTP_REFERER']);
    }
    else if ($_POST['newpassword'] != $_POST['newpassword2']) {
        header("Location: passwords_ikke_ens.php");
    }
    else if (mysql_num_rows($q1user) > "0") {
        header("Location: brugeren_eksisterer_allerede.php");
    }
    else if (mysql_num_rows($q1mail) > "0") {
        header("Location: email_eksisterer_allerede.php");
    }
    else if (empty($_POST['newaccept'])){
        header("Location: checkbox_ikke_hakket_af.php");
    }
    else {
        mysql_query("INSERT INTO $tbl_name (username, password, name, age, postnr, city, email, homepage) VALUES ('$newusername', '$newpassword', '$newname', '$newage', '$newpostnr', '$newcity', '$newemail', '$newhomepage')") or die(mysql_error());
        header("Location: det_virkede.php");
    }
}

?>
Avatar billede erikjacobsen Ekspert
25. februar 2009 - 08:28 #1
Til at forhindre sql-injection skal du bruge http://php.net/mysqli med parameters (se eksemplerne med "?" i sql-strengen)
Avatar billede doncarnage Nybegynder
25. februar 2009 - 11:21 #2
Du har vel ikke et direkte link til det? Synes ikke lige jeg kan finde det du nævner inde på den liste der :)
Avatar billede erikjacobsen Ekspert
25. februar 2009 - 11:30 #3
Der er fx eksempel nummer 1 på http://dk.php.net/manual/en/mysqli.prepare.php
Avatar billede doncarnage Nybegynder
26. februar 2009 - 14:15 #4
Har fået kigget lidt på det nu, men forstår ikke helt hvordan jeg så skal omskrive min del ovenover :/ Det hænger nok sammen med at jeg ikke er den skarpeste til engelsk desværre..
Avatar billede erikjacobsen Ekspert
26. februar 2009 - 15:31 #5
Du kan fx i stedet for

$q1user = mysql_query("select * from members where username = '$_POST[newusername]'");

bruge (utestet):

$stmt=$mysqli->prepare("select * from members where username=?");
$stmt->bind_param("s", $_POST['newusername']);
$stmt->execute();
$stmt->store_result();
$antal_med_username=$stmt->num_rows);
$stmt->free_result();
$stmt->close();

Det er ikke noget du skifter om til på 5 minutter.

Men den kode, du viser i spørgsmålet er jo lidt til grin:

$newusername=$_POST['newusername'];
$newusername = stripslashes($newusername);
$newusername = htmlspecialchars($newusername);
$newusername = mysql_real_escape_string($newusername);

...en masse arbejde for at gøre strengen "sikker". Og alligevel bruger du den oprindelige værdi i SQL-strengen:

$q1user = mysql_query("select * from members where username = '$_POST[newusername]'");

Det er da lige til programmørernes årlige revy ... ;)
Avatar billede doncarnage Nybegynder
26. februar 2009 - 15:49 #6
Hmm okay.. Kan godt se at det er noget af en omvæltning så :S

Mht. den kode, der er til grin. Jeg gik egentlig bare ud fra at det var ligemeget når den blot skulle tjekke op på om bruger/mail eksisterede i tabellen :/

Men i stedet mener du så jeg skal bruge:
$q1user = mysql_query("select * from members where username = $newusername");

Ligesom jeg har gjort længere nede, hvor jeg indsætter det i tabellen right?
Avatar billede erikjacobsen Ekspert
26. februar 2009 - 18:36 #7
Eller rettere:

$q1user = mysql_query("select * from members where username = '$newusername'");

men ja, det ville være det du skulle gøre.
Avatar billede doncarnage Nybegynder
26. februar 2009 - 23:18 #8
Jeg har nu i stedet fået plottet en function ind, da det forkorter koden en del og gør det nemmere at overskue.. Ser koden nogenlunde ud nu med undtagelse af at du stadig anbefaler mysqli mod injections?

<?php
include_once('inc.config.php');
mysql_connect($cfg['mysql']['host'],$cfg['mysql']['username'],$cfg['mysql']['password']);
mysql_select_db($cfg['mysql']['database']);
   
$tbl_name="members_temp"; 
   
$confirmcode=md5(uniqid(rand())); /// til min bekræftelsesmail
   
function clean($str) {
    $str = @trim($str);
    if(get_magic_quotes_gpc()) {
        $str = stripslashes($str);
    }
    return mysql_real_escape_string($str);
    }
   
$newusername = clean($_POST['newusername']);
$newpassword = clean($_POST['newpassword']);
$newname = clean($_POST['newname']);
$newage = clean($_POST['newage']);
$newpostnr = clean($_POST['newpostnr']);
$newcity = clean($_POST['newcity']);
$newemail = clean($_POST['newemail']);
$newhomepage = clean($_POST['newhomepage']);
$newip = clean($_SERVER['REMOTE_ADDR']);
   
$salt = // her har jeg smidt et random salt ind;
$newpassword = md5($salt.$password);
   
$q1user = mysql_query("select * from members_regi where username = '$newusername'") or die(mysql_error());
$q1mail = mysql_query("select * from members_regi where email = '$newemail'") or die(mysql_error());
$q1usertemp = mysql_query("select * from members_temp where username = '$newusername'") or die(mysql_error());
$q1mailtemp = mysql_query("select * from members_temp where email = '$newemail'") or die(mysql_error());
   
if ($_POST['referer'] == 'newuser') {
    if (empty($_POST['newusername']) or empty($_POST['newpassword']) or empty($_POST['newpassword2']) or empty($_POST['newname']) or empty($_POST['newemail'])) {
            $error = "Alle de obligatoriske felter skal udfyldes!";
        }
        else if ($_POST['newpassword'] != $_POST['newpassword2']) {
            $error = "De indtastede passwords var ikke ens!";
        }
        else if (mysql_num_rows($q1user) > "0") {
            $error = "Det ønskede brugernavn eksisterer allerede";
        }
        else if (mysql_num_rows($q1mail) > "0") {
            $error = "Den indtastede e-mail eksisterer allerede!";
        }
        else if (mysql_num_rows($q1usertemp) > "0") {
            $error = "Det ønskede brugernavn eksisterer allerede";
        }
        else if (mysql_num_rows($q1mailtemp) > "0") {
            $error = "Den indtastede e-mail eksisterer allerede!";
        }
        else if (empty($_POST['newaccept'])){
            $error = "Husk at læse og godkende betingelserne for brugen af sitet!";
        }
        else if(strpos($_POST['newemail'], "@") === false){
            $error = "Det indtastede e-mail er ikke gyldig!";
        }
        else {
      // Heri er så formularen til at afsende min akteveringsmail
        }
    }
    ?>
Avatar billede erikjacobsen Ekspert
27. februar 2009 - 09:49 #9
Ja, din clean-funktion er pæn. Specielt at du nu tager højde for om der allerede automatisk er sat \-ere på strengen. Du bør kunne sove roligt, men med tiden benytte mysqli på den rigtige måde.
Avatar billede doncarnage Nybegynder
27. februar 2009 - 12:30 #10
Det var dejligt at høre.. Så kan jeg komme lidt videre med sitet uden at have dårlig samvittighed over det andet her :D

Hvordan var det nu - du ville ikke have points?
Avatar billede erikjacobsen Ekspert
27. februar 2009 - 13:19 #11
Nej tak.
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