カテゴリー: PHP Security

そもそもエスケープとは何なのか?

まずエスケープ処理について全て書こう、ということでPHP Securityカテゴリで様々なエスケープ処理について書いてきました。しかし、「エスケープ処理とは何か?」を解説していなかったので解説します。

エスケープ処理は文字列処理の基本中の基本です。

「エスケープは要らない、知る必要もない」という意見を稀に聞きますが、プログラムに於ける文字列処理とその重要性を理解していないからでしょう。全ての開発者はエスケープ処理の必要性を理解し、確実かつ適切にエスケープできなければなりません。
もっと読む

PHP文字列のエスケープ

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

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

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

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

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

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

もっと読む

いまさら聞けないWebアプリセキュリティの基本ルール

C言語の最も重要なセキュリティの基本ルールは「メモリをきっちり管理する」です。もちろん他にもプログラミングをする上で注意しなればならない事は山ほどありますが、C言語でプログラミングする上で最も基本的なセキュリティのルールは「正確なメモリ管理」です。

Webアプリを作る上でのセキュリティの基本ルールは何でしょうか?

今回はWebアプリセキュリティはもっとシンプルに考えよう!という話です。

 

もっと読む

フィルター/デコード時のセキュリティ対策の鉄則

ブラックリスト型(サニタイズ型)のセキュリティ対策クイズ 解答編 ではバリデーション時の注意点をまとめに書きました。

ホワイトリスト型のバリデーションを行う場合でも以下の項目に注意しなければなりません。

  • 特殊な意味を持つ文字を許可する場合、細心の注意を払う
  • そもそも特殊な意味を持つ文字は許可しない方が良い
  • 絶対の自信が無いのであれば、特殊な意味を持つ文字を許可してはならない

ブラックリスト型(サニタイズ型)のセキュリティ対策クイズ 解答編 でパストラバーサルを禁止するようなフィルター処理(ブラックリスト型サニタイズ処理)は基本的には行うべきではありません。しかし、どうしてのフィルター/デコード処理が必要になる場合があります。
もっと読む

ブラックリスト型(サニタイズ型)のセキュリティ対策クイズ 解答編

昨日のエントリのクイズです。今回はその解答です。もう一度問題を書いておきます。

ブラックリスト型のセキュリティ対策は、どうしても仕方がない限り使ってはなりません。以下のサニタイズコードは “../” 、”..” を無効な文字列として取り除きます。このサニタイズコードを回避しカレントディレクトリよりも上の階層からのパスへアクセスするパストラバーサルを行う文字列を考えてみて下さい。(/etc/passwdなどにアクセスできる文字列を考えて下さい)

レベル1

<?php
if ($_GET['filename']{0} === '/') {
   // 絶対パスは無効
   die('無効なファイル名が送信されました。');
}
// トラバーサルに利用される"../", ".."を削除
// カレントディレクトリ以下のファイルだけ読み込む?
$safe_path = str_replace(array('../', '..'), '', $_GET['filename']);
readfile($safe_path);

簡単すぎた方はレベル2をどうぞ。以下のコードはブラックリスト型チェックでパストラバーサルに利用される “.” が1つしか無いことでセキュリティを維持しようとするコードです。

レベル2

<?php
if ($_GET['filename']{0} === '/') {
   // 絶対パスは無効
   die('無効なファイル名が送信されました。');
}
if (strpos($_GET['filename'], '.') !== strrpos($_GET['filename'], '.')) {
   // トラバーサルに利用される"."は1つしか許さない
   die('無効なファイル名が送信されました。');
}
// カレントディレクトリ以下のファイルだけ読み込む?
readfile($_GET['filename']);

まだ解いていない方は少しだけ時間を使って考えてみて下さい。

もっと読む

PHPスクリプトアップロード対策

今日はWordPressプラグインとWebサーバー設定の脆弱性を例にスクリプトアップロード対策を紹介します。

ファイルアップロードをサポートしているシステムの場合、PHPスクリプトとして実行されてしまう拡張子を持つファイルをアップロードされてしまうとサーバーを乗っ取られてしまいます。

参考リンク:

 

もっと読む

APIとエスケープ/バリデーションとセキュリティ

今回はセキュリティ対策におけるAPIとエスケープ/バリデーションをどう考えるかの話です。

Cプログラマになろうとしているプログラマにメモリ管理を教えないことは考えられません。メモリ管理を考えなくても文字列の処理をしたりするライブラリなどもありますが、メモリ管理をあまり考えなくても良いAPIさえ使っていればOK、メモリリークもValgrindでチェックしてレポートされなければOK、と考えているプログラマが作ったプログラムが安全である可能性は低いでしょう。

言語やプラットフォームの基本中の基本を避けて通っては安全なプログラムの構築が難しくなるだけです。

安全なプログラムを作るために「プログラマに何を教えるべきか?」が今日のテーマです。

もっと読む

SQLのエスケープ

SQLにエスケープなんて必要ないと考えている方も居るとは思いますが、現実にはエスケープを知っておくことは必須と言っても構わないと思います。

既にSQL識別子のエスケープについては書きましたが、今回はSQLエスケープというよりは安全にSQLデータベース利用する話です。先ずはエスケープの話を全て終わらせよう、と思っているのですがSQLエスケープのエントリが無いので作りました。私のブログを読んでいる方はエスケープ処理、プリペアードクエリの利用方法などはよくご存知だと思うのでここの部分は省略しています。

もっと読む

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文字データは”予めバリデーションしておく”必要があります

もっと読む

Webアプリの入力はバリデーションできない、という誤解

Webアプリの入力はバリデーションできない、と誤解している方は少なく無いようです。システム開発に関わる人でなければ誤解していても構わないのですが、システム開発者が誤解していると安全なシステムを作ることは難しいでしょう。

Webアプリの入力はバリデーションできない、と誤解している開発者にも理解できるよう噛み砕いて解説してみます。

もっと読む