HOME > 開発メモ > PHPで呼び出した文字列内の特殊文字で、JavaScriptエラーが出る場合の対処法
2013/02/15 (2016/09/14更新) タグ: ,

PHPで呼び出した文字列内の特殊文字で、JavaScriptエラーが出る場合の対処法

例えばPHPにてデータベースに入っている文字列を呼び出して、その文字列をJavaScriptで使おうとした際に、「’」シングルクォーテーションや「”」ダブルクオーテーションなどが入っていると、上手く動作しないことがあります。

SPONSOR

例えば、JavaScriptの変数にvar a=[“<? echo $data[0]; ?>”,”<? echo $data[1]; ?>”];のようにしていた場合、$data[0]の中にダブルクオーテーションがあれば、動きません。こんな時は、あらかじめPHP側でHTMLエンティティに変換すると解決します。

$data[0]=preg_replace("/&/","&",$data[0]);
$data[0]=preg_replace("/'/","'",$data[0]);
$data[0]=preg_replace("/"/",""",$data[0]);

2013/3/4追記

セキュリティコンサルトの徳丸さんより、XSSのご指摘をいただきました。ありがとうございます。

たしかに、以下のコードは脆弱性がありました。

<?
$data[0]="</script><script>alert(1)//";
$data[0]=preg_replace("/&/","&amp;",$data[0]);
$data[0]=preg_replace("/'/","&#039;",$data[0]);
$data[0]=preg_replace("/"/","&quot;",$data[0]);

$data[1]="');alert('XSS";
?>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script>
function test(){ }
var a=["<? echo $data[0]; ?>"];
</script>
</head>

<body>
<a href="javascript:test('<? echo htmlspecialchars($data[1]); ?>')">リンク</a>

</body>
</html>

これをブラウザ開くと、Scriptが実行されてしまいます。最初にhtmlspecialcharsを使うことを考えたのですが、上記のリンクをクリックすると分かるように、これもScriptが実行されてしまい、安全ではありませんでした。

<?
// 文字列をすべて uXXXX 形式に変換
function unicode_escape($matches)
{
	$u16 = mb_convert_encoding($matches[0],'UTF-16','UTF-8');
	return preg_replace('/[0-9a-f]{4}/','u$0',bin2hex($u16));
}

// 英数字とマイナス、ピリオド以外を uXXXX 形式でエスケープ
function escape_js_string($s)
{
	return preg_replace_callback('/[^-.0-9a-zA-Z]+/u','unicode_escape',$s);
}

$data[0]="</script><script>alert(1)//";
$data[1]="');alert('XSS";
?>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script>
function test(){ }
var a=["<? echo escape_js_string($data[0]); ?>"];
</script>
</head>

<body>

<a href="javascript:test('<? echo htmlspecialchars(escape_js_string($data[1])); ?>')">リンク</a>

</body>
</html>

そして、これが解決策です。徳丸さんが書かれている「体系的に学ぶ 安全なWebアプリケーションの作り方」113Pに記載されているUnicodeエスケープを使っています。これで不正なスクリプトは実行出来ません。unicode_escapeとescape_js_stringを使って、英数字以外を/uXXXXというUNICODE形式にエスケープしています。

さらに詳しくは以下、徳丸さんの本は詳しくて参考になります。

この記事をシェアする

イリテクの最新記事をお届けします

イリテクの最新情報をチェック!
  • follow us in feedly
    RSSで最新記事を読む

イリテクで開発したサービス

請求書作成業務をもっとかんたんに。見積請求書の作成だけでなく、郵送代行、メール送信、PDFダウンロードなどバックオフィスを効率化。

詳しくはこちら

こちらの記事もおすすめです

SPONSER

記事を書いている人
入江 慎吾
イリテク(株)代表。webシステム、デザイン、iOSアプリ開発に携わって15年目。ディレクションもデザインもやるプログラマ。複数の企業と専属エンジニア契約中。自社で見積請求CLOUD PAPER運営。iPhoneアプリ全国総合ランキング3位を記録。イリテクブログは月間約5万PV。(もっと詳しく
SPONSOR
最新記事
Facebook
Twitter