Kirjautuminen

Haku

Tehtävät

Keskustelu: Nettisivujen teko: PHP File Upload tiedostonimen tarkistus

Sivun loppuun

Finley [11.03.2009 18:40:11]

#

Moikka kaikille!

Sain juuri ohjelmoitua ensimmäisen php-lomakkeeni joka lataa tiedostoja palvelimelle. Muuten toimii ihan mainiosti (täydellisesti), mutta siihen pitäisi vielä saada tsekkaus joka kattoo että tiedosto on nimetty oikein.

$pic=($_FILES['kuva']['name']);

Tuo saa kuvan nimen lomakkeelta, mutta millä tämä saataisiin tsekattua että kuvan nimessä saa olla vain numeroita ja pääte pelkästään jpg; eli hyväksytään vaan (0-9).jpg. Ilmeisesti tuo onnituisi eregillä mutta tietotaitoni loppui siihen kohtaan kun sitä olisi pitänyt muokata.

Löytyisikö täältä apuja?

Tumettaja [11.03.2009 18:48:21]

#

Näin?

<?php
	if (preg_match("/^[0-9].jpg$/",$pic)) {
		//nimi kelpaa
	}
?>

Finley [11.03.2009 19:10:57]

#

Kiitos tuosta.

Yritin testata koodia tällaisella, mutta ei onnistunut.

<?php

$pic = "123123.jpg";

if (preg_match("/^[0-9].jpg$/",$pic)) { echo "OK";
    }
else
	{ echo "<br><b>Tarkista tiedoston nime&auml;minen!</b><br><br><a href=\"javascript:history.go(-1)\">Takaisin</a>"; }

?>

Teuro [11.03.2009 19:16:06]

#

Eipä tietenkään, koska tuo tumettajan koodi hyväksyy vain numerot 0-9. Kokeile tätä

<?php

$pic = "123123.jpg";

if (preg_match("/^[0-9]+\\.jpg$/",$pic)) { echo "OK";
    }
else
    { echo "<br><b>Tarkista tiedoston nime&auml;minen!</b><br><br><a href=\"javascript:history.go(-1)\">Takaisin</a>"; }

?>

Cornix [11.03.2009 19:20:03]

#

Seuraavalla pitäisi onnistua:

<?php
if (preg_match("/^[0-9]+\.jpg$/",$pic)) { echo "OK"; }
?>

Finley [11.03.2009 19:25:31]

#

Kiitos kaikille nyt toimii!

Noissa viimeisissä vastauksissa oli hieman eroavaisuutta koodissa... onko sillä vaikutusta vai voinko käyttää kumpaa tahansa?

Cornix [11.03.2009 19:29:19]

#

Hmm. Teuro näköjään muokkasikin omaansakin tähden tilalle plussan. Tuosta kaksois-kenoviivasta en menisi takuuseen. Kokeile vaaditaanko se.

* tarkoittaa "nolla kappaletta tai useampi edellistä" ja + on "yksi tai useampi kappale edellistä" eli tässä tapauksessa tahdotaan tiedoston nimessä olevan vähintään yksi numero.

Teuro [11.03.2009 19:32:07]

#

Cornix kirjoitti:

Hmm. Teuro näköjään muokkasikin omaansakin tähden tilalle plussan. Tuosta kaksois-kenoviivasta en menisi takuuseen. Kokeile vaaditaanko se.

* tarkoittaa "nolla kappaletta tai useampi edellistä" ja + on "yksi tai useampi kappale edellistä" eli tässä tapauksessa tahdotaan tiedoston nimessä olevan vähintään yksi numero.

Muistin tosiaan väärin tuon toistomerkin se on tosiaan + merkki, joka vaaditaan. Tuplakenoviivat pitää olla, kun ollaan lainausmerkkien sisällä. * merkillä hyväksyttäisiin kaiketi virheellisesti myös merkkijono, jossa ei ole numeroita.

Cornix [11.03.2009 19:33:20]

#

Teuro kirjoitti:

Tuplakenoviivat pitää olla, kun ollaan lainausmerkkien sisällä.

Ah, joo aivan. Eli yksi riittäisi, jos lainausmerkkien tilalla olisikin heittomerkit?

Rocceri [12.03.2009 14:19:43]

#

Tai, tässä on suoraan valmis koodi joka tarkistaa sun muuta.

<?php
// php-scriptojen uppaamisen jne.


