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
}
?>
Johan de wit op 16/05/2015 16:04:58

Bij regel 9 krijg ik de volgende foutmelding.
Strict Standards: Only variables should be passed by reference in


Oh oké ja dat kan.

Dan moet dat dus in twee stappen

<?php
$safeId = intval($_GET['id']);
$stmt->bindParam(1, $safeId);
?>
Frank Nietbelangrijk op 16/05/2015 16:50:45

<?php
$safeId = intval($_GET['id']);
$stmt->bindParam(1, $safeId);
?>

Heeft geholpen. Dank je wel.
Johan de wit op 16/05/2015 16:04:58

Ik krijg dit keer netjes foutmelding zodra ik 0 achter id= en als ID niet bestaat dan krijg ik geen melding, onbevoegde kunnen wel bij andermans ID komen, welke oplossingen kan ik hiervoor gebruiken? Ik dacht aan iets als base64_encode() maar dat kan je makkelijk omzetten met base64_decoder().


Nee dit dien je anders op te lossen.

Per (deel van een) pagina kun je bepalen wie het wel mag zien en wie niet.
Laten we uitgaan van een profielpagina waar een aantal privacy gevoelige gegevens te zien zijn.

In het voorbeeld gaan we uit van drie soorten gebruikers:
a) bezoekers (niet ingelogd)
b) normale gebruikers (enige rechten)
c) administrators (alle rechten)

Om type b en c van elkaar te kunnen scheiden zul je een extra kolom in je tabel users moeten aanmaken. De naam van de kolom zou role kunnen zijn en je vult dan per gebruiker ROLE_ADMIN of ROLE_USER in. Je kunt later altijd nog meer rollen toevoegen.

Dan de profielpagina. Wie mag nou een profielpagina bekijken of bewerken?

ROL           | RECHTEN
====================================
niet ingelogd | verboden
ROLE_USER     | alleen eigen pagina
ROLE_ADMIN    | alle profielpagina's


Nu in PHP:

<?php
// get variabele id is verplicht!
if(!isset($_GET['id']) && intval($_GET['id']) > 0) {
echo 'Geen geldig id opgegeven';
exit;
}
$id = intval($_GET['id']);

// gebruiker moet ingelogd zijn
if(!isset($_SESSION['id'])) {
{
header('Location: login.php');
exit;
}

//Haal de gegevens van de ingelogde gebruiker uit de database
$conn = mysqli_connect(/* bla bla */);
$result = mysqli_query($conn, "SELECT * FROM users WHERE id=" . $SESSION['id']);
$loggedIn = mysqli_fetch_assoc($result);

//dan moet de gebruiker nog voldoende rechten hebben
if($loggedIn['role'] != 'ROLE_ADMIN' && loggedIn['id'] != $id)
{
echo 'U heeft onvoldoende rechten';
exit;
}

// laat de profielpagina zien
?>

Regel 3 mist ")":
if(!isset($_GET['id'] && intval($_GET['id']) > 0) {


Regel 22 heeft deze foutmelding:
Parse error: syntax error, unexpected '[' in 

Moet $id niet tussen de haken?
if($loggedIn['role'] != 'ROLE_ADMIN' && loggedIn['id'] != $id)
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.
MD5 is oud wnat je kan overal decoderen.
Als je lang genoeg doorgaat is iets nooit 100% veilig natuurlijk. Maar het werpt een extra barricade op. En het gaat om het principe, wat weerhoudt je om andere encryptie-algoritmes te gebruiken?
Je kunt zelfs nog een willekeurig aangemaakt (metadata) ID gebruiken, dan kan het helemaal gissen zijn voor iemand die kwaad wil.
Inderdaad je hebt daar gelijk in. Willekeurige metadata? Wil je wat meer daar over vertellen?
Willekeurig aangemaakte tekenreeksen zijn databasetechnisch geen vervanger voor ID's en hoogstens visueel bedoeld. Je moet dus zowel een INT (PK) veld voor je ID hebben als een veld voor je willekeurige tekenreeks.
Dus dat raad je af. Is het niet beter om over te gaan naar POST functie en dan MD5 inschakelen?

Reageren