タグ: エスケープ

PHP文字列のエスケープ

PHP文字列をテキストとして出力したい場合もあります。PHPの文字列型はバイナリセーフなのでどのようなデータでも保存可能ですが、プログラム中でPHP変数をPHPのテキスト(リテラル)として出力するにはaddslashes()によるエスケープ処理が必要です。

【重要】エスケープ/API/バリデーション1は出力先に合った方法でないと意味がないです。一口にHTMLと言っても複数の”コンテクストがあります。

  • JavaScript(識別子、変数など)、CSS、タグ属性名、タグ属性値(URIコンテクストに特に注意。BASE64、JavaScriptを使う場合もある)

があります。
SQLクエリと言っても

  • 引数(更にLIKE、正規表現、JSON、XMLなどに別れる)、識別子、SQL語句

などがあります。全てのテキストインターフェースにコンテクスト2があります。
それぞれの”コンテクスト
に適切なエスケープ/API/バリデーションを利用しなければ意味がありません

もっと読む

PHPのJSONのエスケープ

追記:最近のOWASPガイドの更新でJavaScript文字列はUnicodeエンコードで安全性を確保するよう変更されました。元々このブログでもUnicodeエスケープのまま利用するように書いています。他の言語のユーザーはUnicodeエスケープを利用しましょう。PHPもASCII領域の文字をUnicodeエスケープするようにした方が良いと思います。これは提案して実現するように努力します。

JSONはJavaScriptのオブジェクトや配列を表現する方式でRFC 4627で定義されています。メディアタイプはapplication/json、ファイル拡張子はjsonと定義されています。

PHPにJSON形式のデータに変換するjson_encode関数json_decode関数をサポートしています。

JSON関数がサポートされている話は簡単!となれば良いのですが、 いろいろ考慮しなければならない事があります。

TL;DR; PHPのjson_encode()を安全に利用する方法

json_encode()を利用する場合

$json = json_encode($data, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT);

と利用します。これでもまだ最適なエンコード方式とは言えませんが、デフォルトとして最低限必要なオプションが

JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT

です。

JSONデータの文字エンコーディングは基本UTF-8です。UTF-8文字データは”予めバリデーションしておく”必要があります

もっと読む

RailsのJavaScript文字列エスケープ

RailsはJavaScript文字列エスケープメソッドをサポートしています。JavaScript文字列エスケープのエントリで様々な議論があったようです。弊社ではRailsアプリのソースコードも検査しているので、参考としてRailsのソースコードを確認したことを追記をしたました。Rails開発者に直して頂きたいので独立したエントリにしました。

参考:

もっと読む

XPathクエリ(2)

XPathクエリ(1)の続きです。

現在のPHPのXPathクエリの問題はXPath 1.0である事です。通常の仕様書であれば特殊文字のある文字列の場合はエスケープ方法やエスケープAPIが定義されています。エスケープ方法が定義されていなければ「特殊文字を入力することができない」からです。エスケープ方法が無い場合は「エスケープが必要ないAPI」を用意すべきです。

しかし、XPath 1.0ではエスケープ方法もエスケープAPI、エスケープが必要ないAPIも定義されていません。このような場合、仕様を実装しているライブラリの実際の挙動を確認して利用することになります。PHPのSimpleXML、XMLXpathクラスの場合はlibxml2を利用しているので、libxml2の動作を確かめる必要があります。

もっと読む

SQL識別子のエスケープ

SQLのリテラルはエスケープが必要であることは広く認知されていると思います。しかし、識別子のエスケープはあまり広く認知されていないように思います。

PostgreSQLの場合、識別子のエスケープAPI(libpqのPQescapeIdentifier)が提供されておりPHPでもpg_escape_identifier()として利用できます。PostgreSQLの場合は”(ダブルクオート)で識別子を囲むことにより、ダブルクォート無しでは利用できない文字(例えば日本語)も識別子に利用できるようになります。
もっと読む

LDAPエスケープ – PHPのldap_escape関数

OWASP TOP10の1位のセキュリティ脅威はインジェクションです。

https://www.owasp.org/index.php/Top_10_2013-A1-Injection

SQLインジェクション、コマンドインジェクションはリファレンスとして掲載されていますが、何故かLDAPインジェクションは掲載されていません。しかし、OWASPの別の文書では簡単に解説されています。

もっと読む

知っているようで知らないプリペアードクエリ

PostgreSQL Advent Calender 2012用のエントリです。

PostgreSQLや他のDBMSを利用していてプリペアードクエリを知らない方は居ないと思いますが、プリペアードクエリを使いこなす為のTIPSです。役に立つかどうか、は多少疑問ですが、内部がどうなっているか知っているとなにかの役に立つかも知れません。時間的制約で多少端折っているところは勘弁してください。

完全なSQLインジェクション対策は以下を参照してください。

完全なSQLインジェクション対策

もっと読む

PostgreSQL 9.0から使える識別子とリテラルのエスケープ

PostgreSQL Advent Calender用のエントリです。

エスケープ処理が必要なのにエスケープ用のAPIが無い状態は良くありません。エスケープしないために動かないのはまだ良い方です。エスケープが必要なのにエ スケープをしなくても動いてしまい、セキュリティ上の問題となる場合もあります。全てのアプリケーション・ライブラリはエスケープが必要なデータに対するAPIを持っておくべき です。今回はPostgreSQL 9.0から追加されたエスケープ関数を紹介します。

PostgreSQL使い始めて最初の頃に気づくのはuserなどの予約語がフィールド名に使えない事かも知れません。例えば、

yohgaki@[local] test=# CREATE TABLE user (name text);
ERROR:  syntax error at or near "user"
行 1: CREATE TABLE user (name text);

と失敗してしまいます。これはuserがPostgreSQLの予約語であるためSQL文の識別子として使用できないからです。MS Accessからデータベースに入った方には識別子に日本語を使う場合も多いので、PostgreSQLでは日本語のテーブル名やフィールド名はそのままでは使えない事に気が付いた方も多いのではないでしょうか? もっと読む