GET id in url beveiligen

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

Pagina: « vorige 1 2 3 4 volgende »

Frank Nietbelangrijk

Frank Nietbelangrijk

17/05/2015 10:55:08
Quote Anchor link
Je moet nooit aan de hand van een URL gaan bepalen of iemand een pagina wel of niet mag zien. Urls zijn bedoeld om naar een pagina toe te kunnen surfen en dienen gebruiksvriendelijk te zijn.

In de basis is iedere gebruiker anoniem. Pas als we hem op de website wat vragen stellen kunnen we aan de hand van de antwoorden proberen te achterhalen wie het is. Die vragen zijn dan de alom bekende username en wachtwoord. Nadat we achterhaald hebben met wie we te maken hebben kunnen we het id van de gebruiker opslaan in een sessie. Dat id staat dus niet in een url! aan de hand van het id dat in de sessie is opgeslagen bepalen we welke pagina bekeken mag worden of welke gegevens gewijzigd mogen worden.
 
PHP hulp

PHP hulp

25/12/2024 14:13:27
 
Johan de wit

johan de wit

17/05/2015 16:43:05
Quote Anchor link
Je hebt groot gelijk Frank.

Even kijken of ik duidelijke tekening kan maken.
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
_______________________________
|| ID || ID_USERS || WERKSTUKKEN||
||_____________________________||
|| 1  || 1                 || werkstuk naam    ||
||_____________________________||
|| 2  || 2                 || werkstuk naam 2 ||
||_____________________________||

Als user 1 www.domein.nl/index.php?id=1 naar www.domein.nl/index.php?id=2 verandert dan ziet hij/zij werkstuk van user 2.
 
Frank Nietbelangrijk

Frank Nietbelangrijk

17/05/2015 16:54:09
Quote Anchor link
Ja, en user 1 mag dus de url in de urlbalk wijzigen. Dat is helemaal het probleem niet.

even een paar passen terug:

www.domein.nl/index.php?id=1
www.domein.nl/index.php?id=20
www.domein.nl/index.php?id=pannekoek

Alle drie de bovenstaande urls zijn geldige url's
Alle drie de bovenstaande urls zijn door iedereen over de hele wereld opvraagbaar!
Alle drie de url's leiden naar HETZELFDE php script!

JOUW php script MOET dus gaan bepalen WIE die pagina opvraagt.

antwoorden op die vraag kunnen zijn:
- dat weten we niet want de vrager is niet ingelogd dus anoniem
- de gebruiker is ingelogd dus we weten wie het is (id staat in de $_SESSION)

als de gebruiker ingelogd is wil het nog niet zeggen dat hij de pagina ook mag bekijken.
Ik kan me voorstellen dat je enkel wilt dat een gebruiker kan kijken als het zijn EIGEN gegevens zijn.
Je moet dan dus gaan kijken of het ingelogde_gebruiker_id HETZELFDE is als het OPGEVRAAGDE id (met $_GET)

Toevoeging op 17/05/2015 16:57:16:

Laat anders even een stukje uit je login script zien. (dat stukje waar iets in de $_SESSION bewaard wordt als iemand succesvol ingelogd is). Dan kan ik je wat gerichter helpen.
Gewijzigd op 17/05/2015 16:55:04 door Frank Nietbelangrijk
 
Johan de wit

johan de wit

17/05/2015 17:00:17
Quote Anchor link
Zo iets als dit bedoel je toch?

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
<?php
$user_sessies
= $id;

switch($user_sessies)
{
    case
$id :
        echo '$user_sessies is gelijk aan $id';
        break;
    default :

        echo '$user_sessies voldoet niet aan een van de genoemde voorwaarden';
}
        
?>
Gewijzigd op 17/05/2015 17:11:09 door johan de wit
 
Frank Nietbelangrijk

Frank Nietbelangrijk

17/05/2015 17:09:37
Quote Anchor link
Laat anders even een stukje uit je login script zien. (dat stukje waar iets in de $_SESSION bewaard wordt als iemand succesvol ingelogd is). Dan kan ik je wat gerichter helpen.
 
Johan de wit

johan de wit

17/05/2015 17:15:39
Quote Anchor link
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
    /**
     * simply return the current state of the user's login
     * @return boolean user's login status
     */
    public function isUserLoggedIn()
    {
        if (isset($_SESSION['user_login_status']) AND $_SESSION['user_login_status'] == 1) {
            return true;
        }
        // default return
        return false;
    }
 
