Hatena::ブログ(Diary)

hoshikuzu | star_dust の書斎 このページをアンテナに追加 RSSフィード Twitter

hoshikuzu|star_dustの日記について

書く内容の方針とかはフラフラしているのです。あまり考えていないかも知れません。面白いなぁと思うこと、大事なことだなぁと思うことを書いています。あんまり悲しいことは書かない主義。

 | 

2006-02-11 このエントリーを含むブックマーク このエントリーのブックマークコメント

data uri変換機

これはそそります。なるほどぉ。

data:text/html;charset=utf-8;base64,aHR0cDovL2xhLm1hLmxhL21pc2MvanMvZGF0YS5odG1s

FirefoxでWindowsのクリップボードに値を設定する方法

上を踏まえて。

Opera8.5でもいけてる気がします。

外部のサーバを利用せずにHTML単体でいけているのは、dataスキームが有効だからですね。IE7ではまだdataスキームって有効じゃないのでしたっけ?

え?オーバーフローするかって?しないでしょ(笑)

クリップボードに書き込む動作をするActionScriptを埋め込んだswfファイルをdataスキームで表現しているのですね。

ペーストするもうひとつの方法

To paste the contents just use the SHIFT-INSERT keys instead of the ol' CTRL-V.

FirefoxでCTRL-Vが出来ないと騒ぎになったことってあるんでしたっけ?裏技でSHIFT-INSERTだとOKだったみたいですけど。

PHP 利用時に Shift_JIS で addslashes() によるエスケープ処理に SQL インジェクション可能な穴

addslashes() による SQL 文字列のエスケープ回避問題

対策としては、Prepared Statement を使う、または、mysql_real_escape_string() などのデータベース専用のエスケープ関数を使用するという方法がありそうです(実際には試していませんので、確認した方が良いと思います)。

addslashes() による SQL 文字列のエスケープ回避問題::t_komuraの日記

So what can you do? The solution is to use prepared statements, which are supported by nearly all PHP database extensions with the notable exceptions of MySQL (ext/mysql) and SQLite2 (ext/sqlite). So, to be on the safe side, I'd recommend using the PDO interface to talks with those databases or in the case of MySQL using the newer MySQLi (ext/mysqli) extension. Those interfaces provide prepared statement support, which allows for separation between query structure and the query parameters. It should be noted that while PDO does emulated prepared statements for older versions of MySQL that do not support them natively, emulation is still prone to the same kind of issues demonstrated here and in Chris’ article. Therefore for security reasons you should definitely consider upgrading to a more modern version of MySQL and SQLite (SQLite 3).

mysql_real_escape_string() versus Prepared Statements :: iBlog - Ilia Alshanetsky

PHPでは、一部のマルチバイトエンコーディングにおいて、addslashes()を使っているとSQLインジェクションが発生しかねないよ、はてどうしましょう、というお話。

Chris Shiflett 氏が仰ることでは、addslashes()は使わずに、mysql_real_escape_string()を使いましょうと。そこへ Ilia Alshanetsky 氏が、いやいや、mysql_real_escape_string()でも駄目で、Prepared Statements を使いましょう、と言っているような気がします。一方日本でもこの現象について触れている文書があります。

たとえ大規模案件でも発生するSQL Injection(SQLインジェクション:SQLの挿入)。SQLインジェクションとはリクエストのパラメータにSQL文を与えてSQLデータベースを不正に操作する攻撃、またはその攻撃を可能にする入力値の未チェックの脆弱性のことをいいます。

これを避けるための処理にaddslashesというのがあります。が、addslashesだといろいろと問題が起こったりします。(SJISの5C問題とか)

SQLインジェクション防止 DB_common::quoteSmart - PHP::PEAR - dozo PukiWiki

今のところマニュアルでは以下のようになっているのですね。

  • データベースに渡される数値以外のユーザ入力を データベース固有の文字列エスケープ関数 (mysql_escape_string(), sql_escape_string(), など) でクオートしてください。 データベース固有の文字列エスケープ機能が利用できない場合、 addslashes() および str_replace()関数が利用できるでしょう。 (データベースの型に依存) 最初の例を参照 してください。前期の例が示すように、クエリの静的な部分をクオート するだけでは充分ではなく、簡単にクラックされてしまう可能性があ ります。
PHP: SQLインジェクション - Manual

Ilia Alshanetsky 氏が言うように、データベース固有の文字列エスケープ関数やaddslashes()が駄目で、Prepared Statements を使いなさいよ、というのは、やっているところ、どのくらいあるのかなぁ。

2006/02/13追記

結論から言うと、Shift_JISを素直に使っている限り、addslashes()は駄目(Chris Shiflett氏)、mysql_real_escape_string() は駄目(Ilia Alshanetsky氏)、一部のPrepared Statements すらも駄目(id:jrofbyrsさん)、ということらしいです。

また、id:jrofbyr さんから以下のようなコメントをいただきました。MySQL は手元の環境にインストールしていませんので、確認できないのですが、mysql_real_escape_string() でも PEAR の Prepared Statement でもエスケープされない場合があるそうです。

