2015. ápr 11.

Biztonságos linkek 2.

írta: Bozzai Gyula
Biztonságos linkek 2.

urlencode_01_k.jpg

Egy korábbi témát folytatunk ott, ahol abbahagytuk. Addig jutottunk, hogy sikeresen összelinkeltünk két oldalt, és a linket az urlencode függvénnyel kódoltuk, hogy elkerüljük a hibás működést.

Ha még nem olvastad, akkor kezd a korábbi cikkel! >>>

Tehát ott tartunk, hogy van két oldalunk.

oldal1.php: 

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Oldal 1</title>
</head>
<body>
<?php $cegnev = "Procter & Gamble"; ?>
<a href="oldal2.php?cegnev=<?php echo urlencode($cegnev); ?>">Oldal 2</a> </body> </html>

oldal2.php:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Oldal 2</title>
</head>
<body>
    <?php

        $cegnev = $_GET['cegnev'];

        if (isset($cegnev)) {
            echo $cegnev;
        } else {
            echo '$cegnev nem létezik!';
        }
        
    ?>
</body>
</html>

Most a második oldalra fogunk fókuszálni.

Mielőtt továbblépnénk, jól jegyezzük meg a következőt: bármilyen adatban vagy értékben, ami felhasználóktól érkezik, SOSEM szabad megbízni. Felhasználás előtt, mindig ellenőrizni kell. Ebben a posztban ennek az alapjaival foglalkozunk.

Az egész ott indul, hogy bár a linket egy másik oldalról mi indítottuk, a felhasználó azt szabadon manipulálhatja, azaz a céloldalnak bármilyen paramétereket küldhet.

Első probléma: egy cegnev nevű változót várunk a linken keresztül, amit szeretnénk feldolgozni. De mi van ha a linket átírják, és ez a változó nem érkezik meg? Természetesen nincs értelme tovább futtatni a programunkat. Ezért ellenőrizzük, hogy létezik-e a változó és ha nem, akkor leállítjuk a további feldolgozást:

oldal2.php:

<?php

    if (isset($_GET['cegnev'])) {
        $cegnev = $_GET['cegnev'];
    } else {
        echo 'Hiba történt a feldolgozás során!';
        exit;
    }
    
    echo 'Eddig jók vagyunk!';
    
?>

Elemezzük a fenti kódot! Az isset függvényt már ismerjük az első részből, ezzel ellenőrizzük, hogy egy változó létezik-e. Az új dolog az exit parancs. Ha erre fut a program, akkor megáll, az ez utáni kód nem kerül végrehajtásra.

Teszteljük a fenti kódot, ha a linkben helyesen szerepel a ?cegnev=akarmi rész, akkor az "Eddig jók vagyunk!" feliratot látjuk, ha hibás vagy hiányzik, akkor a "Hiba történt a feldolgozás során!" látható.

Második probléma: Túljutottunk az első akadályon, írassuk ki a cég nevét a képernyőre. Ez egyszerű, használjuk az echo utasítást:

oldal2.php:

<?php

    if (isset($_GET['cegnev'])) {
        $cegnev = $_GET['cegnev'];
    } else {
        echo 'Hiba történt a feldolgozás során!';
        exit;
    }

    echo $cegnev;
    
?>

Látszólag minden jó, megjelent a képernyőn a cég neve. A második probléma abból adódik, hogy a ?cegnev= után a felhasználó gyakorlatilag bármilyen HTML kódot beírhat, a böngészőnk megjeleníti. Próbáljuk ki a következő linket:

 

.../oldal2.php?cegnev=<p>Bármilyen HTML utasítást végrehajt ez az oldal!</p><b>Bármit megtehetek itt!</b>

Az eredmény:

biztlink2.jpgMost gondoljuk végig, hogy van egy oldalunk, ami bárki számára, bármilyen külső oldalról meghívható, egy link segítségével. Erre valaki belerondít egy nem kívánt HTML kóddal, nem nagyon örülnénk neki... Mi több, elhelyezhetne saját linket az oldalunkra stb.

Vagy, akkor is gondban vagyunk, ha semmilyen ártó szándék nincs a linkben, hanem ténylegesen speciális HTML karaktereket tartalmaz a paraméter (Lásd a cikk végén, a bónusz probléma résznél.)

De semmi gond, használjuk a beépített htmlspecialchars függvényt, amely a speciális HTML karaktereket, sima szöveggé alakítja, így a böngésző már nem értelmezi feldolgozandó HTML kódnak.

De mik azok a speciális, HTML karakterek? Íme:

 

< > & "

Tehát a probléma megoldása:

oldal2.php: 

<?php

    if (isset($_GET['cegnev'])) {
        $cegnev = $_GET['cegnev'];
    } else {
        echo 'Hiba történt a feldolgozás során!';
        exit;
    }

    echo htmlspecialchars($cegnev);
    
?>

Oldalunkon már csak egy sima szöveg jelenik meg, ahogy azt szerettük volna:

 

<p>Bármilyen HTML utasítást végrehajt ez az oldal!</p><b>Bármit megtehetek itt!</b>

Harmadik probléma: Oké, de mi van akkor, ha a várt paraméter nem szöveg? Hanem mondjuk egy szám. Akkor nem dolgozhatjuk fel szövegként. Ekkor, ha biztosak akarunk lenni abban, hogy paraméterként számot kaptunk, használjuk a típusmegfeleltetést. Erről már egy korábbi cikkben írtam, ezért itt nem részletezem.

- Tehát, először ellenőrizzük, hogy a paraméter létezik (lásd fent)
- Másodszor használjuk a típusmegfeleltetést
- Harmadszor, ellenőrizzük, hogy a kapott szám helyes-e (ez viszont már egy másik történet...)

A kód:

oldal2.php: 

<?php

    if (isset($_GET['szam'])) {
        $szam = $_GET['szam'];
    } else {
        echo 'Hiba történt a feldolgozás során!';
        exit;
    }

    $szam2 = (int) $szam;
echo $szam2; ?>

Bónusz probléma: Ez inkább a cikk első részéhez tartozik, de most jutottunk el oda, hogy megértsük.
Mi van akkor, ha olyan link szöveget szeretnénk, ami tartalmaz speciális HTML karaktert, de nem tudjuk, hogy a céloldal, ezt hogy dolgozza fel? Például mondjuk ilyet:

 

<Kattints ide>

A megoldás természetesen a htmlspecialchars függvény. Tehát a múltkori példa kiegészítve:

oldal1.php: 

<?php

    $cegnev = "Procter & Gamble";
$linktext = "<Kattints ide>"; ?> <a href="oldal2.php?cegnev=<?php echo urlencode($cegnev); ?>">
<?php echo htmlspecialchars($linktext); ?></a>

Tehát, mindegy, hogy linket hozunk létre, vagy feldolgozzuk a céloldalon, a biztonságos működésről gondoskodnunk kell.

A témát lehetne még boncolgatni, de kiindulópontnak bőven elegek lesznek a fentiek is.

Szólj hozzá

echo if else urlencode HTML isset htmlspecialchars