GET id in url beveiligen

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

Pagina: « vorige 1 2 3 4

Johan de wit

johan de wit

21/05/2015 13:40:32
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
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
89
90
<?PHP
session_start();
if (!(isset($_SESSION['user_login_status']) && $_SESSION['user_login_status'] != '')) {
    header ("Location: index.php");
}


// 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';
}


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

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) {

// ALLEEN ROW VAN SESSIES IS TOEGESTAAN
if(isset($id)) {
    if($id == $row['user_id']) {
        wijzig_upload_bestand(); // BESTAND MAG NIET GROTER DAN *** ZIJN.
    } else {
        echo "Foei, stout, niet lief! Jij mag niet andermans spulletjes verwijderen.";
    }
}
else {
    echo "Zonder ID kan ik niks!";
}


if(isset($_POST['submit_btn'])) { // HIER ZOU JE EERST NOG JE FORMULIER MOETEN VALIDEREN
    $query = "UPDATE tabel SET name=? WHERE id=?, user_id=$_SESSION['user_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

    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>
Gewijzigd op 21/05/2015 13:41:09 door johan de wit
 
PHP hulp

PHP hulp

25/12/2024 14:20:03
 
- Ariën  -
Beheerder

- Ariën -

21/05/2015 17:35:35
Quote Anchor link
Ik mis nog steeds een goede stroomlijn in de code. Probeer deze eens, dit is een stuk logischer opgebouwd en tevens ook overzichtelijker.

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
<?PHP
session_start();
if (!(isset($_SESSION['user_login_status']) && $_SESSION['user_login_status'] != '')) {
    header ("Location: index.php");
}
else {
    // je bent ingelogd, vervolg de rest van de stappen..
    if(isset($_GET['id']) && $_GET['id'] > 0) {
        // controleer of het ID is ingevuld en groter is dan 0
        // VOER HIER DE REST VAN DE STAPPEN UIT!!!!!

    } else {
        echo "Er is geen ID-nummer ingevuld!";    
    }
    
}

?>
Gewijzigd op 21/05/2015 17:54:02 door - Ariën -
 
Johan de wit

johan de wit

21/05/2015 19:05:44
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
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
<?PHP
session_start();
if (!(isset($_SESSION['user_login_status']) && $_SESSION['user_login_status'] != '')) {
    header ("Location: index.php");
    exit();
}
else {
    // je bent ingelogd, vervolg de rest van de stappen..
    if(isset($_GET['id']) && $_GET['id'] > 0) {
        // controleer of het ID is ingevuld en groter is dan 0
        // VOER HIER DE REST VAN DE STAPPEN UIT!!!!!

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

    
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) {

if(isset($_POST['submit_btn'])) { // HIER ZOU JE EERST NOG JE FORMULIER MOETEN VALIDEREN
    $query = "UPDATE tabel SET name=? WHERE id=?, user_id=$_SESSION['user_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

    echo "Error: " . $e->getMessage();
}
    }
else {
        echo "Er is geen ID-nummer ingevuld!";    
    }
    
}

?>


<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>
Gewijzigd op 21/05/2015 20:07:10 door johan de wit
 
- Ariën  -
Beheerder

- Ariën -

21/05/2015 19:39:11
Quote Anchor link
Ik zie nog steeds twee controles of een ID-nummer is ingevuld.
 
Johan de wit

johan de wit

21/05/2015 19:43:20
Quote Anchor link
Sorry dat was ik vergeten. Ik heb het aangepast.
 
Thomas van den Heuvel

Thomas van den Heuvel

21/05/2015 19:43:51
Quote Anchor link
Uhm...

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
<?php
if ($veiligheidsCheckDieMislukt) {
    header('Location: unauthorized.htm');
}


// Deze code wordt gewoon uitgevoerd alvorens je geredirect wordt...
?>

Zet na een header('Location: ...') altijd een exit.

Ik heb dit topic nu een tijdje zitten volgen en ik zit mij een beetje te verbijten over de structuur. Wat ik persoonlijk zou doen is het volgende:
- maak een inventarisatie van de verschillende soorten gebruikers
heb je een superadmin die alles ziet? of alleen maar gebruikers die bij hun eigen werkstukken kunnen?
dit bepaalt mede uit hoeveel verschillende (beheer)schermen je applicatie bestaat

- maak een opdeling in acties, er zijn er al een aantal de revu gepasseerd:
* toevoegen werkstuk
* inzage/wijzigen werkstuk
* verwijderen werkstuk

Overigens zou je over die laatste kunnen nadenken: gooi je echt alles daadwerkelijk weg, of zet je een "deleted" flag op true zodat de gebruiker dit werkstuk niet meer ziet, maar wanneer iemand klaagt dat de computer zijn/haar werkstuk heeft opgegeten, dan kun je deze eenvoudig terughalen

- stop herhalende delen in aparte bestanden
zoals het starten van een sessie, het opbouwen van een database connectie; ook zou je wat hulpfuncties voor database-queries in het leven kunnen roepen

Kortom, misschien wordt het tijd eens inhoudelijk na te denken over het (fatsoenlijk) structureren van je applicatie.
 
- Ariën  -
Beheerder

- Ariën -

21/05/2015 19:48:33
Quote Anchor link
.... en begin daarom eens aan het ontwerpen en uitschrijven van een 'flowchart'.
 
Johan de wit

johan de wit

21/05/2015 20:13:43
Quote Anchor link
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
Zet na een header('Location: ...') altijd een exit.

Toegevoegd

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
- maak een inventarisatie van de verschillende soorten gebruikers
heb je een superadmin die alles ziet? of alleen maar gebruikers die bij hun eigen werkstukken kunnen?
dit bepaalt mede uit hoeveel verschillende (beheer)schermen je applicatie bestaat

Nee, er is geen superadmin.

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
- maak een opdeling in acties, er zijn er al een aantal de revu gepasseerd:
* toevoegen werkstuk
* inzage/wijzigen werkstuk
* verwijderen werkstuk

Verwijderen werkstuk is er niet. De reden heb je al opgenoemd.

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
- stop herhalende delen in aparte bestanden
zoals het starten van een sessie, het opbouwen van een database connectie; ook zou je wat hulpfuncties voor database-queries in het leven kunnen roepen

Include heb ik nog niet gebruikt omdat ik juist hele overzicht wilde tonen.

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
.... en begin daarom eens aan het ontwerpen en uitschrijven van een 'flowchart'.

Voor edit pagina is flowchart niet nodig toch? Ik bedoel flowchart is voor hele project bedoeld.
Gewijzigd op 21/05/2015 20:14:41 door johan de wit
 
- Ariën  -
Beheerder

- Ariën -

21/05/2015 20:21:04
Quote Anchor link
Een flow-chart schept wel duidelijkheid, vooral als er diverse controles in het script zitten.
 
Johan de wit

johan de wit

21/05/2015 20:22:37
Quote Anchor link
Afbeelding
Gewijzigd op 21/05/2015 20:42:03 door johan de wit
 

21/05/2015 20:56:15
Quote Anchor link
WERK STUK :-)
 
Thomas van den Heuvel

Thomas van den Heuvel

21/05/2015 20:57:47
Quote Anchor link
Ik denk dat het voornaamste probleem de queries zijn, en waar je welke controles uitvoert. Je moet een onderscheid maken tussen bepalen wat je probeert te doen en te controleren wat iemand mag doen.

Dit topic was er om begonnen met de vraag hoe je er voor zorgt dat iemand alleen maar bij zijn eigen informatie kan.

Je hebt geen controle over wat iemand in een URL propt, dus het enige wat je rest is de informatie die een script tot zijn beschikking heeft of van buitenaf ontvangt onder een vergrootglas leggen.

Hierbij moet je dus onderscheid maken tussen wat iemand probeert te doen, m.a.w., welke actie probeert iemand uit te voeren (bijvoorbeeld het opvragen van informatie van een werkstuk met als doel informatie te wijzigen), en de controles die je uitvoert om deze acties te ontgrendelen.

Beschouw de actie waarbij iemand de informatie van een werkstuk wil inzien om deze te wijzigen.

Hierbij horen de volgende controles:
- de gebruiker moet ingelogd zijn
- er moet op enigerlei wijze een "geldig" werkstuk-id worden doorgegeven, bijvoorbeeld via de URL; als dit werkstuk-id geen positief geheel getal (groter dan 0) is, dan hoef je niet eens een query uit te gaan voeren
Als aan beide bovenstaande criteria is voldaan kun je een poging ondernemen om informatie van een werkstuk op te halen, hierbij bouw je een query waarbij:
- het id gelijk moet zijn aan het werkstuk-id uit de url (die je vantevoren hebt gecontroleerd op een juiste vorm, om SQL-injectie te voorkomen)
EN
- de eigenaar van het op te vragen werkstuk gelijk moet zijn aan de user-id uit de sessie

Als je query geen resultaat oplevert toon je simpelweg een boodschap "werkstuk niet gevonden" en anders druk je de werkstuk-informatie op een veilige manier af.

Ook bij de verwerking zou je eigenlijk eerst moeten controleren wie de eigenaar is van het te wijzigen werkstuk(-id). Als je het heel netjes wilt doen (en in een omgeving waarin meerdere gebruikers actief zijn is dit sowieso een verstandig idee) stop je deze hele verwerkstap in een database-transactie.
Gewijzigd op 21/05/2015 21:00:19 door Thomas van den Heuvel
 
Johan de wit

johan de wit

21/05/2015 21:10:20
Quote Anchor link
Thomas je weet precies wat ik wil. Wat moet ik nu aan bestaande script aanpassen?
 
Thomas van den Heuvel

Thomas van den Heuvel

21/05/2015 22:05:19
Quote Anchor link
De eerste stap lijkt mij dat je alles indeelt in logische eenheden (de eerder genoemde acties). Een actie moet eenduidig zijn, oftewel één duideklijk omschreven doel hebben.

Je zou bijvoorbeeld acties kunnen opdelen in losse PHP-bestanden, waarbij je de bestandsnamen tegelijkertijd omschrijvende namen geeft:

werkstuk_toevoegen.php
werkstuk_toevoegen_verwerken.php
werkstuk_wijzigen.php
werkstuk_wijzigen_verwerken.php
et cetera

Hierbij is direct duidelijk wat het doel van elk bestand is en bewaar je een zeker overzicht omdat code voor het opvragen + afdrukken van werkstuk-informatie niet is verweven met code voor het opslaan van wijzigingen of wat dan ook.

Ik ga dit niet helemaal uitschrijven, maar ik zou je een opzetje kunnen geven.

init.php
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
<?php
// dit bestand zorgt voor een correcte initialisatie van je applicatie
// standaard content-type en character encoding van output, aanname: alles is UTF-8

header('Content-Type: text/html; charset=UTF-8');

// debugging - alleen voor ontwikkeling
error_reporting(E_ALL);
ini_set('display_errors', 'stdout');

// init sessie
session_start();

// database connectie
try {
    // aanname PHP versie 5.3.6 of nieuwer en tabellen hebben UTF-8 encoding
    $db = new PDO('mysql:host=127.0.0.1;dbname=je_database_naam;charset=utf8', 'je_username', 'je_wachtwoord', array(
        PDO::ATTR_ERRMODE                  => PDO::ERRMODE_EXCEPTION,
        PDO::ATTR_EMULATE_PREPARES         => true,
        PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => true,
    ));
}
catch(PDOEXception $e) {
    die('db connection failed');
}

?>


functions.php
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
<?php
// enkele hulpfuncties
function isIndex($in) {
    // remember to trim $in as $ accepts a (one) newline (\n)
    return (1 == preg_match('#^[1-9][0-9]*$#', $in));
}


// functie om HTML onschadelijk te maken
function escape($in) {
    return htmlspecialchars($in, ENT_QUOTES, 'UTF-8');
}


// voor correct en volledig HTML document
function __header($title='') {
?>
<!DOCTYPE html>
<html>
<head>
<title><?php echo $title ?></title>
<!-- voeg hier nog css, js etc in -->
</head>

<body><?php
}

// voor correct en volledig HTML document
function __footer() {
?>
</body>
</html><?php
}
?>


werkstuk_wijzigen.php
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
<?php
require_once './init.php';
require_once './functions.php';

// is de gebruiker ingelogd?
if (empty($_SESSION['user_id')) {
    // voor nu geen nette afhandeling / doorverwijzing
    die('access denied');
}


// is er een id ingesteld?
if (isset($_GET['id']) && isIndex($_GET['id'])) {
    $id = trim($_GET['id']);
}
else {
    die('invalid id');
}


// vraag nu je informatie op
$st = $db->prepare('SELECT * FROM tabel WHERE id = ? AND user_id = ?');
if ($st->execute(array($id, $_SESSION['id'])) {
    // ik verwacht precies 1 resultaatrij...
    $werkstuk = $st->fetch(PDO::FETCH_ASSOC);
    $st->closeCursor();
    // retourneert ook false als er geen resultaten zijn...
    if ($werkstuk === false) {
        die('no werkstuk found');
    }

    // $werkstuk bevat nu een associatief array waarmee je je formulier kunt opbouwen,
    // dit formulier verstuur je naar (de form action is) werkstuk_wijzigen_verwerken.php
    // bouw je HTML document en druk je formulier af

    __header('Bewerk werkstuk - '.escape($werkstuk['name']));
        // als je ook bestanden wilt uploaden, vergeet dan niet enctype=multipart/form-data
        ?>
<form action="werkstuk_wijzigen_verwerken.php?id=<?php echo escape($werkstuk['id']) ?>" method="post" accept-charset="UTF-8">
        <p><label for="name">name</label><input type="text" name="name" id="name" value="<?php echo escape($werkstuk['name']) ?>" /></p>
        <p><button type="submit">opslaan</button></p>
        </form><?php
    __footer();
}
else {
    die('query failed');
}

?>


EDIT: leeg resultaat check toegevoegd

Succes ermee.
Gewijzigd op 21/05/2015 22:26:06 door Thomas van den Heuvel
 
Johan de wit

johan de wit

26/05/2015 15:05:14
Quote Anchor link
Dank je wel werstuk_wijzigen.php regel 6 heb ik aangepast:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
<?PHP
if (empty($_SESSION['user_id')) {
?>

naar
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
<?PHP
if (empty($_SESSION['user_id'])) {
?>


regel 20 en 38 geeft foutmeldingen.

regel 20: parse error unexpected {
regel 38: parse error unexpected ELSE
Gewijzigd op 26/05/2015 15:06:27 door johan de wit
 
- Ariën  -
Beheerder

- Ariën -

26/05/2015 15:16:49
Quote Anchor link
Regel 20: Mist een )
 
Thomas van den Heuvel

Thomas van den Heuvel

26/05/2015 15:18:56
Quote Anchor link
Come on... Tel het aantal openings- en sluitingshaakjes en pas dit aan.

Als je dit nog niet kunt debuggen moet je je ook niet met moeilijkere dingen bezighouden.

Iets meer moeite doen ajb.
 
Johan de wit

johan de wit

26/05/2015 15:19:23
Quote Anchor link
Dank je wel Aar er zijn geen fouten meer. Ik heb net Visual Studio Code geinstalleerd dat geeft netjes errors aan. :)
 
- Ariën  -
Beheerder

- Ariën -

26/05/2015 15:21:19
Quote Anchor link
Graag gedaan, hoewel de fout niet zo heel moeilijk te vinden is.
Een kwestie van haakjes tellen.
 
Johan de wit

johan de wit

26/05/2015 15:21:27
Quote Anchor link
Ik neem ook moeite maar soms heb je dat simpele dingen over je hoofd ziet, ben vast ook niet de enige.

Toevoeging op 26/05/2015 15:22:11:

Ik zal voortaan tellen.
 

Pagina: « vorige 1 2 3 4



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.