// Asetukset
$conf['filetypes'] = array("bmp","jpg","jpeg","png","swf","svg","txt");
$conf['max_filesize'] = 1024; // Max. tiedoston koko Kt. Eli 1024 = 1MB, 2048 = 2MB.
$conf['kansio'] = "uploads/"; // Kansio minne kaikki laitetaan.
$conf['fix_pahat_kirjaimet'] = true; // Muuttaa ääkköset aakkosiksi, poistaa ()[] jne.
$conf['polku'] = ""; // Laitetaan alkuun joku osoite. Älä muuta jos et tiedä mitä olet tekemässä
$conf['banned_ips'] = array("123.123.123.123","123.123.123.123"); // IP:t, jotka eivät voi lisätä tiedostoja.
$conf['imagecheck'] = true; // Tarkistaa onko kyseessä oikeasti kuva, jos tiedostopääte on GIF, JPG, PNG, SWF, SWC, PSD, TIFF, BMP, IFF, JP2, JPX, JB2, JPC, XBM tai WBMP.
$conf['nayta_tiedostot'] = true; // Näyttää listauksen upatuista tiedostoista
$conf['session'] = "upload"; // SESSION:in nimi. Ei tarvitse muuttaa, jos et tajua sitä.
$conf['charset'] = "ISO-8859-15"; // Merkistö. Yleensä ISO-8859-15

// Itse scripta. Älä koske enää ;)

