Ik heb een pagina aangemaakt dat gebruikers gegevens kunnen bewerken maar er viel mij iets op dat je vanaf urlbalk andere regels (en ook ids wat nog niet bestaat) van tabellen kunt bewerken terwijl dat de bedoeling niet is of je voert zomaar bijvoorbeeld letters er achter id= dan zie je nog steeds geen foutmelding.

Hoe zorg ik er voor dat je geen id uit je hoofd kan invoeren en overbodige letters met andere leestekens blokkeren?

Dit helpt bij mij niet:
bindParam(1,is_numeric($_GET['id']))

en dit:
is_numeric(bindParam(1,$_GET['id']))


Beetje opgeschoond om het kleiner te krijgen:
<?PHP
session_start();
if (!(isset($_SESSION['user_login_status']) && $_SESSION['user_login_status'] != '')) {
header ("Location: index.php");
	}
		else 	{
		try {
$dbc = new PDO('mysql:host=localhost; dbname=', '', '');
	} catch (PDOException $e) {
	echo "Error: " . $e->getMessage();
	}
if(isset($_POST['submit_btn'])) {
	$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 "<script>alert('Record updated.');location.href='index.php'</script>";
	} else {
		die('Unable to update record.');
	}
} else {
try {
$query = "SELECT * FROM tabel WHERE id=?";
$stmt = $dbc->prepare($query);
$stmt->bindParam(1,$_GET['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=".$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>
<?php
}?>
</html>
<?php
}
?>
WERK STUK :-)
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.
Thomas je weet precies wat ik wil. Wat moet ik nu aan bestaande script aanpassen?
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
<?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
<?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
<?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.
Dank je wel werstuk_wijzigen.php regel 6 heb ik aangepast:

<?PHP
if (empty($_SESSION['user_id')) {
?>

naar

<?PHP
if (empty($_SESSION['user_id'])) {
?>


regel 20 en 38 geeft foutmeldingen.

regel 20: parse error unexpected {
regel 38: parse error unexpected ELSE
Regel 20: Mist een )
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.
Dank je wel Aar er zijn geen fouten meer. Ik heb net Visual Studio Code geinstalleerd dat geeft netjes errors aan. :)
Graag gedaan, hoewel de fout niet zo heel moeilijk te vinden is.
Een kwestie van haakjes tellen.
Ik neem ook moeite maar soms heb je dat simpele dingen over je hoofd ziet, ben vast ook niet de enige.

[size=xsmall]Toevoeging op 26/05/2015 15:22:11:[/size]

Ik zal voortaan tellen.

Reageren