2009-07-08 18 views
0

Ich arbeite an einem Routenplaner-Service, wo Benutzer die von und zu Adressen eingeben und die Wegbeschreibung Tabelle (die gibt Turn-by-Turn-Informationen gibt) zusammen mit einer Karte mit der Route.Benutzereingabe, PHP, Javascript und Sicherheit

Im Folgenden finden Sie die komplette Quellcode (getdirections.php):

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml"> 
<head> 
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> 
<title>Directions</title> 
<style> 
    * { font-family: Verdana; font-size: 96%; } 
    label { width: 15em; float: left; } 
    label.error { display: block; float: none; color: red; vertical-align: top; } 
    p { clear: both; } 
    .submit { margin-left: 12em; } 
    em { font-weight: bold; padding-right: 1em; vertical-align: top; } 
</style> 
<script src="jquery-1.3.1.js" type="text/javascript"> 
</script> 
<script src="http://maps.google.com/maps?file=api&amp;v=2&amp;sensor=false& amp;key=[Your Key Here]" 
type="text/javascript"> 
</script> 
</head> 
<body onunload="GUnload()"> 
<div id="container">  
<div id="directform"> 
    <form id="direct" action="getdirections.php" method="get"> 
<p><label for="loc1">From Here:</label> 
<input id="loc1" type="text" name="location1" class="required" /></p> 
<p><label for="loc2">To Here:</label> 
<input id="loc2" type="text" name="location2" class="required" /></p> 
<p><input type="submit" value="Search" /></p> 
    </form> 
</div> 
<?php 
function filterInput ($input) { 
$replacement = ','; 
$input = preg_replace('/(\n|\r)+/', $replacement, $input); 
$replacement = " "; 
$input = preg_replace('/(\t)+/', $replacement, $input); 
$inputarray = explode(' ', $input); 
foreach ($inputarray as $i => $value) { 
    $ch = ''; 
    if ($value[strlen($value)-1] == ',') { 
    $ch = ','; 
    $value = substr($value, 0, -1); 
    } 

$value = 
     preg_replace('/^(\&|\(|\)|\[|\]|\{|\}|\"|\.|\!|\?|\'|\:|\;)+/', "", $value); 

$inputarray[$i] = 
     preg_replace('/(\&|\(|\)|\[|\]|\{|\}|\"|\.|\!|\?|\'|\:|\;)+$/', "", $value); 
$inputarray[$i] = $inputarray[$i].$ch; 
} 
$filteredString = implode(" ", $inputarray); 
return $filteredString; 
} 

?> 
</div>  
<table class="directions"> 
<tr> 
<td valign="top"> 
    <div id="directions" style="width: 100%"></div> 
</td> 
</tr> 
<tr> 
<td valign="top"> 
<div id="map_canvas" style="width: 250px; height: 400px"></div> 
</td> 
</tr> 
<td valign="top"> 
<div id="directions_url"></div> 
</td> 
</table> 

<noscript><b>JavaScript must be enabled in order for you to use Google Maps.</b> 
    However, it seems JavaScript is either disabled or not supported by your browser. 
    To view Google Maps, enable JavaScript by changing your browser options, and then 
    try again. 
</noscript> 
<script type="text/javascript"> 

// This programming pattern limits the number of global variables 
// Thus it does not pollute the global namespace 
// for_directions is the only global object here. 
for_directions = function(){ 

// The map is loaded into the div element having id specified by mapid 
// private variable 
var mapid = "map_canvas"; 

// The direction listing is loaded into the div element having id specified by directionsid. 
// private variable 
var directionsid = "directions"; 

// From here 
// private variable 
var location1; 

// To here 
// private variable 
var location2; 

// The functions (init and addevent) are public methods of for_directions object 
return { 
    // Called on loading of this page 
    // public method 
    init: function(){ 
     location1 = "<?= filterInput($_GET['location1']) ?>" || 0; 
     location2 = "<?= filterInput($_GET['location2']) ?>" || 0; 
     var directions = document.getElementById(directionsid); 
     directions.innerHTML = "Please check the address and try again"; 

     if (GBrowserIsCompatible() && location1 != 0 && location2 != 0){ 
      mapAddress(location1, location2); 
      } 
    }, 

    // This method is cross browser compliant and is used to add an event listener 
    // public method 
    addEvent:function(elm,evType,fn,useCapture){ 
     if(elm.addEventListener){ 
      elm.addEventListener(evType, fn, useCapture); 
      return true; 
     } else if (elm.attachEvent) { 
      var r = elm.attachEvent('on' + evType, fn); 
      return r; 
     } else { 
      elm['on' + evType] = fn; 
     } 
    } 
}; 

// Called from init 
// private method 
    function mapAddress (address1, address2){ 
     var geocoder = new GClientGeocoder(); 
    var directions = document.getElementById(directionsid); 
    var i = 0; 

    geocoder.getLatLng(address1, function(point1){ 
     if (point1){ 
     geocoder.getLatLng (address2, function(point2){ 
      if (point2){ 
      getDirections(); 
      } else { 
      directions.innerHTML = "Please check the address and try again"; 
      } 

     }); 
     } else { 
     directions.innerHTML = "Please check the address and try again"; 
     } 

    }); 
} 

// Called from mapAddress to load the directions and map 
// private method 
function getDirections(){ 
    var gmap = new GMap2(document.getElementById(mapid)); 
    var gdir = new GDirections(gmap,document.getElementById(directionsid)); 
    gdir.load("from: " + location1 + " to: " + location2, 
      { "locale": "en_US" }); 
    generateURL(); 
} 

function generateURL(){ 
    var url = "http://maps.google.com/maps?saddr="; 
    url += location1; 
    url += "&daddr="; 
    url += location2; 
    var a = $("<a></a>").attr('href',url); 
    $(a).text("Google Maps"); 
    $("#directions_url").append(a); 
} 
}(); 
// The(); above results in the function being interpreted by the browser just before the page is loaded. 

