Löysin netistä PHP:llä kirjoitetun kirjautumisjärjestelmän jota muokkasin hieman omiin tarpeisiini. Voisiko joku tietäväisempi ystävällisesti katsoa sitä ja kertoa kuinka turvallinen se on, koska joudun tulevaisuudessa tekemään projekteja joissa tietoturva on tärkeää.
Kirjautuminen käyttää keksejä ja käyttäjätiedot on tallennettu mysql-tietokantaan jossa salasanat on tiivistetty MD5-algoritmilla.
*** muuttujat.php *** <?php $avain = "salainen"; // käytetään hash-keksin sekoitukseen, hash-keksiä käytetään käyttäjän tunnistamisessa $vanheneminen = 900; // keksin vanheneminen sekunneissa ?> *** kirjautuminen.php *** <?php include("muuttujat.php"); // uloskirjaus if($_GET["toiminto"] == "uloskirjaus") { setcookie("tunnus", "", (time() + $vanheneminen), "/", "", false); setcookie("hash", "", (time() + $vanheneminen), "/", "", false); header("Location: index.php"); // käyttäjän sisäänkirjaus } else { $yhteys = mysql_connect("palvelin", "tunnus", "salasana"); mysql_select_db("kayttajat", $yhteys); if(!$_POST["tunnus"] || !$_POST["salasana"]) header("Location: index.php?virhe=Tunnus tai salasana puuttuu!"); else { $tunnus = strtolower($_POST["tunnus"]); $salasana = $_POST["salasana"]; $kysely = mysql_query("SELECT * FROM kayttajat WHERE tunnus = \"".$tunnus."\" AND salasana = \"".md5($salasana)."\"", $yhteys); if(mysql_num_rows($kysely) > 0) { $hash = md5($tunnus.$avain); setcookie("tunnus", $tunnus, (time() + $vanheneminen), "/", "", false); setcookie("hash", $hash, (time() + $vanheneminen), "/", "", false); header("Location: etusivu.php"); } else header("Location: index.php?virhe=Tunnus tai salasana on virheellinen!"); } mysql_close($yhteys); } ?> *** etusivu.php *** <?php include("muuttujat.php"); if(!kirjautunut()) { header("Location: index.php"); exit("Et ole kirjautunut!"); // lopetetaan koodin suoritus varmuuden vuoksi // jos käyttäjä on kirjautunut, pidennetään keksien voimassaoloaikaa jottei kokoajan tarvitse kirjautua uudelleen } else { setcookie("tunnus", $_COOKIE["tunnus"], (time() + $vanheneminen), "/", "", false); setcookie("hash", $_COOKIE["hash"], (time() + $vanheneminen), "/", "", false); } <a href="kirjautuminen.php?toiminto=uloskirjaus">Kirjaudu ulos</a> function kirjautunut() { global $avain; if($_COOKIE["tunnus"] && $_COOKIE["hash"]) { if(md5($_COOKIE["tunnus"].$avain) == $_COOKIE["hash"]) return true; else return false; } else return false; } ?>
Toinen kysymys: Käytettäessä kyseistä järjestelmää (kirjautumattomana), esimerkiksi sivuilla oleviin kuviin pääsee käsiksi jos vierailija tietää niiden sijainnin. Miten kansiot saisi suojattua käyttäjiltä jotka eivät ole kirjautuneet sisään?
kayttaja-5600 kirjoitti:
Löysin netistä PHP:llä kirjoitetun kirjautumisjärjestelmän jota muokkasin hieman omiin tarpeisiini. Voisiko joku tietäväisempi ystävällisesti katsoa sitä ja kertoa kuinka turvallinen se on
Ei ole turvallinen, siinä on mm SQL Injektion paikka.
Minusta aavistuksen verran huolestuttavaa jos olet vastuussa turvallisien järjestelmien tekemisestä, mutta et osaa itse analysoida onko järjestelmä turvallinen vai ei.
hae googlesta tietoa mm. Sanalla input escaping, sql injection ja magic_quotes, ja pohdi miten tämä tieto liittyy mm. Post arrayn käyttöön... Lisäksi tietokannan salasana ja käyttäjätunnus kannattaa pitää tiedostossa, johon ei ole suoraa pääsyä www:n kautta, ja inkuloida se sieltä. Näin www palvelin ei tarjoile sitä maailmalle, mikäli php tulkki on jostain syystä nurin.
maz kirjoitti:
hae googlesta tietoa mm. ... magic_quotes
No joo, tuosta kannattaa ehkä hakea siinä mielessä tietoa, että miten voi varmistaa että ne on pois päältä. PHP kehittäjätkin ovat tajunneet ko. ominaisuuden idioottimaisuuden ja se ollaan poistamassa.
kayttaja-5600 kirjoitti:
Toinen kysymys: Käytettäessä kyseistä järjestelmää (kirjautumattomana), esimerkiksi sivuilla oleviin kuviin pääsee käsiksi jos vierailija tietää niiden sijainnin. Miten kansiot saisi suojattua käyttäjiltä jotka eivät ole kirjautuneet sisään?
Laita kuvat johonkin salaiseen kansioon jonka suojaat .htaccessilla käyttäjiltä ja näytä niitä ainoastaan kirjautuneille käyttäjille php-skriptin välitysellä tyyliin
*** kuva.php <?php $dir = "./ghdgio/"; if(kirjautunut()){ // Tässä on syytä tarkistaa, että nimeen ei ole laitettu sopimattomia merkkejä kuten /, jolloin voitaisiin hakea myös muista kansioista. Tästä syystä kansiossa tulisi olla vain kuvia, muuten voitaisiin hakea esimerkiksi kuvaa "tiedosto.php" tai jos /-merkkiä ei tarkistettaisi, vaikka kuvaa "../salainen_tietokanta/salasanat.txt" $otettava_kuva = $dir.$_GET["name"]; } else $otettava_kuva = $dir."tyhjä.png"; // Lukee kuvan ja tulostaa sen käyttäjälle lue_kuva($otettava_kuva); ?>
Samalla voisit tarkistaa refererin, jottei kuviasi suoralinkitetä.
Tjaa... kandeisi käyttää ihan sessioita. Evästeet voi pölliä ja sitten käyttää kirjautumiseen.
ja käikki $_GET ja $_POST muutujat kandee jotekin suodattaa, ettei niihin voi syöttää jotain ikävää.
$tunnus = strtolower($_POST["tunnus"]); $salasana = $_POST["salasana"];
Hetkonen siis eikös sessiotkin käytä oletuksena evästeitä? Siis sen session IDn tallentamiseen. Vai jokos nykyiset PHP versiot mahdollistaa ns. cookiettoman session ilman rankkaa handlerien kirjoittamista uusiksi?
lapm kirjoitti:
Hetkonen siis eikös sessiotkin käytä oletuksena evästeitä? Siis sen session IDn tallentamiseen.
Tietyssä määrin tuo on jo saivartelua. :) Kun keksiin tallennetaan dataa, joku voi saada käytettäväkseen ja muokattavakseen dataa. Kun keksiin tallennetaan datan tunniste, joku voi saada käytettäväkseen datan tunnisteen. Kun data sisältää tiedon mm. kirjautumisen vanhenemisesta, ensimmäisessä tapauksessa peli on menetetty. Toisessa tapauksessa taas istunto vanhenee aivan yhtä lailla kuin luvallisessakin käytössä. Datan tunniste ei myöskään mahdollista datan lukemista. Jos siis joku onkii tietoonsa itse datan, hän voi helposti käyttää tunnuksia väärin milloin vain. Jos taas tiedossa on vain istunnon tunniste, tietoja pitää onnistua käyttämään pian onkimisen jälkeen, jottei istunto vanhene, ja samasta syystä käyttöä täytyy luultavasti jatkaa koko ajan. On myös mahdollista, ettei jatkuva jatkaminenkaan auta, jos palvelimen puolella määrätään istunnon vanhenemisajaksi tietty aika kirjautumisen jälkeen.
Aihe on jo aika vanha, joten et voi enää vastata siihen.