PHP jQuery AJAX HTTPRequest onveilig?
Ik heb een paar dagen geleden een HTTPRequest gemaakt met jQuery, Ajax en PHP die de data dmv een $_POST meegeeft, dan data ophaalt uit een database en daarmee de content opnieuw inlaadt.
Een vriend van mij heeft gezegt dat deze manier heel makkelijk te hacken is, maar voor dat ik kon vragen waarom ging hij alweer offline.
Kan iemand van jullie mij misschien uitleggen waarom deze methode onveilig is?
Alvast bedankt.
-Richard
Dit is mijn code:
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//File: contentswitch.js
$(document).ready(function() {
$("#menu ul li").click(function() {
var Title = $(this).attr("title");
$('#content').fadeOut();
$.post("contentswitch.php", { page: Title }, function(data) {
$('#content').html(data);
});
});
});
//File: contentswitch.php
<?php
if(isset($_POST['page'])) {
include 'database.php';
include 'functions/convertdate.php';
include 'functions/getcontent.php';
echo getContent($_POST['page']);
}
//getContent is een functie die de content uit mijn database haalt,
//vandaar include 'database.php';
?>
$(document).ready(function() {
$("#menu ul li").click(function() {
var Title = $(this).attr("title");
$('#content').fadeOut();
$.post("contentswitch.php", { page: Title }, function(data) {
$('#content').html(data);
});
});
});
//File: contentswitch.php
<?php
if(isset($_POST['page'])) {
include 'database.php';
include 'functions/convertdate.php';
include 'functions/getcontent.php';
echo getContent($_POST['page']);
}
//getContent is een functie die de content uit mijn database haalt,
//vandaar include 'database.php';
?>
Iedereen kan van alles invoeren in het $_POST['page'] en daarmee bijv. tabellen uit je database verwijderen en je database gegevens bemachtigen.
Wat kan ik doen om dat tegen te gaan?
De ingevoerde data controleren voordat je iets ophaalt uit de database.
quotjes? commas?
Gewijzigd op 08/11/2011 00:32:45 door Eddy B
Gewoon hetzlefde waar je ook op controleert bij het verzenden van een formulier.
Sorry, maar ik snap niet helemaal wat jullie bedoelen.
Die moet die functie toepassen op de POST, GET en COOKIE variabelen welke je binnen je mysql_query() gebruikt.
Dus wat moet ik nou doen? Bepaalde characters filteren? Ik snap het allemaal niet meer.
Zie Eddy Bisschops zijn reactie. en kijk eens op www.php.net/mysql_real_escape_string
mysql_real_escape_string escape \x00, \n, \r, \, ', " en\x1a.
Als je bijvoorbeeld dit stuk code hebt:
mysql_query("SELECT * FROM pages WHERE page_title = '".$_POST['page']."'");
Dan zou ik in $_POST['page'] kunnen veranderen in a' OR '1
als ik dat doe wordt de query naar de DB dus
mysql_query("SELECT * FROM pages WHERE page_title = 'a' OR '1'"); en 1 return altijd alles van de SELECT.
Als je dus mysql_real_escape_string gebruikt dan werkt dit niet want dan wordt de query naar de DB
mysql_query("SELECT * FROM pages WHERE page_title = 'a\' OR \'1'");
Ik zou dit trouwens in je functie getContent doen, dus bijvoorbeeld:
Code (php)
1
2
3
4
5
6
7
2
3
4
5
6
7
<?php
function getContent($_title){
$title = mysql_real_escape_string($_title);
mysql_query("SELECT content FROM pages WHERE title = '.$title.'");
//return pagina
}
?>
function getContent($_title){
$title = mysql_real_escape_string($_title);
mysql_query("SELECT content FROM pages WHERE title = '.$title.'");
//return pagina
}
?>
Code (php)
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
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
<?php
include "database.php";
function filter_query($term) {
if(!isset($term) || empty($term)) {
$output = "The parameter must be a valid query term.";
}
else {
$filter = array('/\'/', '/\"/', '/\%/', '/\_/', '/\,/', '/\-/');
for($I = 0; $I < count($filter); $I++) {
if(preg_match($filter[$I], $term)) {
$output .= "contains ".$filter[$I]."<br />";
}
}
if(count($output) > 0) {
$Out = "404 error";
}
else {
$Out = $term;
}
}
return $Out;
}
?>
include "database.php";
function filter_query($term) {
if(!isset($term) || empty($term)) {
$output = "The parameter must be a valid query term.";
}
else {
$filter = array('/\'/', '/\"/', '/\%/', '/\_/', '/\,/', '/\-/');
for($I = 0; $I < count($filter); $I++) {
if(preg_match($filter[$I], $term)) {
$output .= "contains ".$filter[$I]."<br />";
}
}
if(count($output) > 0) {
$Out = "404 error";
}
else {
$Out = $term;
}
}
return $Out;
}
?>
Ik heb er ook een mysql_real_escape_string(); aan gehangen in de httprequest.
En de 404 komt pas als je de query naar de DB hebt gestuurd, dan check of er data is gekomen zo van de DB,ja laat dan de pagina zien, zo nee laat dan de 404 zien.
Zo krijg je altijd de correcte error te zien, bijvoorbeeld mijn data is valid, maar de pagina bestaat niet dan moet je ook 404 laten zien, maar ook als de data niet valid is, het is beter om dat op 1 plek te doen dan op verschillende plekken in je code
Als deze 1 is, wordt de pagina weergeven, als deze 0 is of groter dan 1, krijgt de gebruiker een 404 te zien.
Kijk zelf anders.
Mijn mobile website
Beste resultaat is op een mobiel apparaat te zien, iPod telt ook.
Kleine tip: moet je echt de pagina in de DB hebben? want het vaak makkelijker om met template systemen te werken zoals bijvoorbeeld Smarty.
Paginas in DB is vaak geen oplossing voor lange periode.
Mja, ik dacht, ik doe het eens anders. ;)