mysql_real_escape_string()でもSET NAMES sjis;等を実行した後に使うと2バイト目の0x5C文字がエスケープされないようです。PEAR::DBのDB_common::prepare() ではMySQL使用時は内部でmysql_real_escape_string()が使われるので、エスケープされない場合がありました。確か環境は PHP 4.4.1/MySQL 4.1.12です。SET NAMES binary;でなんとか回避してます。

また、PostgreSQL でも SET client_encoding TO 'SJIS' を実行するとこの問題の影響を受けることを確認しました

addslashes() による SQL 文字列のエスケープ回避問題::t_komuraの日記

安全な対処方法としては Shift_JIS などの文字の最後のバイトに \ が含まれる可能性のある文字コードを使用しないことです。

addslashes() による SQL 文字列のエスケープ回避問題::t_komuraの日記

以上で追記終わりです。

magic_quotes_gpcディレクティブ

magic_quotes_gpcディレクティブをONにしていると、ほとんど至るところ、自動的にaddslashesしているようなものですが…その辺どうでしょうか?やばくないですか?元々、magic_quotes_gpcディレクティブはOFFでというのが激しく推奨されているところではありますが。

マジッククオートは、PHPスクリプトに入力されるデータを 自動的にエスケープする機能です。 コードでは、マジッククオートをオフにして 実行する際必要な時にデータをエスケープすることが望まれます。

PHP: マジッククオート - Manual

オンの場合、全ての' (シングルクオート), " (ダブルクオート), \ (バックスラッシュ)およびNULL 文字がバックスラッシュで自動的にエスケープされます。 これは、addslashes() の機能と同じです。

PHP: マジッククオート - Manual
magic_quotes_gpc
HTTPリクエストデータ(GET, POST, そして COOKIE)に作用します。 実行時に設定することはできません。 PHPのデフォルトは、onです。
PHP: マジッククオート - Manual

既定値オンですか。多くの場合に、magic_quotes_gpcをオフにして、必要時にaddslashes()をかけているのかなぁ。それとも無茶やってるかなぁ。それはともかく、Shif_JISは、そもそも文字化けが嫌われるので採用されなっぽい気もしますけれど。

マルチバイト文字処理の有無に関わらず、magic_quotes_gpcディレクティブは 有効にしてはいけない機能です。かならず、無効に設定するベキです。

[PHP-users 11443

magic_quotes_gpcをOnにすると、CGIパラメタがShift_JIS で渡されたときに文字化けが発生してしまうため、これが邪魔になるという問題が起きているようだ。そのため、酷いことに、 magic_quotes_gpc がOnのPHP環境でも動くようなプログラムを作るテクニックと称して、PHPプログラムの冒頭で、CGIパラメタの全部に対して「stripcslashes」をかけるという「前処理」が、一部のPHPプログラマの間で定番となっているようだ(この本に書かれているわけではない)。 magic_quotes_gpc = On したり stripcslashes したり、また htmlspecialchars してみたりと、ほんと汚いPHPコードがたくさん Googleで見つかる。magic_quotes_gpc は Off で徹底がよいだろう。

「サニタイズ言うなキャンペーン」とは何か::高木浩光@自宅の日記

Prepared Statements (準備済みSQL文(バインドメカニズム)の場合)

PHPではLIKEに使えない?…

Prepared statementはSQL のロジックとデータを分離することで セキュリティを増加します。ロジックとデータを分離することで、SQL インジェクション攻撃を回避することができます。

MySQL Lists: mysql-ja: Prepared Statement (訳)

くぅ〜、かっこいい。でもPHPのどこがウケルのか考えて見ますに、ソースレベルでロジックとデータをあえて混在させているところなのですよねぇ。…気が知れない。ところで Prepared Statementsって処理が重そうだけど、そんなときの為にAJAXとか(違)

2006/02/13追記:

最後の手段のはずだった、Prepared Statementsでも駄目かもという話になってきました。→addslashes() による SQL 文字列のエスケープ回避問題::t_komuraの日記

PEAR::DBのDB_common::prepare() ではMySQL使用時は内部でmysql_real_escape_string()が使われるので、エスケープされない…う〜ん。根本的にShift_JISってPHPと相性が悪いような(汗)

追記終わり。


.NET Frameworksにて、エスケープしてもSQLインジェクション対策にならない事例

id:jrofbyrさんの、これ、凄い話ですねぇ。

えむけいえむけい 2006/02/13 21:34 > 最後の手段のはずだった、
むしろPrepared Statementsを使うのが基本だと思います。サニタイジング症候群の人【誰】にはサニタイジング【謎】のための最終兵器か何かに見えるかもしれませんが。
Prepared Statementsで問題が起きるのはPrepared Statementsの設計そのものに欠陥があるわけではなくて、その実装がバグってるからに過ぎません。商用DBのように内部でもSQLの文字列に変換せずプレースホルダ用のメモリ領域に直接値が突っ込まれる実装なら原理的にこの種の問題は起きえませんね。バッファオーバーフローはあるかもしれませんが。

hoshikuzuhoshikuzu 2006/02/14 00:17 むきになって最後の手段をdel要素直下におきました。(笑)
ありがとうございます(まじめ)

 | 
最近のコメント