<html> <head> <title>Demo2t2</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> </head> <body> <p>Mitä ohjelmointikieliä osaat?</p> <form action="http://localhost/sijainti1/mail.php" method="post"> <select name="kielet[]" multiple="multiple"> <option value="PHP">PHP</option> <option value="Java">Java</option> <option value="Actionscript">Actionscript</option> <option value="JavaScript">JavaScript</option> <option value="Python">Python</option> </select> <input type ="hidden" name="lahetetty" value="true"> <input type="submit" value="Lähetä"> </form> </body> </html>
Toinen ongelmani koskee noiden tietojen tallentamista evästeisiin (cookie). Tässä on mitä olen saanut tähän mennessä tiedostoihin setcookie.php sekä usecookie.php:
Setcookie.php:
if (isset($_POST['lahetetty'])) //referoi Lomake.html-tiedostossa sijaitsevaan piilotettuun arvoon { $uusidata=$_POST['kielet']; setcookie('data',$uusidata); }
Usecookie.php:
if (isset($_COOKIE['data'])) { foreach($_COOKIE['data'] as $name => $value) { echo "Osaat seuraavia ohjelmointikieliä: ". $name == $value . "<br>\n"; } }
Tallentaako ja tulostaako jo tuolla kaikki arvot myöhemmin, jos evästeet ovat tallessa? Vai onko kaikki päin mäntyä?
Et voi laittaa evästeeseen taulukkoa, vain tekstiä. Voit yhdistää taulukon implodella ja purkaa tulostusvaiheessa explodella. Hyvä erotinmerkki on vaikkapa "\0".
Lisäksi tulostuskoodisi on pielessä.
Metabolix kirjoitti:
Et voi laittaa evästeeseen taulukkoa, vain tekstiä.
Niin, evästeen arvo on merkkijono. Jos halutaan jotain rakenteisempaa, se pitää itse koodata – tai sitten pitää evästeen sijasta käyttää selainmuistia (localStorage), jonka selaintuessa tosin on vielä iso IE:n mentävä aukko.
lainaus:
Lisäksi tulostuskoodisi on pielessä.
Onko koodissa jotain, joka ei ole pielessä? Koko idea on hämärä, ja <select multiple> on käytettävyydeltään surkea – miksi ihmeessä ei käytetä valintaruutuja (checkboxes)?
Ette oo tainnu kumpikaan koskaan kuulla php:n serialize()-funktiosta?
Käytät keksejä täysin väärin. Sinun kuuluisi käyttää sessioita. Evästeitä et oikeastaan tarvitse yhtään mihinkään.
The Alchemist, serialisointi ei muuta mitenkään sitä, että evästeeseen laitettava arvo pitää tavalla tai toisella muuttaa tekstiksi ja takaisin. Sen sijaan serialisointi avaa uusia tietoturva-aukkoja, koska käyttäjä pääsee laittamaan taulukkoon muutakin kuin tekstiä. Havainnollistan:
<?php // X = luokka, jonka __toString-metodi luottaa, että $this->y on turvallinen. // Voisi olla vaikka jokin ihmeellinen FileReader. class X { private $y; public function __construct($y) { $this->y = $y; } public function __toString() { return file_get_contents($this->y); } } // Käyttäjältä tuleva serialisoitu eväste: // $_COOKIE["data"] = serialize(array("C++", "PHP", new X("/etc/passwd"))); $_COOKIE["data"] = 'a:3:{i:0;s:3:"C++";i:1;s:3:"PHP";i:2;O:1:"X":1:{s:4:"'. "\0X\0". 'y";s:11:"/etc/passwd";}}'; // Kysyjän toivoma käyttötapa evästeelle: $data = @unserialize($_COOKIE["data"]); if (is_array($data)) { $kielet = htmlspecialchars(implode(",", $data)); echo "<p>Osaat näitä kieliä: {$kielet}.</p>\n"; } // Yllättävä lopputulos: ?> <p>Osaat näitä kieliä: C++,PHP,root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/bin/false daemon:x:2:2:daemon:/sbin:/bin/false ... nobody:x:99:99:nobody:/:/bin/false .</p>
Tuskinpa edes tulit ajatelleeksi, että jotain tällaista voisi käydä.
Tietenkin taulukon sisällön voi tarkistaa, mutta helpommalla pääsee tässä tapauksessa implodella ja explodella, jolloin sisältö on taatusti tekstiä.
Istunnossa aukkoa ei toki ole, koska käyttäjä ei voi muokata tietoja. Toisaalta silloin ei ole koko ongelmaakaan, koska taulukon serialisointi tapahtuu automaattisesti.
Tokihan minä serialisoinnin vaarat tiedän, tässä on viime aikoina varsinkin Ruby-piireissä käynyt kuhina huonojen toteutusten takia. Pelkkä olioinstanssin luominen ei tosin itsessään vielä ole tietoturvauhka.
Aihe on jo aika vanha, joten et voi enää vastata siihen.