// Onko CSS?
if (isset($_GET['css'])) {
    header('Content-type:  text/css; charset='.$conf['charset']);
    print '    body {
        font-size:12px;
        font-family:Verdana,Arial,sans-serif;
    }
    .fileupload, #fileupload_error {
        border:1px #8099B3 solid;
        margin:4px;
        padding:4px;
        width:60%; min-width: 350px;
        background-color:#F0F7FF;
        text-align:left;
        min-height:100px;

    }
    #fileupload_error { background-color:#F7DDDD; border:1px #841C1C solid; }

    .fileupload label {
        float:left;
        width:100px;
        text-align:right;
        padding-right:10px;
    }
    .fileupload input {
        float:left;
        width:200px;
        text-align:left;
        font-size:12px;
        font-family:Verdana,Arial,sans-serif;


    }
    #submit {
        margin-top:3px; border:1px #3D5A7C solid; background-color:#CBD5E0;
        margin-left:110px; width:auto!important;
    }
    #submit:hover { background-color:#B1C1D3; }
    h1 { margin:0px; padding:0px; color:#893939; border-bottom:1px #E13232 dotted; }
    #ilo { color:#426854;  border-bottom:1px #2FB970 dotted; }
    .tieto { font-size:10px; color:#616161; margin-left:110px; }
    br { clear:left; }
    .tiedosto { width:50%; float:left; }
    ';
    exit;
}

session_start();
// Merkistö
header('Content-type: text/html; charset='.$conf['charset']);

// Tarvittavat functiot
function humanread($bytes) {
    $pp = array("B","KB","MB","GB","TB");
    $menossa = 0;
    while ($bytes >= 1024) {
        $menossa++;
        $bytes = $bytes / 1024;
    }
    return round($bytes,2).$pp[$menossa];
}

function msgdie($msg,$error=false) {
    print('<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
  <head>
    <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset='.$conf['charset'].'">
    <LINK rel="stylesheet" type="text/css" href="'.$_SERVER['PHP_SELF'].'?css">
    <title>Virhe</title>
    <style type="text/css">

    </style>
  </head>
  <body>
    <center>');


if ($error == true) print '<div id="fileupload_error"><h1>Virhe</h1>';
else  print '<div class="fileupload"><h1 id="ilo">Ilmoitus</h1>';

print ('
            '.$msg.'
        </div>
    </center>
  </body>
</html>');
exit();

}

// Käydään bannatut IP:t läpi
foreach ($conf['banned_ips'] as $ip) {
    if ($_SERVER['REMOTE_ADDR'] == $ip) msgdie("Olet bannattu eli sinulla on porttikielto.",true);
}
// Jos uppaus?
if (is_numeric($_POST['upload'])) {

    // Aikatarkistukset
    if (strlen($_POST['upload']) > (strlen(time()) * 100)) msgdie("Jotain ihmeellistä on tapahtunut...",true);
    if ($_POST['upload'] > time()) msgdie("Olet etuajassa.",true);
    if ($_SESSION[$conf['session']] == $_POST['upload']) msgdie("Olet nähtävästi yrittänyt painaa Refresh nappulaa. Paina mielummin <a href='".$_SERVER['PHP_SELF']."'>tästä</a>.",true);

    // Tiedostolle tarkistukset
    if ($_FILES['file']['size'] > ($conf['max_filesize'] * 1024)) msgdie("Tiedosto on liian suuri. Kokorajoitus on ".humanread($conf['max_filesize'] * 1024),true);
    if ($_FILES['file']['size'] == 0) msgdie("Yritätkö edes lähettää tiedostoa...?",true);

    // Tiedostonpääte
    list($tiedoston_paate) = array_reverse(explode(".",$_FILES['file']['name']));
    $tiedoston_paate = strtolower($tiedoston_paate);
    if ($tiedoston_paate == "") msgdie("Tällä tiedostolla ei ole tiedostonpäätettä tai jotakin ihmeellistä tapahtui.<br><br>Palaa <a href='".$_SERVER['PHP_SELF']."'>tästä</a> takaisin.",true);
    $sallitaanko = false;
    foreach ($conf['filetypes'] as $sallittu) {
        if ($tiedoston_paate == strtolower($sallittu)) $sallitaanko = true;
    }
    if ($sallitaanko == false) msgdie("Tiedostonpääte ".$tiedoston_paate." ei ole sallittu.<br><br>Palaa <a href='".$_SERVER['PHP_SELF']."'>tästä</a> takaisin.",true);

    // Tarkistus
    if ($conf['imagecheck'] == true) {
        #GIF, JPG, PNG, SWF, SWC, PSD, TIFF, BMP, IFF, JP2, JPX, JB2, JPC, XBM tai WBMP
        $tuetut = array("gif","jpg","jpeg","png","swf","swc","psd","tiff","bmp","iff","jp2","jpx","jb2","jpc","xbm","xbmp");
        if (in_array($tiedoston_paate,$tuetut)) {
            if (!@getimagesize($_FILES['file']['tmp_name'])) msgdie("Tiedostonpääte ".$tiedoston_paate." ei ole oikea. Olet saattanut nimetä esimerkiksi zip tiedoston tiedostopäätteen.<br><br>Palaa <a href='".$_SERVER['PHP_SELF']."'>tästä</a> takaisin.",true);
        }
    }


    // Nyt on siirron aika
    if (!is_dir($conf['kansio'])) { @mkdir($conf['kansio']) or msgdie("Kansiota ".$conf['kansio']." ei ole olemassa.",true); }
    $tiedoston_nimi_orginal = basename($_FILES['file']['name']);



    // ÄÄKKÖSKORJAUS
    if ($conf['fix_pahat_kirjaimet'] == true) {
        $tiedoston_nimi_orginal = str_replace(array("ä","ö","å","Ä","Ö","Å"," "),array("a","o","a","A","O","A","_"),$tiedoston_nimi_orginal);
        $tiedoston_nimi_orginal = preg_replace("[^a-zA-Z0-9]","",$tiedoston_nimi_orginal);
    }
    // Harvinaista - mutta mahdollista
    if ($tiedoston_nimi_orginal == "") { $tiedoston_nimi_orginal = base64_encode(basename($_FILES['file']['name']));  }

    $tiedoston_nimi = $tiedoston_nimi_orginal;

    $i = 1;
    while (is_file($conf['kansio'].$tiedoston_nimi)) {
        // Tiedosto on jo olemassa, eli keksitään uusi nimi
        $halkaistu = explode(".",$tiedoston_nimi_orginal);
        $halkaistu[0] = $halkaistu[0]."_".$i;
        $tiedoston_nimi = implode(".",$halkaistu);
        $i++;
    }

    if (@move_uploaded_file($_FILES['file']['tmp_name'], $conf['kansio'].$tiedoston_nimi)) {
        $polku = $conf['polku'].$conf['kansio'].$tiedoston_nimi;
        if ($conf['polku'] != "") $polku = $conf['polku'].$tiedoston_nimi;

        $_SESSION[$conf['session']] = $_POST['upload'];

        msgdie("Tiedosto ".$tiedoston_nimi." on siirretty onnistuneesti. Pääset käsiksi tiedostoosi tästä:<br><br>
        <a href='".$polku."'>".$tiedoston_nimi."</a><br><br>Palaa <a href='".$_SERVER['PHP_SELF']."'>tästä</a> takaisin.");
    } else {
        msgdie("Tiedoston siirto ei onnistunut. Tämä johtuu mm. seuraavista syistä:<br>* Tällä scriptillä ei ole oikeuksia upload kansioon.<br><br>Palaa <a href='".$_SERVER['PHP_SELF']."'>tästä</a> takaisin.",true);
    }


}

?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
  <head>
    <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=<?php print $conf['charset']; ?>">
    <LINK rel="stylesheet" type="text/css" href="<?php print $_SERVER['PHP_SELF']; ?>?css">
    <title>File Upload</title>
    <style type="text/css">

    </style>
  </head>
  <body>
    <center>

        <div class="fileupload">
            <form action="<?php print $_SERVER['PHP_SELF']; ?>" method="POST" enctype="multipart/form-data">
            <input type="hidden" name="upload" value="<?php print time(); ?>">
            <label for="file">Tiedosto:</label>
            <input type="file" name="file" id="file">
            <br>
            <div class="tieto">Sallitut tiedostopäätteet <?php print implode(", ",$conf['filetypes']); ?> ja suurin sallittu tiedostonkoko on <?php print humanread($conf['max_filesize'] * 1024); ?></div>
            <input type="submit" name="submit" id="submit" value="Lataa palvelimelle">
            <br>
            </form>
        </div>
        <?php
        if ($conf['nayta_tiedostot'] == true) {
            print '
            <div class="fileupload" style="min-height:30px;">
            <b>Tiedostot:</b><br>
            ';
            $kayty_lapi = false;
            foreach (glob($conf['kansio']."*") as $filename) {
                $kayty_lapi = true;
                print "<div class='tiedosto'><a href='".$filename."'>".basename($filename)."</a></div>\n";
            }

            if ($kayty_lapi == false) print "Ei tiedostoja";

            print '
            <br>
            </div>
            ';
        }
        ?>


    </center>
  </body>
</html>

walkout_ [15.03.2009 10:21:10]

#

Etäs jos sinne nakkaa tällaisen

100923.jpg.php?

Eiks toi preg_macth hoida sen niin että noin ei voi huijata?

Mut mun mielestä tiedoston nimi pitäisi laittaa niin että se pakotetaan lowercaseksi ja åå, ää ja öö -kirjaimet ja muut turhat replasetetaan sopiviksi.. menaan kun perus käyttäjät ei tajua että tiedosto nimet ei saisi Linux-palvelimelle upittuna olla mallia "Ääääöööååå ååÄÄ.JPG"

Onko muuten mahdollista uppia palvelimele text/plain tiedosto joka on nimeltään tiedosto.jpg ja sitten laittaa jotekin sen headeriksi text/html ja sit käyttää sitä Exploitina jota pommittaa jokin perl-pohjainen Spideri joka on asennettu toiselle kaapatulle sivulle ja tutkii erinäisiä sivuja tällä tavalla voiko ne hakkeroida.

trilog [15.03.2009 10:44:21]

#

walkout_ kirjoitti:

tiedosto nimet ei saisi Linux-palvelimelle upittuna olla mallia "Ääääöööååå ååÄÄ.JPG"

Miksi ei saisi?

walkout_ [17.03.2009 16:04:38]

#

trilog kirjoitti:

walkout_ kirjoitti:

tiedosto nimet ei saisi Linux-palvelimelle upittuna olla mallia "Ääääöööååå ååÄÄ.JPG"

Miksi ei saisi?

Siksi ei, että ne ei toimi.. riippuu sitä mikä on palvelime locale

trilog [17.03.2009 17:09:24]

#

walkout_ kirjoitti:

Siksi ei, että ne ei toimi.. riippuu sitä mikä on palvelime locale

Hieman on ristiriidassa sanomasi, ensin väität ettei ne toimi (missään tilanteessa), mutta sitten väität sen riippuvan localesta.

Localella ei tosin ole yhtään mitään merkitystä tiedostonimien kanssa, ääkkösten toimivuus tiedostonimissä (kuten muidenkin merkkien) riippuu palvelimen tiedostojärjestelmästä. Linuxissa yleisemmin käytetyt tiedostojärjestelmät ovat ext2 ja ext3, jotka molemmat tukevat mitä tahansa merkkejä, paitsi tyhjää tiedostonimissä. Eli Linux-palvelimelle, jossa on joku edellä mainituista tiedostojärjestelmistä käytössä voi uppia vaikka tällaisen tiedoston:

/äääääää/ööööö ö/åå ååå å.jpg

Blaze [17.03.2009 18:04:36]

#

Tai vaikka
-rw-r--r-- 1 blaze users 3382474 2008-08-12 22:29 /data/musaa/おっくせんまん!.mp3


Sivun alkuun

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta