私は出発地と目的地のアドレスを入力し、ルートを示す地図とともに道順表(道順情報を与える)を取得する道順サービスに取り組んでいます。あなたはそれがgetdirections.phpとしてシステム名にこのコードを試してみる場合はユーザ入力、PHP、Javascript、セキュリティ
<!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&v=2&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>
:以下
は、完全なソースコード(getdirections.php)です。あなたが変更する必要がある唯一のものは、Googleマップのapiキーです。キーhereを得ることができます。
あなたがkeyパラメータに入れて、あなたの鍵を生成した後は、(便宜上、以下の行を再現):
<script src="http://maps.google.com/maps?file=api&v=2&sensor=false& amp;key=[Your key here]"
type="text/javascript">
を上記のコードから分かるように、私はPHPを介して入力を取得し、JavaScriptで処理を行います。今、私はユーザーがどんな種類の入力(javscript、危険なHTMLなど)で逃げるのを望んでいません。私はPHPでurlencode関数を使ってみました。ただし、コード化されたユーザー入力はJavaScriptコードでは受け入れられず、入力が良好であっても失敗します。
私はこの問題を回避するために、特定の文字を置き換えたり削除したりするためにPHPでfilterInput関数を書いています。ユーザーが入力を介してJavaScriptコードを試して実行しようとする試みを阻止します。
これはうまくいきました。しかし、ユーザーが悪意のある入力をした場合、たとえば "+ alert(" hello ")+"のように開始と終了の両方の引用符を含めると、filterInput関数は先頭と末尾の引用符をトリミングし、結果の文字列は以下のようになります。
今+alert("hello")+
以下のコードが実行される:Sの
location1 = "+alert("hello")+" || 0;
実行:
location1 = "<?= filterInput($_GET['location1']) ?>" || 0;
PHPは、以下のようにその戻り値を持つ関数呼び出しをsubstitues criptは上の行でエラーで停止します(欠落しています。前のステートメント)
注:私は引用符をトリムしていないし、$ _GET ['location1']を直接使用しました。
location1 = ""+alert("hello")+"" || 0;
alert( "hello")が実行されます。
ですから、私は修正を受けています。私は入力をフィルタリングする場合、私は特定のユーザー入力でJavaScriptエラーを取得し、私は入力をフィルタリングしない場合は、ユーザーが任意の種類のJavaScriptを実行することができます。
私の質問は、以下のとおりです。
- ウェブ上で入力を処理するために、適切かつ安全な方法は何ですか?
- この種のユーザー入力クロス(PHPからJavascriptへ)の言語はOKですか?
- javascriptを実行できるユーザー以外に、この脆弱なコードは他の種類のセキュリティ上の脅威が何ですか?
お読みください!
助けてください。
なぜ、自分のセッションで任意のJSを実行しているユーザーが心配ですか?とにかくFirebugなどでそれらを行うことができます。通常の攻撃経路には、サーバー側のプロセス(PHPやデータベースサービスを含む)や他のユーザーのセッション(XSS攻撃を含む)への攻撃が含まれます。人々が自分のブラウザを混乱させたい場合、なぜそれらを止めようとしますか?実際、この場合はサーバー側の処理が本当に必要なのですが、init関数をonClickハンドラとして実行し、JSでフォーム値を取得するだけで済みます。 – steamer25