Frank Nietbelangrijk

Frank Nietbelangrijk

17/05/2015 17:20:36
Quote Anchor link
Oké aan de naam user_login_status af te leiden gaat het hier niet om het userId maar enkel om een true/false.

Je hebt beslist het userId nodig.

Je kunt altijd even in de sessie kijken ;-)
(je moet wel ingelogd zijn)

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
<?php
session_start();
echo '<pre>';
print_r($_SESSION);
echo '</pre>';
exit;
?>
 
Johan de wit

johan de wit

17/05/2015 17:24:30
Quote Anchor link
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
Array
(
    [user_email] => [email protected]
    [user_name] => test_gebruiker
    [user_id] => 3
    [user_login_status] => 1
)
 
Frank Nietbelangrijk

Frank Nietbelangrijk

17/05/2015 17:41:06
Quote Anchor link
Bingo

$_SESSION['user_id'] moeten we hebben!
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
<?PHP
session_start();
if (!(isset($_SESSION['user_login_status']) && $_SESSION['user_login_status'] != '')) {
    header ("Location: index.php");
    exit; // NA HEADER EEN EXIT EN JE SCRIPT STOPT DAN OOK DAADWERKELIJK
}

// INITIALISATIE ID MET DEFAULTWAARDE 0
$id = 0;
if(isset($_GET['id'])) {
    $id = intval($_GET['id']);
}


// VALIDATIE VAN $id
if($id < 1) {
    echo 'Ongeldige GET parameter id';
    exit;
}


// EN HIER GAAN WE DAN :-)
if($id != $_SESSION['user_id']) { // WE VERGELIJKEN DUS HET ID DAT MET GET IS OPGEVRAAGD MET HET USER_ID VAN DE INGELOGDE GEBRUIKER
    echo 'U mag niet de gegevens van anderen bekijken';
    exit;
}


try {
    $dbc = new PDO('mysql:host=localhost; dbname=', '', '');
}
catch (PDOException $e) {
    echo "Error: " . $e->getMessage();
}


if(isset($_POST['submit_btn'])) { // HIER ZOU JE EERST NOG JE FORMULIER MOETEN VALIDEREN
    $query = "UPDATE tabel SET name=? WHERE id=?";
    $stmt = $dbc->prepare($query);
    $stmt->bindParam(1, $_POST['name']);
    $stmt->bindParam(2, $_POST['uid']);
    if($stmt->execute()) {
        echo "Geupdated";
    }
else {
        echo "Probeer nogmaals";
    }

    
    // EEN GOEDE GEWOONTE IS OM NA HET VERWERKEN VAN EEN 'POST' TE REDIRECTEN
    header ("Location: whatever.php"); // KIES ZELF MAAR NAAR WELKE PAGINA JE WILT
    exit;
    
}

try {
    $query = "SELECT * FROM tabel WHERE id=?";
    $stmt = $dbc->prepare($query);
    $stmt->bindParam(1, $id);
    $stmt->execute();
    $row=$stmt->fetch(PDO::FETCH_ASSOC);
    $username = $row['user_name'];
    $id = $row['id'];
}
catch(PDOException $e) {
    echo "Error: " . $e->getMessage();
}

?>

<form id="<?php $row["id"] ?>" action="" method="POST">
<input type="hidden" value="<?php echo $id; ?>" name="uid">
  <div class="container">

<div class="panel-heading">
<h3 class="panel-title">Gegevens</h3>
</div>
  <div class="panel-body">
        <div class="row">
            <div class="col-md-6">
                    <table class="table">        
                    <tbody>

                <tr>
                    <td>Naam</td>
                    <td><input class="form-control" type="text" id="formGroupInputSmall" placeholder="Naam"name="username" value="<?php echo $username; ?>"/></td>
                </tr>
                    </tbody>
                    </table>
                    <input class="btn btn-default"  type="submit" name="submit_btn" value="Bevestigen"/>
</form>
            </div>
        </div>
    </div>
  </div>
</body>
</html>
Gewijzigd op 17/05/2015 17:45:21 door Frank Nietbelangrijk
 
Johan de wit

johan de wit

17/05/2015 19:23:30
Quote Anchor link
Na het inloggen krijg ik geen toegang meer bij bewerken pagina.

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
<?PHP

