プロが教えるわが家の防犯対策術!

XSS対策の htmlspecialchars の付けどころについて質問なのですが

POSTやGETの値をとりあえず最初に全て htmlspecialchars をして変数に入れてから使用しています
しかし最初でなくHTMLなどの出力時に htmlspecialchars をしないとダメだと他サイトでみました
よく分からなかったのですがHTMLなどに出力する最終の時その箇所だけその値に htmlspecialchars をするべきで、面倒なので最初に全てしてから使うと危険なのでしょうか



下記は htmlspecialchars をしなくても安全のようですが

if(isset($_POST["name"]){

下記の様なものは問題があるのでしょうか

$i = "id" . $_POST["name"];
if($i=="id10"){


よろしくお願いします。

質問者からの補足コメント

  • >HTMLとして出力する際に必要な処理
    有難うございます誤解をしておりました

    >出力するすべてのデータに対して必要
    入力されるものだけ気をつければ大丈夫と思っていたのですが
    下記の様な場合はもちろん駄目でしょうが

    $i = こんにちは . $_POST["x"];
    echo $i;

    例えばこちらで変数に入れた値を出力する際もなのでしょうか

    $i=10;
    echo $i;

    No.1の回答に寄せられた補足コメントです。 補足日時:2015/03/31 10:31
  • >出力しないデータをhtmlspecialcharsすること自体無駄
    有難うございます誤解しておりました

    HTML出力時に入ってきた値がコードだった場合それが機能してしまう以外で
    PHP内で実行されると誤解していました。

    $_POST["x"] = "0 == 0 or 0"
    if($_POST["x"] == 1 ){


    >変換後のデータはチェックが煩雑
    なるほどです

    No.2の回答に寄せられた補足コメントです。 補足日時:2015/03/31 10:38

A 回答 (4件)

>HTML出力時に入ってきた値がコードだった場合それが機能してしまう以外で


>PHP内で実行されると誤解していました。

なるほど、それはSQLのインジェクションですね
いまはSQLのデータ渡しはPDO経由が主流(?)なので
多少攻撃的なデータでもSQLに致命的な攻撃はしづらくなっています

PHP自体でevalなど非推奨の処理さえしなければ問題ないでしょう
    • good
    • 0
この回答へのお礼

はい
PHP内で実行されてしまうかも、と勘違いしておりました。
SQLの方はPDOを使用して気をつけたいと思います。
有難うございます。

お礼日時:2015/03/31 15:42

>例えばこちらで変数に入れた値を出力する際もなのでしょうか



変数に代入と、HTML出力の間に他の処理が挟まった場合に、その間に変数の値が安全であり続けるということは自明ではないので、それを保証する必要がありますが、それは面倒ですし、不必要な努力です。
HTML出力時に変換することにしていれば、安全なのは自明で、安全の保証に手間が掛かりません。

「自分が作ったプログラムを自分だけが利用して被害も自分だけが被る」のであれば自分が「このプログラムは安全だ」と確信を持てれば良いので、他人に対して品質保証するということを考えなくてもいいのですが。

HTMLを出力する他にも、
・何らかの理由で動的にSQLを組み立てなければならないケース
・ファイル名を指定してファイルにアクセスするケース
・OSコマンドを実行するケース
・JavaScriptを生成出力するケース
などなど、対処が必要なケースはいくらでもありますが、それぞれそれをする直前にパラメータを変換して無害化するのが正しいやり方です。$_GET/$_POSTを参照する時点で上記すべてへの対処をするのは不可能です。
    • good
    • 0
この回答へのお礼

>間に他の処理が挟まった場合
出力直前に無害化が確実という事ですね

有難うございます。

お礼日時:2015/04/01 09:53

ひとつは先にhtmlspecialcharsをすると変換後のデータはチェックが煩雑


たとえば受け取ったリクエストの完全一致、部分一致、長さのチェックなど
先にやるほうが処理が多くろくなことがない
(SQLで検索するときなど一致しなくなるし)

<?PHP
$test1=isset($_REQUEST["test1"])?htmlspecialchars($_REQUEST["test1"]):null;
if($test1==htmlspecialchars("<hoge>")){
print "test1 ok";//チェックしたいデータもhtmlspecialcharsしないと一致しない
};
?>
<form>
test1:<input type="text" name="test1" value="&lt;hoge&gt;">
<input type="submit" value="go">
</form>
<?php
$test2=isset($_REQUEST["test2"])?htmlspecialchars($_REQUEST["test2"]):null;
if(preg_match("/&/",$test2)){
print "test2 ok"; //"<"は"&lt"なので"&"にマッチする
};
?>
<form>
test2:<input type="text" name="test2" value="&lt;">
<input type="submit" value="go">
</form>

もうひとつは、受け取ったリクエストは必ずしも出力するわけではないので
出力しないデータをhtmlspecialcharsすること自体無駄
この回答への補足あり
    • good
    • 0

危険と言うより、htmlspecialcharsは、HTMLとして出力する際に必要な処理なので、他のところで行うと混乱の元です。

バグを生む元になりかねません。

$_GETや$_POSTから得たデータだけをhtmlspecialcharsすればいいと思っていませんか?
HTMLとして出力するすべてのデータに対して必要ですよ。
この回答への補足あり
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!