Avatar billede cozey Nybegynder
13. august 2009 - 21:57 Der er 17 kommentarer

billedeupload funktion er ustabil og virker ikke altid!

Hej alle.
jeg har på min side en upload-funktion til billeder, hvor den uploader (valgte) billeder til en mappe og samtidig smider nogle inormationer om brugeren i min database. Jeg har dog oplevet at denne funktion er ustabil og ikke altid virker!... nogen der ved hvad dette kan skyldes?

Her er koden:
----------------------------------------------------------------

<?php

mysql_connect("********", "********", "********") or die(mysql_error());
mysql_select_db("web329930_5") or die(mysql_error());

  $name = stripslashes($_POST['name']);
  $email = stripslashes($_POST['email']);
  $adress = stripslashes($_POST['adress']);
  $postnum = stripslashes($_POST['postnum']);
  $city = stripslashes($_POST['city']);
  $tele = stripslashes($_POST['tele']);
  $type = stripslashes($_POST['type']);
  $beskrivelse = stripslashes($_POST['beskrivelse']);
  $maengde = stripslashes($_POST['maengde']);
 
if(isset($_POST['nyhedsbrev'])) {
  $nyhedsbrev .= "JA";
}else{
  $nyhedsbrev .= "NEJ";
}

if (isset($_POST['submit'])) //Har brugeren sendt formularen?
{
   
$uploadedPic = $_FILES['imagefile']['name'];
$split = explode(".", $uploadedPic);
$newName = $tele . "_01." . $split[1];

$uploadedPic2 = $_FILES['imagefile2']['name'];
$split2 = explode(".", $uploadedPic2);
$newName2 = $tele . "_02." . $split2[1]; 

if ($_FILES['imagefile']['type'] == "image/pjpeg" AND $_FILES['imagefile2']['type'] == "image/pjpeg"){
copy ($_FILES['imagefile']['tmp_name'], "admin.wio.dk/vinbil/".$newName) or die ("Fejl! Ikke kopieret");

copy ($_FILES['imagefile2']['tmp_name'], "admin.wio.dk/vinbil/".$newName2) or die ("Fejl! Ikke kopieret");

}
else {
echo "Filen er ikke kopieret, forkert Filtype (".$_FILES['imagefile']['name'].")";
}   
       
mysql_query("INSERT INTO customer (username, password, email, navn, adresse, postnr, city, telefon, type, beskrivelse, maengde, billede, billede2, nyhedsbrev, godkendt) VALUES ('$email', '$tele', '$email', '$name', '$adress', '$postnum', '$city', '$tele', '$type', '$beskrivelse', '$maengde', '$newName', '$newName2', '$nyhedsbrev', 'nej')") OR DIE(mysql_error());

  $content = "<font size=\"3\" face=\"Verdana\">Hej $name.<BR><BR>Du har tilmeldt dig med følgende oplysninger:<BR><BR><B>Brugernavn: </B>$email<BR><B>Kodeord: </B>$tele <BR><BR>Din tilmelding skal godkendes af en administrator, hvilket vil ske indenfor 24 timer og du vil straks modtage svar på e-mail. </font>";

  $headers = "From: joolix".PHP_EOL;
  $headers .= "Content-Type: text/html; charset=ISO-8859-1 ".PHP_EOL;
  $headers .= "MIME-Version: 1.0 ".PHP_EOL;

  mail("$email", "Tilmeldt $type til joolix", $content, $headers);

?>

-------------------------------------------------------------
Som det kan ses omdanner den filnavnet til deres telefonnummer, kan dette evt. være noget der giver problemer eller måske noget med filtyperne?

Jeg håber der er nogen der har en idé om hvad fejlen kan være, da jeg er helt på bar bund... eller evt. har et bedre script.

På forhånd tak.

/Daniel
Avatar billede repox Seniormester
13. august 2009 - 22:35 #1
Der er mange ting der kan nå at få galt i det script, men altså; du fortæller ikke hvad det præcist er der er 'ustabilt' men din slutkommentar tyder på det er noget med selve billederne der er ustabile?

Anyhow, måden du omdøber på er ikke særlig god.
Spørg dig selv hvad der sker med et billede der har filnavnet 'mit.billede.jpg'?

Det kunne også være interessant hvis du begyndte at gemme dine fejl istedet for at bare vise dem til brugeren - det er nemlig ubrugeligt for brugeren at se fejlmeldinger - og ubrugeligt for dig at du ikke kan se dem.

Istedet for at skrive:
mysql_query("...") OR DIE(mysql_error());

bør du overveje at gemme den fejl MySQL kommer med og nøjes med at fortælle brugeren at der er sket en upser:

<?php

    $sql = "INSERT INTO ...";
    $res = mysql_query($sql);
    if(!$res)
    {
        file_put_contents("minlog.txt", mysql_error(), FILEAPPEND);
        echo "Serveren lige en ups'er, men jeg kigger på det";
    }

?>

På den måde kan du også se hvor fejlene sker, hvilke fejl der sker og hvad du kan gøre for at komme ud over dem.

Sidst men ikke mindst: SQL Injection!!! Ja, det er ikke for sjov der er så mange udråbstegn - din kode er et gabende sikkerhedshul...
Avatar billede olebole Juniormester
13. august 2009 - 22:36 #2
<ole>

Mellemrum er ikke smart i filnavne - og hel galt går det ved med numre à la: +45 12 34 56 78

/mvh
</bole>
Avatar billede olebole Juniormester
13. august 2009 - 22:38 #3
- og jeg forholdt mig udelukkende til det, du skrev om filnavn og tlf-nummer. Koden er ét langt selvmord!  =8-O
Avatar billede cozey Nybegynder
13. august 2009 - 22:55 #4
repox>>
Tak. problemet er at den ssimpelthen ikke uploader billederne en gang imellem, men smider informationerne i databasen. Hvad skal jeg gøre for sikkerheden? Har du evt. et link?

Ole>>>
Ja, tænkte godt lige på det med telefonnummeret.
Ja, koden er ikke optimal, men jeg er ret grøn i php, så måske du kunne påpege nogle fejl?

På forhånd tak.
Avatar billede repox Seniormester
13. august 2009 - 23:02 #5
#4

if ($_FILES['imagefile']['type'] == "image/pjpeg" AND $_FILES['imagefile2']['type'] == "image/pjpeg"){

Jeg er ikke sikker på der er ret mange billeder længere der er af typen 'image/pjpeg'? Du skulle overveje at tage højde for 'image/jpeg' også.

Men som sagt - log dine fejl når der sker noget uventet - så kan du selv se hvad der sker.
Avatar billede cozey Nybegynder
13. august 2009 - 23:15 #6
repox>>>
Jeg har bare fundet scriptet på nettet og flettet det ind i resten. Jeg ved faktisk ikke præcis hvad den linje gør ... men den tjekker vel hvilken slag fil der er tale om? ... skal jeg bare fjerne P'et, således at:

if ($_FILES['imagefile']['type'] == "image/pjpeg" AND $_FILES['imagefile2']['type'] == "image/pjpeg"){


bliver til:

if ($_FILES['imagefile']['type'] == "image/jpeg" AND $_FILES['imagefile2']['type'] == "image/pjpeg"){

og ja, jeg vil bestemt sætte den til at gemme fejlene.
Avatar billede repox Seniormester
13. august 2009 - 23:19 #7
Jeg ville nok gøre noget ala:

$filetypes = array();
$filetypes[] = "image/pjpeg";
$filetypes[] = "image/jpeg";
$filetypes[] = "image/gif";
$filetypes[] = "image/png";

if (in_array($_FILES['imagefile']['type'], $filetypes) && in_array($_FILES['imagefile2']['type'], $filetypes)){
Avatar billede cozey Nybegynder
13. august 2009 - 23:32 #8
repox>>>
Takker, det retter jeg lige til. Er der andet du syntes jeg burde rette?
Avatar billede repox Seniormester
13. august 2009 - 23:46 #9
Ja, der er masser - hele scriptet er, som både og jeg og olebole har påpeget, et gabende sikkerhedshul.
Desværre er det ikke bare lige at 'påpege' fejl i dit script - mest fordi det hele er noget juks; enhver PHP udvikler ville med det samme forkaste koden og skrive noget andet.

Der er jo i forvejen påpeget nogle ret væsentlige ting som du bør tage stilling til.
Avatar billede cozey Nybegynder
14. august 2009 - 00:00 #10
okay, men selve koden til at smide info i database og mailafsendingen er vel fin nok eller hvad? Så det er vel bare selve uploadfunktionen der skal skiftes ud? Hvilken burde jeg bruge istedet?... der er vel ikke så mange muligheder, eller hvad?
Avatar billede repox Seniormester
14. august 2009 - 00:02 #11
Nej, den måde du sætter data i tabellen er faktisk den værste - der er stor risiko for at blive angrebet af SQL injection (google det).

Mailafsendelse er også en fryd for robotter - en rigtig spam engine. Altså, alt i alt er det virkelig dårlig kode....
Avatar billede olebole Juniormester
14. august 2009 - 01:13 #12
Man kan fake en MIME type. Derfor kan man godt uploade en eksekverbar fil med en uskyldig MIME. Man kan derimod ikke eksekvere en fil, der hedder *.jpg  ;o)

$allowed = array(
    "jpeg" => 1,
    "jpg" => 1,
    "gif" => 1,
    "png" => 1
    /* osv ... osv */
);

$aFname = explode(".", $_FILES['imagefile']['name']);
$ext = end($aFname);
$ext = strtolower($ext);
if ($allowed[$]) {
    // Filen er af tilladt type
}

Undgå SQL-injection - brug mysqli:
    http://dk2.php.net/manual/en/book.mysqli.php

Begynd f.eks. ved:
    http://dk2.php.net/manual/en/mysqli-stmt.prepare.php

Undlad at bruge copy til den uploadede fil. Brug i stedet:
    http://dk2.php.net/manual/en/function.move-uploaded-file.php
Avatar billede repox Seniormester
14. august 2009 - 08:27 #13
#12
Ja, god pointe - det er selvfølgelig bedre at kontrollere om filen kan eksekveres henover http. Jeg havde bare i tankerne at de uploadede filer lagde uden for webroden (for sådan gør jeg normalt).
Avatar billede cozey Nybegynder
14. august 2009 - 10:34 #14
olebole>>>
Tusind tak for hjælpen, jeg har ddog lige et par spørgsmål.
Nu har jeg forsøgt at få sammetsat noget kode fra det du skrev og er noget frem til følgende:

$uploadedPic = $_FILES['imagefile']['name'];
$split = explode(".", $uploadedPic);
$newName = $tele . "_01." . $split[1];

$uploadedPic2 = $_FILES['imagefile2']['name'];
$split2 = explode(".", $uploadedPic2);
$newName2 = $tele . "_02." . $split2[1];

$allowed = array(
    "jpeg" => 1,
    "jpg" => 1,
    "gif" => 1,
    "png" => 1
);

$aFname = explode(".", $_FILES['imagefile']['name']);
$ext = end($aFname);
$ext = strtolower($ext);
if ($allowed[$]) {

$uploads_dir = 'admin.wio.dk/vinbil/';
foreach ($_FILES["pictures"]["error"] as $key => $error) {
    if ($error == UPLOAD_ERR_OK) {
        $tmp_name = $_FILES["pictures"]["tmp_name"][$key];
        $name = $_FILES["pictures"]["name"][$key];
        move_uploaded_file($tmp_name, "$uploads_dir/$newName");
    }
}

}


Er det overhovedet rigtigt? Og denne gemmer vel kun newName 1 og ikke den anden... hvordan sætter jeg den til at tage newName2 med også?

Og hvad hvis billedefilerne ender på .JPG (med stort) istedet for .jpg... klarer den også det?

På forhånd tak.
Avatar billede cozey Nybegynder
16. august 2009 - 20:17 #15
Ingen der gider hjælpe mig?
Avatar billede repox Seniormester
17. august 2009 - 09:19 #16
Jo, folk gider godt hjælpe, men at gennemgå hver linie step by step kommer til at virke som om at vi egentlig skal lave det for dig, istedet for at hjælpe.

Du har fået rigeligt af pointere og hints at gå videre med og scriptet er også rimelig simpelt; for mig virker det som om at du ikke ved hvad du laver, men du skal bare have det til at virke. Det er betingelser vi ikke kan arbejde med eller ud fra.
Avatar billede olebole Juniormester
18. august 2009 - 00:53 #17
#13 >> Med de løsninger, man meget ofte ser folk lave her på Eksperten, er det såmænd ikke nogen garanti for noget som helst, at du uploader til et sted udenfor webspace. Under alle omstændigheder er det ikke klogt at tro, man kan slække på sikkerheden af nogen somhelst årsag. Når noget kan gå galt - så går det før eller siden galt!    ;o)

Med denne konstruktion (som skræmmende ofte ses på E) kan din bruger f.eks. eksekvere en hvilken somhelst fil inden- og udenfor webspace:

<?php
if (isset($_GET["page"]) && $_GET["page"]!="") {
    include($_GET["page"]);
}
?>

Spørgsmålet er, om du tør garantere, du ikke har én eller anden lille uhensigtsmæssighed i din kode, som kan udnyttes. Jeg kender ikke én eneste professionel programmør, der tør løbe anpå at være så dygtig og forudseende  ;o)
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