// Make for_directions.init as the listener to load event 
// Note that the init method is public that why its accessible outside the object scope 
for_directions.addEvent(window, 'load', for_directions.init, false); 
</script> 
</body> 
</html> 

Wenn Sie diesen Code auf Ihrem System Namen ausprobieren es als getdirections.php. Das einzige, was Sie ändern müssen, ist der Google Maps API-Schlüssel. Sie können den Schlüssel here bekommen.

Sobald Sie Ihren Schlüssel in der Schlüsselparameter (reproduziert die Zeile unter der Einfachheit halber) setzen erzeugen:

<script src="http://maps.google.com/maps?file=api&amp;v=2&amp;sensor=false& amp;key=[Your key here]" 
type="text/javascript"> 

Wie aus dem obigen Code zu sehen ist, erhalte ich die Eingabe über PHP und tun, um die Verarbeitung in Javascript . Nun möchte ich nicht, dass Benutzer mit irgendeiner Art von Eingabe (javscript, gefährlichem HTML usw.) davonkommen. Ich habe versucht, die URL-Code-Funktion in PHP zu verwenden. Die codierte Benutzereingabe wird jedoch vom JavaScript-Code nicht akzeptiert und schlägt selbst bei guter Eingabe fehl.

Als Workaround für dieses Problem schrieb ich eine FilterInput-Funktion in PHP, die bestimmte Zeichen ersetzt/löscht und jeden Versuch des Benutzers vereitelt, Javascript-Code durch Eingabe zu versuchen und auszuführen.

Das hat gut funktioniert. Wenn der Benutzer jedoch versucht hat, eine bösartige Eingabe zu geben, wie "+ alert (" hallo ") +", wobei sowohl die Anfangs- als auch die Endzitate enthalten sind, hat die filterInput-Funktion die führenden und spitzen Anführungszeichen gekürzt und die resultierende Zeichenfolge ist unten:

+alert("hello")+ 

wenn nun folgenden Code ausgeführt wird:

location1 = "<?= filterInput($_GET['location1']) ?>" || 0; 

PHP substitues der Funktionsaufruf mit Rückgabewert wie folgt:

location1 = "+alert("hello")+" || 0; 

Ausführung der s cript stoppt mit der obigen Zeile mit einem Fehler (fehlt; vor Aussage)

Hinweis, hätte ich nicht die Zitate getrimmt und $ _GET ['location1'] direkt verwendet, würde ich bekommen.

location1 = ""+alert("hello")+"" || 0; 

alert ("hallo") würde ausgeführt werden !!

Also, ich bin in einer Lösung. Wenn ich die Eingabe filtere, erhalte ich bei bestimmten Benutzereingaben einen JavaScript-Fehler und wenn ich die Eingabe nicht filtere, erlaube ich den Benutzern, jede Art von Javascript auszuführen.

Meine Fragen dann sind:

  • Was ist eine ordnungsgemäße und sichere Art und Weise Eingang auf dem Netz zu handhaben?
  • Ist diese Art der Benutzereingabe Sprachen (von PHP zu Javascript) ok?
  • Abgesehen davon, dass der Benutzer JavaScript ausführen kann, was andere Arten von Sicherheitsbedrohungen tun, ist dieses Stück Code anfällig?

Danke fürs Lesen !!

Bitte helfen.

+1

Warum sind Sie besorgt über Benutzer, die willkürliche JS in ihrer eigenen Sitzung ausführen? Sie können das mit Firebug usw. sowieso tun. Übliche Angriffsvektoren würden Angriffe auf serverseitige Prozesse (einschließlich PHP und irgendwelcher Datenbankdienste) oder Sitzungen anderer Benutzer (einschließlich XSS-Angriffe) umfassen. Wenn die Leute sich mit ihrem eigenen Browser herumschlagen wollen, warum dann versuchen, sie zu stoppen? Tatsächlich sehe ich in diesem Fall keine echte Notwendigkeit für eine serverseitige Verarbeitung - Sie könnten einfach Ihre init-Funktion als onClick-Handler ausführen und die Formularwerte mit JS abrufen. – steamer25

Antwort

1

Sie können versuchen, json_encode in PHP und ein eval in Javascript.

Wenn der JS auf demselben Computer ausgeführt wird, auf dem die Eingabe erfolgt, würde ich mich nicht um die Sicherheit kümmern. Ein Hacker kann seine eigene Maschine hacken, es sollte kein Problem sein.