Netissä liikkuu vaikka minkälaisia upload scriptoja. Useat niistä sallivat PHP-scriptojen uppimisen. Monet scriptit ovat ns. "kusessa", kun samanniminen tiedosto onkin olemassa.
Siistissä ZIP:issä saat tämän: http://omena.org/~dd/blog/?page_id=59
<?php // Olen kyllästynyt huonoihin uppiscriptoihin, jotka sallivat // php-scriptojen uppaamisen jne. /* * Copyright (c) 2006 Frozenball <orkkiolento@gmail.com> * All rights reserved. * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Names of its contributors may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ // 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>File Upload - Ilmoitus</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="Upload"> <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> '; } ?> <div id="footer">Powered by <a href="http://frozenblog.urli.net">FruitUpload</a>. | Valid <a href="http://validator.w3.org/check?uri=referer">HTML</a> and <a href="http://jigsaw.w3.org/css-validator/check/referer">CSS</a></div> </center> </body> </html>
Demo löytyy tästä: http://dd.simppeli.org/upload_demo/
Hienosti toimii. Tällaiselle olisi käyttöä, ilmoitan toki sinulle sitten ensin =)
Hieno koodi, mutta kyllä tästäkin on bugeja löydyttävä!
Hyvin kommentoitu! :)
Hyvin kommentoitu? Tarkoitat varmaan ettei kommentointia ole.
Aika sörsseliä mikäli minulta kysytään, mutta hoitaa homman.
Bugi: muutin tossa demossa yhden zipin txt päätteiseksi, uppasin sen ja kun painoin sen linkkiä niin tarjottiinkin taas zip tiedostoa..
Miten tohon sais lisättyä jotenkin, että noita tiedostoja voisi myös poistaa tuolta??
Teet PHP-skriptin joka osaa poistaa tiedosotoja "tuolta". Yksinkertaista.
Toimiva, mutta kyllä tuohon kannattaisi lisätä $_FILES['file']['error'] -muuttujan käsittely. Kun siirrossa menee jotain pieleen, niin syykin olisi mukava tietää.
Tarviiks tonne sulloo tunnuksii, salasanoi yms.?
Aika ahtaan näköistä koodia. Tästä saisi vaikka luokan, jota voisi käyttää suoraan luomalla siitä olion. Nyt käyttö on turhan rajoittunutta.
-"original" ei "orginal". Muutenkin kielien yhdistäminen ei ole selkeän dokumentoinnin kannalta suotavaa.
-Yhden rivin if-lauseet eivät tarvitse hakasulkuja. Kun nyt niitä tahdot kuitenkin käyttää niin jaottele ehto ja toiminto eri riveille, esim:
<?php if (ehto) { toiminto; // käytin neljää väliä sisentämiseen kun ei tabi toimi } ?>
En nyt muista suositteleeko myös PEARin syntaksiopas laittamaan tuon aloittavankin hakasulun omalle rivilleen, ainakin Javassa näin muistaakseni on, mutta itse en vain ole tavoille oppinut.
-Eikös kilon lyhenne ole pieni k?
-PHP_SELF ei ole turvallinen, käytä SCRIPT_NAMEa.
Esimerkki PHP_SELFin turvattomuudesta
-Ja paljon muuta pientä :).
... mulla kun koitta avata uploadun kuvan se ilmottaa et se on frobbien 403... miten saan sen että kaikki näkee ne kuvat?
Aluksi toi ei toiminu. Otin rivit 126-128 pois, ja nyt toimii.
Tuohan on mainiota. Himan höystettynä tuota voi käyttää vaikka missä.
Nam, mikä koodi..
Tässä koodissa pitäisi olla logi, johon kirjataan tiedoston lähettäjän ip näin:
tiedosto|ip
Lisäsin toiminnon itselleni.
nerootto kirjoitti:
Tässä koodissa pitäisi olla logi, johon kirjataan tiedoston lähettäjän ip näin:
tiedosto|ipLisäsin toiminnon itselleni.
No ei ole vaikea tehdä.
Aihe on jo aika vanha, joten et voi enää vastata siihen.