session_start();
if (!(isset($_SESSION['user_login_status']) && $_SESSION['user_login_status'] != '')) {
    header ("Location: index.php");
    exit; // NA HEADER EEN EXIT EN JE SCRIPT STOPT DAN OOK DAADWERKELIJK
}

// INITIALISATIE ID MET DEFAULTWAARDE 0
$id = 0;
if(isset($_GET['id'])) {
    $id = intval($_GET['id']);
}


// VALIDATIE VAN $id
if($id < 1) {
    echo 'Ongeldige GET parameter id';
    exit;
}


// EN HIER GAAN WE DAN :-)
if($id != $_SESSION['user_id']) { // WE VERGELIJKEN DUS HET ID DAT MET GET IS OPGEVRAAGD MET HET restaurant_id VAN DE INGELOGDE GEBRUIKER
    echo 'U mag niet de gegevens van anderen bekijken';
    exit;
}


try {
    $dbc = new PDO('mysql:host=localhost; dbname=', '', '');
}
catch (PDOException $e) {
    echo "Error: " . $e->getMessage();
}


if(isset($_POST['submit_btn'])) { // HIER ZOU JE EERST NOG JE FORMULIER MOETEN VALIDEREN
    $query = "UPDATE tabel SET name=? WHERE id=?";
    $stmt = $dbc->prepare($query);
    $stmt->bindParam(1, $_POST['name']);
    $stmt->bindParam(2, $_POST['uid']);
    if($stmt->execute()) {
        echo "Geupdated";
    }
else {
        echo "Probeer nogmaals";
    }

    
    // EEN GOEDE GEWOONTE IS OM NA HET VERWERKEN VAN EEN 'POST' TE REDIRECTEN
    header ("Location: lijst.php"); // KIES ZELF MAAR NAAR WELKE PAGINA JE WILT
    exit;
    
}

try {
    $query = "SELECT * FROM tabel WHERE id=?";
    $stmt = $dbc->prepare($query);
    $stmt->bindParam(1, $id);
    $stmt->execute();
    $row=$stmt->fetch(PDO::FETCH_ASSOC);
    $username = $row['user_name'];
    $id = $row['id'];
}
catch(PDOException $e) {
    echo "Error: " . $e->getMessage();
}

?>


<form id="<?php echo $row["id"]; ?>" action="" method="POST">
<input type="hidden" value="<?php echo $id; ?>" name="mid">
          <div class="container">

<div class="panel-heading">
<h3 class="panel-title">Gegevens</h3>
</div>
  <div class="panel-body">
        <div class="row">
            <div class="col-md-6">
                    <table class="table">        
                    <tbody>

                <tr>
                    <td>Naam</td>
                    <td><input class="form-control" type="text" id="formGroupInputSmall" placeholder="Naam"name="username" value="<?php echo $username; ?>"/></td>
                </tr>
                    </tbody>
                    </table>
                    <input class="btn btn-default"  type="submit" name="submit_btn" value="Bevestigen"/>
</form>
            </div>
        </div>
    </div>
  </div>
</body>
</html>
 
Frank Nietbelangrijk

Frank Nietbelangrijk

17/05/2015 19:29:22
Quote Anchor link
en met id=3? (Jouw id dus): www.domein.nl/index.php?id=3 ?
 
Johan de wit

johan de wit

17/05/2015 19:42:14
Quote Anchor link
Dan krijg ik wel toegang.
 
Frank Nietbelangrijk

Frank Nietbelangrijk

17/05/2015 19:52:45
Quote Anchor link
Dus dan werkt het...

Alleen jij ziet jezelf als een admin. Hoe moet een script dat weten?
Voor jouw script ben je een gebruiker ;-)

Lees nog eens terug en kom dan zelf eens met het antwoord?
 
Johan de wit

johan de wit

17/05/2015 20:00:50
Quote Anchor link
Volgens mij begreep je mij verkeerd.

Je logt in en dan kan je werkstukken uploaden (upload heb ik nog niet) onder je eigen naam.
Ik heb een pagina met lijst staan wat allemaal zelf is aangemaakt, bij elke regel is er een button om gegevens te bewerken. Ik vond het gevaarlijk uitzien dat je vanaf adresbalk id kon aanpassen en werkstukken van andere kon zien/bewerken.

