Olen yrittänyt koodata tämmöistä koodia, joka siirtyy tietylle sivulle kun näpyttelee oikean tunnuksen ja salasanan. Mutta kun olen antanut oikean tunnuksen ja salasanan, niin ilmestyy tämmönen php-virhe:
Parse error: syntax error, unexpected T_ELSE in /home/jiminet/www/salainensivu.php on line 4
Listaukset:
salasanansyotto.html:
<html> <head><title>Testisivu</title> </head> <body> <form method="post" action="tarkista.php"> Tunnus: <input type="text" name="nimi"><br> Salasana: <input type="text" name="sala"><input type="submit"> </form> </body> </html>
tarkista.php:
<?php session_start(); $_SESSION["tunnus"] = "id="; //Asettaa istunnon $tunnus="pake10"; //Tunnuksien määritys $salasana="testi"; $nimi=$_POST["nimi"]; $sala=$_POST["sala"]; $sivu="salainensivu.php"; if($nimi==$tunnus && $sala==$salasana) include($sivu); //Salainensivu.php näytetään, jos tunnukset on oikein. else echo "<font color=\"#ff0000\"><b>Salasana ja tunnus väärä.</b></font>" ?>
salainensivu.php:
<?php $_SESSION["tunnus"] = "id="; //Lataa istunnon echo "Salainen sivu."; else { //Jos käyttäjällä ei ole tätä istuntoa, niin hän ei näe sivua. echo "<font color=\"#ff0000\"><b>Kirjaudu sisään nähdäksesi tämän sivun.</b></font>; } ?>
ulos.php:
Mutta tuossa salainensivu.php:ssa tuo else-komento ei toimi. Eli miten tuo saataisiin toimimaan?
(olen täysi n00bi näissä.)
Tarkista oppasta, miten tuota if-lausetta käytetään.
pake10 kirjoitti:
$_SESSION["tunnus"] = "id="; //Lataa istunnon
Eipäs, vaan asettaa sessionin tunnus arvoksi id=.
pake10 kirjoitti:
Tämä taitaa ainoastaan tyhjentää sessionin. Tarkemmin näin:
<?php unset($_SESSION["tunnus"]); //Sulkee istunnon. session_destroy(); echo "Olet kirjautunut ulos." ?>
make10 kirjoitti:
Korjasin vähäsen:
<?php if(isset($_SESSION["tunnus"])) { echo "Salainen sivu"; } else { //Jos käyttäjällä ei ole tätä istuntoa, niin hän ei näe sivua. echo "<font color=\"#ff0000\"><b>Kirjaudu sisään nähdäksesi tämän sivun.</b></font>"; } ?>
Asetat myös sessionin, vaikka tunnus olisi väärin. Tässä parannus:
<?php //Aloitetaan sessioni session_start(); //Tunnus: $tunnus = "make10"; //Salasana: $salasana = "123123"; //Otetaan muuttujat talteen: $kayttajatunnus = $_POST["tunnus"]; $salasana_ = $_POST["salasana"]; //Tarkistetaan käyttäjätunnus ja salasana: if($kayttajatunnus = $tunnus && $salasana_ = $salasana) { $_SESSION["tunnus"] = "id="; include("salainensivu.php"); } else die("Tunnus tai salasana oli väärin!"); ?>
Kiitti! Nyt onnistui.
Eipä tuo uloskirjautuminen toimi... Tulee vain:
Warning: session_destroy() [function.session-destroy]: Trying to destroy uninitialized session in /home/jiminet/www/ulos.php on line 3
Olet kirjautunut ulos.
Mitenkäs tuo korjataan?
Poistamalla tuo unset() funktio, koska se poistaa todellakin tuon muuttujan (olkoon vain superglobaali) muistista. Eli session_destroy() yksinään. Tuon jälkeen voi kaiketi kutsua tuota unset() funktiota, mutta sille ei ole tarvetta.
MIB, tuossa koodissa on bugi. Näyttää menevän salaiselle sivulle väärälläkin salasanalla.
Tässä vähän parannuksia:
<?php session_start(); //ylaosa.php //Määrittele tunnukset $kayttajatunnus = "testi"; $salasana = "salainen"; //Jos lähetetyt tiedot eivät ole tyhjiä if(!empty($_POST["tunnus"]) && !empty($_POST["salasana"])) { //Jos ne ovat oikein if($_POST["tunnus"] == $kayttajatunnus && $_POST["salasana"] == $salasana) { //Laitetaan sessioniin tunnus $_SESSION["tunnus"] = $_POST["tunnus"]; //Ohjataan salaiselle sivulle header("Location: salainensivu.php"); } else die("Väärä tunnus tai salasana!"); } if(isset($_GET["logout"])) { session_destroy(); header("Location: kirjautumislomake.html"); } ?>
<?php //salainensivu.php include("ylaosa.php"); if(isset($_SESSION["tunnus"])) { echo "Tervetuloa " . $_SESSION["tunnus"] . "! <a href=\"?logout\">Kirjaudu ulos</a>"; echo "<p>Lorem ipsum...</p>"; } else header("Location: kirjautumislomake.html"); ?>
// kirjautumislomake.html <form action="ylaosa.php" method="POST"> Tunnus:<br> <input type="text" name="tunnus"><br><br> Salasana:<br> <input type="password" name="salasana"><br><br> <input type="submit" value="Kirjaudu"> </form>
Tuossa on toimiva esimerkki:
https://www.ohjelmointiputka.net/keskustelu/
Antin linkittämä salasanasuojausesimerkki on kyllä toimiva, mutta se on mahdollista ohittaa varsin helposti, jos register_globals-asetus on päällä.
Koska $tiedot-taulukkoa ei alusteta, voi hyökkääjä lisätä sinne oman käyttäjätunnuksensa esim. kutsumalla skriptiä tyyliin:
sisaan.php?tiedot[krakkeri]=123
Ongelman voi korjata esimerkiksi lisäämällä seuraavan rivin ennen käyttäjätunnusten ja salasanojen tallentamista taulukkoon:
<?php $tiedot = array(); ?>
Tapasi lisäisi alkion muuttujaan $_GET[tiedot] eikä taulukkoon $tiedot?
Molempiin, jos register_globals on päällä.
Contraband kirjoitti:
Molempiin, jos register_globals on päällä.
Mutta eihän kenelläkään vakavasti otettavalla web-koodarilla ole register_globals päällä. Se on vanhentunut jo aikaa sitten, ja tuleva PHP 6 ei sisällä sitä enää ollenkaan.
Toki taulukon alustaminen on silti hyvä tapa, ettei tarvitse arvailla, onko siihen sijoitettu jotain jo aiemmin.
Hakoulinen: arvo menee muuttujaan $_GET['tiedot']['krakkeri'].
Totta tuokin. Yhteensopivuussyistä (vanhat skriptit) siirtymä on tosin yllättävän hidas varsinkin web-hotelleissa - esimerkiksi MBNet muutti asetuksen vasta viime toukokuussa. Toki MBNet-hostauksen vakavastiotettavuudestakin voidaan keskustella :) Toisaalta tuskin täysin vakavasti otettavissa ympäristöissä edes käytettäisiin mainitunkaltaista PHP-arrayihin perustuvaa sisäänkirjautumisjärjestelmää. Yhtä kaikki, taulukoiden alustaminen on hyvä tapa.
Contraband kirjoitti:
Antin linkittämä salasanasuojausesimerkki on kyllä toimiva, mutta se on mahdollista ohittaa varsin helposti, jos register_globals-asetus on päällä.
Hyvä huomautus: en tullut ajatelleeksi tuota asiaa lainkaan.
Aihe on jo aika vanha, joten et voi enää vastata siihen.