ユーザーが html フォームに " または \ を入力すると問題が発生します
入力されたテキストは、html コンテンツおよび html 属性コンテキストでユーザーに再度表示されます。
次のデータフローがあります。
- jQuery フォームの行入力
- $_POST
- html 属性のエスケープ: 関数は、html エンティティまたは 16 進エンティティ (
"
または\
)でエスケープします。 - PHPのjson_encode
- ヒューズを飛ばす未知の JavaScript 干渉
- jquery ajax コールバックの json_parse
目標は、入力したテキストとまったく同じテキストをユーザーに表示することですが、xss 攻撃を回避するために適切にエスケープすることです。
最初に得たのは、何らかの理由で $_POST にスラッシュが追加されたことです。そのため、最初にストリップスラッシュを使用します。これで一重引用符のすべてが解決されましたが、ユーザーが " または \ を入力すると、それでも壊れます。
問題は、json_parse がデータを取得する前に JavaScript が何らかのデコードを行うことです。16 進エスケープを \ と " に戻し、json_parse を強制終了します。
したがって、ステップ 4 と 5 の間で htmlspecialchars( $data, NO_QUOTES, 'utf-8' ) を使用する場合、アンパサンドを にエンコードすると&
、javascript のデコードが中和されるはずですが、そうではありません。&
" と 16 進エンコーディングをデコードしている間、何らかの理由でデコードしません...
どこが間違っていますか?javascipt が何をデコードし、それを PHP から中和するかを正確に知る方法はありますか?
半日を無駄にした後、私が今していること:
onsuccess ハンドラーがデータを取得する前にデータに干渉するのは、おそらく jQuery の問題だと思います。今はそれを掘り起こして殺す時間がないので、文字列を変換しないようにするためだけに 3 つの文字列変換を意味するハックでこっそり通り過ぎていますが、開発者の時間はここではまれな商品です.
PHPで:
// due to a problem with the jQuery callback code which seems to decode html entities and hex entities except for &
// we need to do something to keep our data intact, otherwise parse_json chokes on unescaped backslashes
// and quotes. So we mask the entity by transforming the & into & here and back in js.
// TODO: unit test this to prevent regression
// TODO: debug the jQuery to avoid this workaround
//
// echo json_encode( $response );
echo preg_replace( '/&/u', '&', json_encode( $response ) );
parse_json の前の js で:
// due to a problem with the jQuery callback code which seems to decode html entities and hex entities except for &
// we need to do something to keep our data intact, otherwise parse_json chokes on unescaped backslashes
// and quotes. So we mask the entity by transforming the & into & here and back in js.
// See function xxxxxx() in file xxxxx.php for the corresponding transformation
//
responseText = responseText.replace( /&/g, '&' );
現時点では単体テストを書く気になれませんでしたが、それを破ることはできないようです。
本当の問題は、同じ結果を得ながら、どうすれば不要な変換をノックアウトできるかということです。