Ik denk dat user_id ergens anders moet staan. Zal even naar kijken.
 
Frank Nietbelangrijk

Frank Nietbelangrijk

17/05/2015 20:19:52
Quote Anchor link
http://www.phphulp.nl/profiel/frank-nietbelangrijk/28479/
http://www.phphulp.nl/profiel/twan-de-langen/32045/

Je kan ze beiden aanklikken :-)

Toch kan ik niet jouw gegevens aanpassen :p

Linkjes en Buttons laat je enkel zien als de gebruiker ook naar de achterliggende pagina mag.
Gewijzigd op 17/05/2015 20:20:37 door Frank Nietbelangrijk
 
Thomas van den Heuvel

Thomas van den Heuvel

17/05/2015 20:19:57
Quote Anchor link
Ik houd niet van functies die iets controleren, en tegelijktijd de waarde proberen te repareren zodat het resultaat wel geldig is. De enige goede manier (wat mij betreft) om het controleren of (bijvoorbeeld) een ($_GET) variabele correct is (een auto-increment id bevat), is door te kijken (!== aanpassen) naar de vorm:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
<?php
function isIndex($in) {
    // noot voor puristen: $ accepteert één newline (\n) dus je doet er ook
    // verstandig aan dit soort input te trimmen

    return (preg_match('#^[1-9][0-9]*$#', $in) == 1);
}

?>

An tje op 16/05/2015 21:09:18:
Nog een tactiek om ID-s te obfuscaten is door ze te door de MD5-functie te halen. Je krijgt dan een tekenreeks van 32 karakters als ID. Vervolgens kan je die terug laten rekenen door de database met WHERE-clause als:
WHERE `{tabelnaam}`.`id` = MD5("{die geobfuscate ID}")
Dan is het al lastiger om oplopende ID's te voorspellen voor de eindgebruiker.

Security through obscurity is nooit een goed ontwerpprincipe. Daarnaast heeft een enigszins tech savvy persoon deze "beveiliging" zo gekraakt.
 
Eddy E

Eddy E

17/05/2015 20:49:27
Quote Anchor link
Precies, zelfde als met base64_encode() iets 'versleutelen' en terugsleutelen.
 
- Ariën  -
Beheerder

- Ariën -

17/05/2015 20:55:35
Quote Anchor link
Johan de wit op 16/05/2015 23:54:15:
Dus dat raad je af. Is het niet beter om over te gaan naar POST functie en dan MD5 inschakelen?

Ik raad het niet af, maar als je ID's echt graag wilt obfuscaten (facturen, C.V's etc..) dan raad ik aan om een unieke hash te gebruiken je je per item aanmaakt. Uiteraard blijf je onderwater de ID (PK;AutoIncrement) gewoon nog gebruiken.
Gewijzigd op 17/05/2015 20:55:51 door - Ariën -
 
Johan de wit

johan de wit

17/05/2015 21:04:36
Quote Anchor link
- Aar - op 17/05/2015 20:55:35:
Johan de wit op 16/05/2015 23:54:15:
Dus dat raad je af. Is het niet beter om over te gaan naar POST functie en dan MD5 inschakelen?

Ik raad het niet af, maar als je ID's echt graag wilt obfuscaten (facturen, C.V's etc..) dan raad ik aan om een unieke hash te gebruiken je je per item aanmaakt. Uiteraard blijf je onderwater de ID (PK;AutoIncrement) gewoon nog gebruiken.


Zo iets al uniqid()?
Gewijzigd op 17/05/2015 21:25:23 door johan de wit
 
Frank Nietbelangrijk

Frank Nietbelangrijk

17/05/2015 22:09:18
Quote Anchor link
Johan: Don't do it! Clear your mind!

Een gebruiker toetst in wat hij wil intoetsen als url. Ook met md5, unique_id or whatever string er in.
Stop je energie in "WAT LAAT IK ZIEN AAN WELKE GEBRUIKER".

(Hoeveel moeite kost het om iemand van een slecht idee af te helpen - lieve hemel :O )
 

Pagina: « vorige 1 2 3 4 volgende »



Overzicht Reageren

 
 

Om de gebruiksvriendelijkheid van onze website en diensten te optimaliseren maken wij gebruik van cookies. Deze cookies gebruiken wij voor functionaliteiten, analytische gegevens en marketing doeleinden. U vindt meer informatie in onze privacy statement.