Ik ben al een tijdje bezig met een API System te maken voor mijn website. In de database komen namelijk persoonlijke gegevens te staan die extern op te vragen zijn. Dus wil ik er zeker van zijn dat dit systeem veilig en waterdicht is.

Zo ziet de code van het systeem er ongeveer uit:

API Client:

<?php
// API Content
if (isset($_POST['username']) && isset($_POST['password'])) {
	// Encrypted Post Fields
	$username = base64_encode($_POST['username']);
	$password = base64_encode(sha1($_POST['password']));
	$ip_adress = base64_encode($_SERVER['REMOTE_ADDR']);
	
	// PHP Curl
	$ch = curl_init($api_server);
	curl_setopt($ch, CURLOPT_POST, 1);
	curl_setopt($ch, CURLOPT_POSTFIELDS, 'api_key=' . $api_key . '&website=' . $_SERVER['HTTP_HOST'] . '&username=' . $username . '&password=' . $password . '&ip_adress=' . $ip_adress);
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
	$re = curl_exec($ch);
	curl_close($ch);
	
	// Handle Data
	$api_content = explode('|', $re);
	if (empty($api_content[10])) {
		echo $re;
	} else {
		$data1 =   $api_content[0];
// enz enz

	}
} else {
// Hier het formulier om in te loggen  
}
?>


API Server:
De code hiervan komt niet online te staan, hieronder staat informatie die mij belangrijk lijkt om in te schatten of mijn systeem veilig is:

- Iedere query die door de database word uitgevoerd is beveiligd met de volgende functie:

<?php
// Mysql Injection
function clean_input($query) {
	$query = stripslashes($query);
	$query = strip_tags($query);
	$query = trim($query);
	return mysql_real_escape_string($query);
}
?>

- Het wachtwoord ziet er ongeveer zo uit:

<?php
$password = md5(($salt . $_POST['password']) . $salt);
?>

- De API code word gecontroleerd met de database, net zoals die website die gebruikt maakt van de API Client
- De data word uit de database 'ge-echo-ed' (onbeveiligd)
- De server maakt een logbestand met: ip adres gebruiker, ip adres website, api key, query, tijd, datum

Alvast bedankt!
Sander de Vos op 03/02/2011 15:37:55

Oke bedankt!
Maar hebben jullie ook nog ideeën voor de andere 'problemen'?

En is mijn clean_iput functie goed (genoeg).
Bevat hij onnodige dingen, of mist hij iets enz.

Alvast bedankt!

Dat hangt er van af waar je het tegen wil beveiligen en welke input je toe wilt laten. Stripslashes is overbodig in deze context en kan je problemen geven als je later weer addslashes moet toevoegen. Mysql_real_escape_string() is voldoende voor beveiliging tegen SQL injectie. Strip_tags heb je alleen nodig als je de data op wat voor manier output en je de gebruikers wil beschermen tegen mogelijke XSS aanvallen.

Om even terug te komen op het hele SHA/MD5 gebeuren terug te komen. MD5 is oud en moet niet meer gebruikt worden. Leesvoer: http://stackoverflow.com/questions/348109/is-double-hashing-a-password-less-secure-than-just-hashing-it-once en http://stackoverflow.com/questions/287517/encrypting-hashing-plain-text-passwords-in-database#287883
Strip_tags heb je alleen nodig als je de data op wat voor manier output en je de gebruikers wil beschermen tegen mogelijke XSS aanvallen.

En wat is er mis met htmlspecialchars() ?
Wel ja, het is kiezen, he.

Ofwel kies je voor htmlspecialchars(), dan krijg je html tags te zien zoals je broncode ziet; ofwel strip je ze.
Dan is htmlspecialchars beter dan striptags. Met striptags kun je namelijk nog steeds (complexe) XSS-injecties uitvoeren, met htmlentities niet omdat alle tekens naar nutteloze entiteiten worden omgezet.
Of je combineert ze

htmlspecialchars(striptags($mijn_tekst))

Wat striptags niet verwijdert, haalt htmlspecialchars dan alsnog weg.
Maar waarom zou je tags weg willen halen? Misschien wil de poster ze wel gebruiken om iets duidelijk te maken.
Dus iets als dit voldoet ook:

<?php
function clean_input($query) {
    if(get_magic_quotes_gpc()) {
        $query = stripslashes($query);
    }
	return mysql_real_escape_string($query);
}
?>
Nee, want je moet magic quotes uitzetten. En je moet data zo puur mogelijk in je database zetten. Je gaat hem pas bewerken op het moment dat je data uit je tabel haalt.
Dus alleen mysql_real_escape_string over een input is genoeg?
Ja, dat is voldoende. Alle andere functies, zoals htmlentities etc., pas je toe net voordat je de data als output gaat versturen...

Reageren