連想配列のキーも値もまとめてhtmlspecialchars()でサニタイズする関数の作成解説
2017/06/16
連想配列のキーも値もまとめてhtmlspecialchars()でサニタイズ
PHPの配列・連想配列のキーと値を一括してサニタイズする関数
PHPの配列の値に対して一括で htmlspecialchars()関数を実行し、値のサニタイズ(無害化、無毒化)を行う方法を解説します。
また、配列の値だけではなく、連想配列のキーに対してもサニタイズ(無害化、無毒化)を行っています。
PHPの配列・連想配列のキーと値を一括してサニタイズする関数のサンプルソースコード
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
// 連想配列をサニタイズする関数 function mysanitize ( $input ) { $_input = array (); foreach ( $input as $key => $val ) { if ( is_array ( $val ) ){ $key = htmlspecialchars ( $key ); $_input[$key] = mysanitize ( $val ); } else { $key = htmlspecialchars ( $key ); $_input[$key] = htmlspecialchars ( $val ); } } return $_input; } // 入力される連想配列 $array = array ( "aaa" => "aaa", "bbb" => "<a href=bbb>bbb</a>", '<a href="#ccc">ccc</a>' => '<a href="#ccc">ccc</a>' ); $array_h = mysanitize ( $array ); // サニタイズした結果を表示 print_r ( $array_h ); |
PHPの配列・連想配列のキーと値を一括してサニタイズする関数の解説
配列(連想配列)を引数に関数を実行すると、配列のキーと、値に対して一括して htmlspecialchars()関数を実行し、サニタイズ(無害化、無毒化)を行った結果を返す関数です。
クロスサイトスクリプティング(XSS)の対策のために htmlspecialchars()関数でサニタイズ(無害化、無毒化)を行いますが、この関数では、配列(連想配列)に対しても一括して処理を実行することができます。
見てもらえばわかると思いますが、foreach文でグルグル回しながら、入力値が配列であれば、改めて「mysanitize()」関数を呼び出し、さらに foreach文を実行して階層を深堀していく、という処理になっています。
配列でなければ「htmlspecialchars()」関数でサニタイズを実行します。
また、連想配列のキーもサニタイズを実行しています。
連想配列のキーも値もまとめてサニタイズする処理を作った経緯
この記事を書くきっかけになったのは、下記のツールを作成したことでした。
JSONの値のデコードツール
XMLを配列に変換するツール
そして、そのツールの解説記事として下記の記事を書きました。
JSON形式の値を配列形式に変換・PHPでは json_decode()、json_encode()
XML形式の値を配列形式に変換・PHPでは simplexml_load_string()
SMTP Mailerでスパム判定回避。WP Mail SMTPで発生する送信エラーも対応
作成したツールは、入力された JSON形式のデータ、XML形式のデータを配列に変換するという単純なツールなのですが、単純なツールだからと言ってもセキュリティホールを放置するわけにはいかないわけですので、サニタイズの対応を行うことにしました。
ですが、簡易的なツールですので、「json_decode()」関数、「simplexml_load_string()」関数で生成した配列を、そのまま「print_r()」で出力しているだけのツールでした。
そのため、「json_decode()」関数、「simplexml_load_string()」関数で生成した配列を何とかまとめてサニタイズを行う方法を実装しないと、JSON形式、XML形式の変換ツールなのにサニタイズの処理の方が大きくなってしまう、と思ったわけです。
そして出来上がったのが、このサニタイズの関数です。
まぁ、結果的にはサニタイズ処理の方が大きな処理ですし、実装にははるかに悩みましたが...
array_map()を利用してサニタイズする方法
最初は、下記のようなサニタイズの処理を書いていました。
ですが、これだと配列の値のサニタイズは問題なくできるのですが、連想配列の場合は、キーに対しては全く無防備だということが確認できました。
1 2 3 4 5 6 7 8 9 10 11 12 |
function mysanitize ( $string ) { if ( is_array ( $string ) ) { return array_map ( "mysanitize", $string ); } else { return htmlspecialchars ( $string, ENT_QUOTES ); } } $array = array ( "aaa" => "aaa", "bbb" => "<a href=bbb>bbb</a>", '<a href="#ccc">ccc</a>' => '<a href="#ccc">ccc</a>' ); $array_h = array_map ( 'mysanitize', $array ); print_r ( $array_h ); |
そのため、下記の様に修正をしてみました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
function mysanitize ( $key, $value ) { if ( is_array ( $value ) ) { return array_map ( "mysanitize", array_keys ( $value ), array_values ( $value ) ); } else { $output[htmlspecialchars ( $key, ENT_QUOTES )] = htmlspecialchars ( $value, ENT_QUOTES ); return $output; } } $array = array ( "aaa" => "aaa", "bbb" => "<a href=bbb>bbb</a>", '<a href="#ccc">ccc</a>' => '<a href="#ccc">ccc</a>' ); $array_h = array_map ( 'mysanitize', array_keys($array), array_values($array) ); print_r ( $array_h ); |
この方法でも一応、連想配列のキーもサニタイズできてはいますが、結果が想定しているものとは違う状態になりまして、実用には耐えうることができないと判断するに至りました。
「array_map()」関数は「指定した配列の要素にコールバック関数を適用する」関数ですので、連想配列のキーに対する処理は想定していないからであろう、と思います。
もう少しどうにかすれば...という感じもしましたが、下記のサイトに『「array_map()」関数を使うより、foreach文を使おう!』と書いてありましたので、上記の処理はあきらめて、記事の最初に載せた foreach文で実行する方法を採用することにしました。
http://qiita.com/tadsan/items/bfd1acb7c35a9a6fe452
他にこんな簡単な方法があるよ!というのがあると教えていただけると幸いです。
GoogleAdwords
GoogleAdwords
この記事が参考になったと思いましたらソーシャルメディアで共有していただけると嬉しいです!
関連記事
-
XML形式の値を配列形式に変換・PHPでは simplexml_load_string()
XMLとは「Extensible Markup Language」の略でテキストベースのデータフォーマット。XMLをPHPで配列に変換するWebツールの紹介とその処理「simplexml_load_string()」関数についての解説。
-
PHPで配列の値をダブルクオーテーションで囲んでimplodeでカンマ区切りにする方法
PHPで配列の値を、preg_replace関数でクォーテーションで囲み、implode関数で「,(カンマ)」で区切ってテキスト化する方法。この方法であれば配列が空でも分岐の処理は必要なし!
-
PHPのcURLでAPIやWebサイトへのアクセス方法。file_get_contentsとの比較
PHPからWebサイトにアクセスしてHTMLを取得、APIにアクセスして情報を取得する場合は、cURLがオススメ。file_get_contentsでも可能だがエラー制御に難がありトラブルのもとになる。
-
ECCUBEでカード決済NGの受注情報をマイページ購入履歴に表示しない方法解説
ECCUBEでカード決済に失敗しても購入履歴一覧に注文情報(受注情報)が表示される問題への対処方法を解説。受注情報レコードの作成の流れとステイタスについても解説。
-
ファイル変更だけ!ECCUBEの本番から開発環境をコピーする手順を解説
ECCUBEを本番から開発環境をコピーする際の手順を解説。PGMメンテに必要な開発環境を構築する手順を解説。ECCUBEの仕組みは簡単なので作業は5分ほど。
-
複数銘柄を指定して株価チャートを一覧するツール公開
入力銘柄の5日間、3か月間、6か月間、1年間、2年間の株価チャートを一覧表示しますのでチャートで売買判断をするのに最適です。
-
Smartyの修飾子regex_replaceで正規表現の後方参照・PHPではpreg_replace
ECCUBEで使われているSmartyで文字列を正規表現で置換し後方参照で値を利用する装飾子regex_replaceの解説です。細かな条件がありますので注意が必要です。
-
ECCUBEの商品一覧ページのSEO対策!rel=”next” rel=”prev”を設定
Googleは関連あるページはその旨明示するよう求めています。ECCUBEの商品一覧ページでその求めに応じるための「rel=”next”」「rel=”prev”」について解説します。
-
ECCUBEの管理画面のSSL設定をインストール後に変更する方法
ECCUBEをインストールした後から管理画面のSSL設定を変更する方法を解説します。config.phpファイルのHTTPS_URLとADMIN_FORCE_SSLの値を変更すればOK。
-
Smartyのテンプレート内の処理で計算、加工をする方法
Smartyのテンプレート上で変数を計算する、加工する方法を解説します。