<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="rss.css" type="text/css"?>
<rdf:RDF xmlns="http://purl.org/rss/1.0/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:xhtml="http://www.w3.org/1999/xhtml" xml:lang="ja-JP">
	<channel rdf:about="http://www.tokumaru.org/d/index.rdf">
	<title>徳丸浩の日記(without comments)</title>
	<link>http://www.tokumaru.org/d/</link>
	<xhtml:link rel="alternate" media="handheld" type="text/html" href="http://www.tokumaru.org/d/" />
	<description></description>
	<dc:creator>徳丸浩(ockeghem)</dc:creator>
	<dc:rights>Copyright 2010 徳丸浩(ockeghem) &lt;hiroshi2007 [at] tokumaru.org&gt;, copyright of comments by respective authors</dc:rights>
	<items><rdf:Seq>
<rdf:li rdf:resource="http://www.tokumaru.org/d/20100725.html#p01"/>
<rdf:li rdf:resource="http://www.tokumaru.org/d/20100701.html#p01"/>
<rdf:li rdf:resource="http://www.tokumaru.org/d/20100406.html#p01"/>
<rdf:li rdf:resource="http://www.tokumaru.org/d/20100405.html#p01"/>
<rdf:li rdf:resource="http://www.tokumaru.org/d/20100329.html#p01"/>
<rdf:li rdf:resource="http://www.tokumaru.org/d/20080601.html#p01"/>
<rdf:li rdf:resource="http://www.tokumaru.org/d/20100325.html#p01"/>
<rdf:li rdf:resource="http://www.tokumaru.org/d/20100222.html#p01"/>
<rdf:li rdf:resource="http://www.tokumaru.org/d/20100212.html#p01"/>
<rdf:li rdf:resource="http://www.tokumaru.org/d/20100118.html#p02"/>
<rdf:li rdf:resource="http://www.tokumaru.org/d/20100118.html#p01"/>
</rdf:Seq></items>
</channel>
<item rdf:about="http://www.tokumaru.org/d/20100725.html#p01">
<link>http://www.tokumaru.org/d/20100725.html#p01</link>
<xhtml:link rel="alternate" media="handheld" type="text/html" href="http://www.tokumaru.org/d/20100725.html#p01" />
<dc:date>2010-07-25T12:57:15+09:00</dc:date>
<title>ツッコミSPAM対策で、ツッコミ抜きのRSSフィードを用意しました</title>
<dc:creator>徳丸浩(ockeghem)</dc:creator>
<description>昨日17:47から19:13にかけて、大量のツッコミSPAMが来ています。取り急ぎ、ツッコミの一日あたりの上限数を0にすることにより、対応しましたが、フィードで日記をご覧いただいてる方々には、見苦しいものをお見せして申し訳ございません。 ツッコミ対策は色々工夫してはおりますが、まだ決定的なものはない状態で、時々このような事態となっております。 当面の問題として、RSSフィードがSPAMだらけになることが問題ですので、ツッコミを含まないRSSフィードも生成する設定にいたしました。ツッコミがうざいと思われる方は、恐れ入りますが、以下のURLから再設定いただけるとよろしいかと思います。 http://www.tokumaru.org/d/no_comments.rdf no_comments.rdfの方は当面試験運用といたします。不具合などありましたら、ツッコミなどでお知らせください。</description>
<content:encoded><![CDATA[<h3>ツッコミSPAM対策で、ツッコミ抜きのRSSフィードを用意しました</h3><p>
<p>昨日17:47から19:13にかけて、大量のツッコミSPAMが来ています。取り急ぎ、ツッコミの一日あたりの上限数を0にすることにより、対応しましたが、フィードで日記をご覧いただいてる方々には、見苦しいものをお見せして申し訳ございません。</p>
<p>ツッコミ対策は色々工夫してはおりますが、まだ決定的なものはない状態で、時々このような事態となっております。</p>
<p>当面の問題として、RSSフィードがSPAMだらけになることが問題ですので、<a href="http://www.tokumaru.org/d/no_comments.rdf">ツッコミを含まないRSSフィード</a>も生成する設定にいたしました。ツッコミがうざいと思われる方は、恐れ入りますが、以下のURLから再設定いただけるとよろしいかと思います。</p>
<p><a href="http://www.tokumaru.org/d/no_comments.rdf">http://www.tokumaru.org/d/no_comments.rdf</a></p>
<p>no_comments.rdfの方は当面試験運用といたします。不具合などありましたら、ツッコミなどでお知らせください。</p>

</p>

<p><a href="http://www.tokumaru.org/d/20100725.html#c">ツッコミを入れる</a></p>]]></content:encoded>
</item>
<item rdf:about="http://www.tokumaru.org/d/20100701.html#p01">
<link>http://www.tokumaru.org/d/20100701.html#p01</link>
<xhtml:link rel="alternate" media="handheld" type="text/html" href="http://www.tokumaru.org/d/20100701.html#p01" />
<dc:date>2010-07-01T22:17:15+09:00</dc:date>
<title>ぼくがPDOを採用しなかったわけ(Shift_JISによるSQLインジェクション)</title>
<dc:creator>徳丸浩(ockeghem)</dc:creator>
<description>PHPのデータベース・アクセス・ライブラリPDOは、DB接続時の文字エンコーディング指定ができないため、文字エンコーディングの選択によっては、プレースホルダを使っていてもSQLインジェクション脆弱性が発生します。 はじめに 本を書いています。SQLインジェクションの節から書き始めて、初稿はレビュアーの方々にお送りしましたところ、さっそく有意義なコメントを多数頂戴しています。ありがとうございます。 その原稿の中で、DBアクセスに使用するPHPのライブラリとしてMDB2を紹介していたところ、PDOを紹介すべきではという意見を複数頂戴しました。そこで、現時点でPDOを採用していない理由を報告したいと思います。これは、「安全なSQLの呼び出し方」でPDOを取り上げていない理由でもあります。 PDOは接続時に文字エンコーディングを指定できない（指定しても無視される）ので、データベースへの接続時の文字エンコーディングはLatin1が暗黙に指定されます。すると、日本語の読み書きで文字化けが生じるため、「SET NAMES SJIS」により、文字エンコーディングを接続後に指定するようなプログラミン..</description>
<content:encoded><![CDATA[<h3>ぼくがPDOを採用しなかったわけ(Shift_JISによるSQLインジェクション)</h3><p>
<p>PHPのデータベース・アクセス・ライブラリPDOは、DB接続時の文字エンコーディング指定ができないため、文字エンコーディングの選択によっては、プレースホルダを使っていてもSQLインジェクション脆弱性が発生します。</p>
<h4>はじめに</h4>
<p>本を書いています。SQLインジェクションの節から書き始めて、初稿はレビュアーの方々にお送りしましたところ、さっそく有意義なコメントを多数頂戴しています。ありがとうございます。</p>
<p>その原稿の中で、DBアクセスに使用するPHPのライブラリとしてMDB2を紹介していたところ、PDOを紹介すべきではという意見を複数頂戴しました。そこで、現時点でPDOを採用していない理由を報告したいと思います。これは、「<a href="http://www.ipa.go.jp/security/vuln/websecurity.html">安全なSQLの呼び出し方</a>」でPDOを取り上げていない理由でもあります。</p>
<p>PDOは接続時に文字エンコーディングを指定できない（指定しても無視される）ので、データベースへの接続時の文字エンコーディングはLatin1が暗黙に指定されます。すると、日本語の読み書きで文字化けが生じるため、「SET NAMES SJIS」により、文字エンコーディングを接続後に指定するようなプログラミングがなされているようです（MySQLの場合）。</p>
<p>そのようなプログラム例を示します。このプログラムでは、内部文字エンコーディングとしてShift_JISを利用しているという想定です。PHP5.3.0とMySQL5.1.37の組み合わせで確認しました。</p>
<pre>
&lt;?php
  $dbh = new PDO('mysql:host=localhost;dbname=test;charset=sjis', 'username', 'password');
  $dbh->query("SET NAMES sjis");
  $sth = $dbh->prepare("select * from test WHERE name=?");
  $sth->setFetchMode(PDO::FETCH_NUM);
  $name = ...
  $sth->execute(array($name));
  while ($data = $sth->fetch()) {
    var_dump($data);
  }
</pre>
<p>PDO+MySQLの場合、プレースホルダは「動的プレースホルダ」あるいは、俗に「クライアントサイドのプリペアードステートメント」などと呼ばれる実装になっています<span class="footnote">*1</span>。</p>
<p>このため、$nameとして「ソ' OR 1=1#」という文字列を指定した場合、MySQLに対して以下のようなクエリが送信されます（Wiresharkによるダンプ）。</p><BR/>
<img src="/img/PDO-MYSQL.png">
<p>0x83は「ソ」の先頭バイトです。これをPDOではLatin1(ISO-8859-1)として扱うので、0x83はNBHという制御文字を意味し、1バイト文字になります。PDOは、続く「\'」を「\\\'」とエスケープします。</p>
<p>一方、MySQLサーバー側では、受け取ったSQLをShift_JISと想定しているので「ソ\\'」という並びと解釈します。「\\」は「\」をエスケープしたものなので、後続の「'」は文字列リテラルの終端に使われ、残りの「 OR 1=1#'」はSQL文の一部とみなされます。SQL文が注入できたので、SQLインジェクション脆弱性があるということになります。ここまでの説明を下図にまとめました。</p><br/>
<img src="/img/pdo-sjis-escape.png">
<h4>my.cnfの修正でもダメ</h4>
<p>「set names」がセキュリティ上問題があることが広く知られるようになったせいか、PDOの文字化けを別の方法で対処するようにすすめているエントリもあります。たとえば<a href="http://yuubiseiharukana.blog.shinobi.jp/Entry/77/">このエントリ</a>では、my.cnf(my.ini)の修正でPDOの文字化けに対応しているのですが、Shift_JISを使う場合はこれもダメです<span class="footnote">*2</span>。その理由は、「PDOはLatin1として処理したものを、MySQLはShift_JISとして解釈する」状態には変わらないからです。</p>
<h4>まとめ</h4>
<ul>
<li>PDO+MySQLでは、動的プレースホルダ（なんちゃってプリペアード・ステートメント）が使われる
<li>PDOでは文字エンコーディングが指定できない
<li>PDO+MySQL+Shift_JISでは、プレースホルダを使ってもSQLインジェクション脆弱性となる
</ul>
<h4>解決策・回避策</h4>
<p>PDOの文字化け問題とSQLインジェクション脆弱性問題を解決するにはどうすればよいでしょうか。私が思いつくのは以下の2つの方法です。</p>
<OL>
<LI>PDOではなくMDB2など文字エンコーディングを正しく扱えるライブラリを使用する(根本的対策)
<LI>アプリケーションからDBまで一貫してUTF-8で処理し、set names utf8により文字化けを回避する(回避策)
</OL>
<p>2.で具体的な問題が起こるかどうかは分かりませんが、文字エンコーディングを正しく扱えないことで潜在的なリスクがあると考えます。そのため、書いている本の中では1.を採用したという訳です。</p>
<p>しかし、私自身PHPを熟知しているわけではないので、ひょっとすると、PDOの使い方などでもっとよい方法があるかもしれません。識者のご指摘をいただければ幸いです。</p>
<h4>追記(2010/07/01 21:30)</h4>
<p><a href="http://d.hatena.ne.jp/nihen/">id:nihen</a>さんが、PDOに対して文字エンコーディングを設定する方法を調べてくださいました。nihenさん、どうもありがとうございます。以下に引用します。</p>
<pre>
PDOからよばれるreal_escape_stringで文字コードを考慮させたい場合は
$dbh = new PDO('mysql:host=localhost;dbname=sandbox;charset=cp932', 'sandbox', 'sandbox', array(
    PDO::MYSQL_ATTR_READ_DEFAULT_FILE => '/etc/mysql/my.cnf',
    PDO::MYSQL_ATTR_READ_DEFAULT_GROUP => 'client',
));

もしくはserver-side-prepareを使う場合(文字コード気にしなくておｋ)

$dbh = new PDO('mysql:host=localhost;dbname=sandbox;charset=cp932', 'sandbox', 'sandbox', array(
    PDO::ATTR_EMULATE_PREPARES => false,
));

ちなむと前者は接続時に使われるオプションなのでnew PDOしたあとにあとから
$dbh->setAttribute
しても、ダメ。後者はおｋ。
</pre>
<div align="right"><a hre="http://gist.github.com/459499"><a href="gist:">gist:</a> 459499 - GitHub</a>より引用</div>
<p>ご覧のように、MySQLサーバーへの接続時に、MySQL APIに渡すパラメータとして、my.cnfのファイル名を指定しています。上記の例ではGROUPを「client」に設定していますので、my.cnfに以下の設定を追加することになります。</p>
<pre>
[client]
default-character-set=sjis
</pre>
<p>ただし、Windows版のPHPでは、PDO::MYSQL_ATTR_READ_DEFAULT_FILEが使えないようです。このため、サーバー接続時に文字エンコーディングを指定する方法がありません。このため、Windows版のPHPを使う場合は、PDO::ATTR_EMULATE_PREPARESをfalseにする(真のプリペアード・ステートメントを使う)ことで対策することになります。</p>


</p>
<div class="footnote">
	<p class="footnote">*1&#160;高木浩光氏のいわれる「<a href="http://www.atmarkit.co.jp/fsecurity/column/ueno/60.html">なんちゃってプリペアド・ステートメント</a>」</p>
	<p class="footnote">*2&#160;元エントリはUTF-8なので問題はおきませんが、逆に言えば、set names utf8でも問題ないことになります</p>
</div>

<p><a href="http://www.tokumaru.org/d/20100701.html#c">ツッコミを入れる</a></p>]]></content:encoded>
</item>
<item rdf:about="http://www.tokumaru.org/d/20100406.html#p01">
<link>http://www.tokumaru.org/d/20100406.html#p01</link>
<xhtml:link rel="alternate" media="handheld" type="text/html" href="http://www.tokumaru.org/d/20100406.html#p01" />
<dc:date>2010-04-06T09:31:09+09:00</dc:date>
<title>PROXY（プロキシ）経由でのDNSリバインディングと対策</title>
<dc:creator>徳丸浩(ockeghem)</dc:creator>
<description>このエントリでは、PROXY経由でWebアクセスしている場合のDNSリバインディング対策について考察する。 PROXY（プロキシ）経由でWebアクセスしている場合、DNSによる名前解決はブラウザではなくPROXYにより行われる。したがって、	ブラウザ側ではDNS Pinningできないので、PROXY側での対策が重要になる。 広く使われているPROXYサーバーであるsquidの場合、DNS Pinningに相当するパラメータは、negative_dns_ttlであり、デフォルト値は1分間である。したがって、最初のアクセスから1分あけてXMLHttpRequestすれば、DNSリバインディングが成立する。これは実験で確認した。Internet ExplorerやOperaは、他のブラウザと比べてDNS Pinningがしっかりされている印象があるが、PROXY経由の場合は、これらブラウザでも比較的簡単にDNSリバインディングが成立するので注意が必要だ。 先のエントリで説明したように、JavaアプレットによるDNSリバインディングでも、URLクラスを使いかつPROXY経由でのアクセスの..</description>
<content:encoded><![CDATA[<h3>PROXY（プロキシ）経由でのDNSリバインディングと対策</h3><p>
<p>このエントリでは、PROXY経由でWebアクセスしている場合のDNSリバインディング対策について考察する。</p>
<p>PROXY（プロキシ）経由でWebアクセスしている場合、DNSによる名前解決はブラウザではなくPROXYにより行われる。したがって、	ブラウザ側ではDNS Pinningできないので、PROXY側での対策が重要になる。</p>
<p>広く使われているPROXYサーバーであるsquidの場合、DNS Pinningに相当するパラメータは、negative_dns_ttlであり、デフォルト値は1分間である。したがって、最初のアクセスから1分あけてXMLHttpRequestすれば、DNSリバインディングが成立する。これは実験で確認した。Internet ExplorerやOperaは、他のブラウザと比べてDNS Pinningがしっかりされている印象があるが、PROXY経由の場合は、これらブラウザでも比較的簡単にDNSリバインディングが成立するので注意が必要だ。</p>
<p><a href="http://www.tokumaru.org/d/20100405.html#p01">先のエントリ</a>で説明したように、JavaアプレットによるDNSリバインディングでも、URLクラスを使いかつPROXY経由でのアクセスの場合は、やはりPROXYでのDNS Pinningが問題となる。PROXY経由でのアクセスでは、Javaアプレットの場合でも、JavaScriptのXMLHttpRequestの場合同様、1分以上間隔をあけてやればDNS Rebindingが成立する。ただし、攻撃に使用できるプロトコルはHTTPのみであるので、JavaアプレットとJavaScriptでは、リスクは変わらない。</p>
<p>negative_dns_ttlの値を大きくすれば、squidがDNSキャッシュする最低時間を伸ばすことが可能だが、二つの点で問題がある。</p>
<p>第一の問題は、negative_dns_ttlを大きくすることの副作用だ。negative_dns_ttlは元々、DNSアクセスに失敗した場合のキャッシュ保持時間を意味するからだ。以下に、negative_dns_ttlのリファレンスを引用する。</p>
<blockquote cite="http://www.squid-cache.org/Doc/config/negative_dns_ttl/" title="squid : negative_dns_ttl configuration directive">
<p>Time-to-Live (TTL) for negative caching of failed DNS lookups. This also sets the lower cache limit on positive lookups. Minimum value is 1 second, and it is not recommendable to go much below 10 seconds.</p>

</blockquote>
<p class="source">[<cite><a href="http://www.squid-cache.org/Doc/config/negative_dns_ttl/" title="squid : negative_dns_ttl configuration directiveより引用">squid : negative_dns_ttl configuration directive</a></cite>より引用]</p>

<p>このため、一例として、negative_dns_ttlを6時間に設定した状態でDNS参照に失敗した場合（参照先DNSサーバーが一時的に停止した場合など）も6時間はDNSを再アクセスしない。すなわち、DNSのエラーが発生した場合は、negative_dns_ttlで設定した時間内は、当該サイトにアクセスできなくなるのだ。このため、negative_dns_ttlの値をあまり大きくすると、サイト閲覧に支障がでる可能性がある。</p>
<p>第二の問題は、negative_dns_ttlを長くしてもDNSリバインディングの根本対策にはならないことだ。
その背景には、PROXYサーバーをマルチユーザで使う場合が多いことや、タブブラウザの普及などがある。
やはりnegative_dns_ttlを6時間に設定した場合で説明しよう。AさんとBさんが同じPROXYサーバーを共有しているとする。Aさんが10:00にワナサイトにアクセスした場合、PROXYは16:00までワナサイトのIPアドレスをキャッシュする。したがって、Bさんが15:59にワナサイトを閲覧すると、そこから一分間でDNSキャッシュが無効になり、Bさんのブラウザ上動作するXMLHttpRequestがプライベートアドレスにアクセスすることを許してしまうかもしれない。
また、シングルユーザで考えても、タブブラウザのユーザはタブを開きっぱなしにする傾向があるので、6時間後の攻撃が成立する可能性はある。</p>
<h4>アクセス制御による対策</h4>
<p>結局negative_dns_ttlによる対策はうまくいかないので、別の方法を考える必要がある。有効な対策は、proxyのアクセス制御(ACL)により、squidにプライベートアドレスを中継させないことだ。以下に、192.168.0.0/16に対してアクセスを禁止する場合のsquid.confの設定例を示す。</p>
<pre>
acl localnet dst 192.168.0.0/16
http_access deny localnet
</pre>
<p>この場合、プライベートアドレスに対してはPROXY経由でアクセスできなくなるので、ブラウザのPROXY設定の例外設定をお忘れなく。下図に例外設定の例を示す。</p>
<img src="/img/IE-proxy-settings-x.png"><br clear=left>
<p>このACLによる対策の効果であるが、JavaScriptとJavaによるアクセスに関しては完全に対策できると考える。当初Javaアプレットが対策から漏れることを心配していたが、<a href="http://www.tokumaru.org/d/20100405.html#p01">先のエントリ</a>で検証したように問題ないことがわかった。Flashについては未検証なので今後検証したい…ところだが、私はFlashのコンテンツを書いたことがない。どなたか教えてください。</p>
<h4>まとめ</h4>
<p>PROXY経由でWebアクセスしている場合のDNSリバインディング対策について検討し、PROXYのACLによりプライベートアドレスを中継禁止することで対策可能であることを示した。DNSリバインディング対策のまとめについては別稿にて報告する。</p>

</p>

<p><a href="http://www.tokumaru.org/d/20100406.html#c">ツッコミを入れる</a></p>]]></content:encoded>
</item>
<item rdf:about="http://www.tokumaru.org/d/20100405.html#p01">
<link>http://www.tokumaru.org/d/20100405.html#p01</link>
<xhtml:link rel="alternate" media="handheld" type="text/html" href="http://www.tokumaru.org/d/20100405.html#p01" />
<dc:date>2010-04-05T08:43:14+09:00</dc:date>
<title>JavaアプレットのDNSリバインディングはJRE側で対策済みだった</title>
<dc:creator>徳丸浩(ockeghem)</dc:creator>
<description>Black Hat Japan 2007における金床氏のプレゼンテーションや金床本で、Javaアプレットに対するDNSリバインディングの手法が説明されている。ここしばらく、その追試を行っていた。結論としては、金床氏の方法にはJRE側で対策がとられていたので報告する。 金床氏が報告しているDNSリバインディングの手法とは以下のようなものだ（金床本に説明されている方法）。  被害者のユーザにワナのページをPROXY経由で閲覧させる ワナのドメイン(FQDN)に対するIPアドレスを変更する ワナページ上で数秒〜数十秒のちにJavaScriptによりJavaアプレット用のHTMLをレンダリングする JREがアプレットをPROXY経由で*1ダウンロードする アプレットのダウンロード時点で既にDNSレコードは書き換わっているが、PROXYがDNSキャッシュしているため、アプレットは正常にダウンロードされる アプレットからワナサイトのFQDNの任意のポートに対してSocket通信する。 既にIPアドレスは書き換わっているので、プライベートアドレスに対して任意のSocket通信ができることになる。..</description>
<content:encoded><![CDATA[<h3>JavaアプレットのDNSリバインディングはJRE側で対策済みだった</h3><p>
<div style="float: right;">
<iframe src="http://rcm-jp.amazon.co.jp/e/cm?t=jisakucompile-22&o=9&p=8&l=as1&asins=4887189400&fc1=000000&IS2=1&lt1=_blank&lc1=0000FF&bc1=000000&bg1=CCCCCC&f=ifr" style="width:120px;height:240px;" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"></iframe>
</div>
<p><a href="http://www.blackhat.com/html/bh-japan-07/bh-jp-07-jp-index.html">Black Hat Japan 2007</a>における<a href="http://src.jumperz.net/bh/bhj2007kanatoko.ppt">金床氏のプレゼンテーション</a>や<a href="http://www.amazon.co.jp/dp/4887189400?tag=jisakucompile-22&linkCode=as1&creative=6339">金床本</a>で、Javaアプレットに対するDNSリバインディングの手法が説明されている。ここしばらく、その追試を行っていた。結論としては、金床氏の方法にはJRE側で対策がとられていたので報告する。</p>
<p>金床氏が報告しているDNSリバインディングの手法とは以下のようなものだ（金床本に説明されている方法）。</p>
<ol>
<li>被害者のユーザにワナのページをPROXY経由で閲覧させる
<li>ワナのドメイン(FQDN)に対するIPアドレスを変更する
<li>ワナページ上で数秒〜数十秒のちにJavaScriptによりJavaアプレット用のHTMLをレンダリングする
<li>JREがアプレットをPROXY経由で<span class="footnote">*1</span>ダウンロードする
<li>アプレットのダウンロード時点で既にDNSレコードは書き換わっているが、PROXYがDNSキャッシュしているため、アプレットは正常にダウンロードされる
<li>アプレットからワナサイトのFQDNの任意のポートに対してSocket通信する。
<li>既にIPアドレスは書き換わっているので、プライベートアドレスに対して任意のSocket通信ができることになる。
</ol>
<p>このように、攻撃が成立すればとても凶悪な攻撃となるのだが、最近のJREでは以下の方法で対策されているようだ。</p>
<ul>
<li>アプレットがPROXY経由でダウンロードされた場合、アプレットからのSocket通信は全てクロスドメイン通信と扱われる
</ul>
<P>このような挙動に変わったバージョンを調べたところ、Java SE 6 update 3以降であることが分かった<span class="footnote">*2</span>。すなわち、Javaアプレットの金床方式によるDNSリバインディングが成立するバージョンは以下の通りである。</P>
<ul>
<li>J2SE1.4.xの全てのアップデート
<li>J2SE5.0の全てのアップデート
<li>Java SE 6のUpdate2以前
</ul>
<p>そして、Java SE6 Update3以降で、クロスドメイン通信になった場合の挙動は、JREのバージョンにより異なる。Java SE 6 update 10より前のバージョン（Update3〜7）だと、Socketでダイレクトにアクセスしようとするとエラーになる。一方、Java SE 6 update 10以降のバージョンでは、アクセス先のcrossdomain.xmlを参照して、その内容に従う。このあたりの挙動は、「<a href="http://java.sun.com/javase/ja/6/webnotes/6u10/plugin2/index.html">次世代 Java(TM) Plug-In テクノロジのリリースノート (JDK 6u10)</a>」を参照されたい。
</p>
<p>一方、アプレットが直に（PROXYを経由せずに）ダウンロードされた場合は、アプレットの置かれたFQDNに対してSocketによる任意ポートへの通信が可能だ。この場合は、DNSリバインディングが懸念されるところであるが、Javaの強固なDNS Pinningにより、アプレットダウンロード時のIPアドレスが永続的に保持されるので、DNSリバインディング攻撃はできない。</p>
<p>したがって、金床氏のプレゼンテーション資料には、Java版DNSリバインディング対策が色々書かれているが、その後Java側で対策がとられたことを考慮すると、ユーザが取るべき最善の対策は以下だろう<span class="footnote">*3</span>。</p>
<ul>
<li>JREを最新のバージョンにアップデートする
</ul>
<p>J2SE5.0以前のバージョンは既にEOLになっているし、DNSリバインディング対策もとられていないことから、使うべきではない。</p>
<p>また、Socketクラスではなく、URLクラス等HTTP系のクラスを使う場合は、PROXY経由の有無にかかわらず元FQDNとの通信は可能である。URLクラスを使う場合は、アプレットダウンロード時の設定に従い、PROXY経由となるか否かが決まる。URLクラスで、PROXY経由しない場合は、JavaのDNS Pinningが有効となり、DNSリバインディングはできない。一方、PROXY経由の場合は、PROXY側のDNS Pinningが問題となる。PROXYによるDNSリバインディング対策については稿を改めて説明する。</p>

</p>
<div class="footnote">
	<p class="footnote">*1&#160;Javaの設定にもよるがデフォルトはブラウザの設定をそのまま利用するので、PROXY経由となる</p>
	<p class="footnote">*2&#160;Java SE 6 update 3がリリースされたのが2007年10月3日、金床氏のBHJでのプレゼンテーションが2007年10月25日だったので、BHJのプレゼンテーション時点でJRE側の対策がなされていたことになる。ただし、update 3のリリースノートを読んでも、このような対策がなされていることは読み取れなかった。おそらく金床氏もupdate 3で対策されたとは明確には分からなかったのだろう。<a href="http://www.jumperz.net/index.php?i=2&a=1&b=10">金床氏のJavaアプレットによるDNSリバインディングのデモページ</a>には「Does not work on JRE1.6.0_03 or later」と明記されている。</p>
	<p class="footnote">*3&#160;今時Javaアプレットなど使わないというのであれば、あわせてJavaアプレット（プラグイン）を無効にするというのもあり。その場合もJREのバージョンは最新にすべきだ。</p>
</div>

<p><a href="http://www.tokumaru.org/d/20100405.html#c">ツッコミを入れる</a></p>]]></content:encoded>
</item>
<item rdf:about="http://www.tokumaru.org/d/20100329.html#p01">
<link>http://www.tokumaru.org/d/20100329.html#p01</link>
<xhtml:link rel="alternate" media="handheld" type="text/html" href="http://www.tokumaru.org/d/20100329.html#p01" />
<dc:date>2010-03-29T10:44:33+09:00</dc:date>
<title>DNSリバインディングによる無線LANパスフレーズの読み出しに成功</title>
<dc:creator>徳丸浩(ockeghem)</dc:creator>
<description>DNSリバインディング攻撃により、無線LANアクセスポイント(AP)に設定したWPAのパスフレーズ(PSK)を読み出す実験に成功したので報告する。 先のエントリではDNSリバインディング攻撃によるルータ設定変更の実験を報告したが、エントリでも触れたように設定変更についてはCSRF脆弱性を悪用することによっても可能だ*1。両手法の違いとして、CSRFは攻撃先の情報を読み出すことはできないのに対して、DNSリバインディングでは読み出しも可能だ。DNSリバインディングによるセッションCookieの読み出し例については、「ケータイtwitter(twtr.jp)においてDNS Rebinding攻撃に対する脆弱性を発見・通報し、即座に修正された」でも言及した。 無線LANアクセスポイントに対するDNSリバインディングのリスクを考える上で、もちろん設定変更もリスクではあるが、設定変更された場合、元々の所有者が無線LANにアクセスできなくなるなどの副作用が想定される。一方、パスフレーズの読み出しが行えれば、被害者のユーザに気づかれないままに攻撃される可能性が高く、それだけリスクも大きくなる。 ..</description>
<content:encoded><![CDATA[<h3>DNSリバインディングによる無線LANパスフレーズの読み出しに成功</h3><p>
<p>DNSリバインディング攻撃により、無線LANアクセスポイント(AP)に設定したWPAのパスフレーズ(PSK)を読み出す実験に成功したので報告する。</p>
<p><a href="/d/20100325.html#p01">先のエントリ</a>ではDNSリバインディング攻撃によるルータ設定変更の実験を報告したが、エントリでも触れたように設定変更についてはCSRF脆弱性を悪用することによっても可能だ<span class="footnote">*1</span>。両手法の違いとして、CSRFは攻撃先の情報を読み出すことはできないのに対して、DNSリバインディングでは読み出しも可能だ。DNSリバインディングによるセッションCookieの読み出し例については、「<a href="http://www.tokumaru.org/d/20100222.html#p01">ケータイtwitter(twtr.jp)においてDNS Rebinding攻撃に対する脆弱性を発見・通報し、即座に修正された</a>」でも言及した。</p>
<p>無線LANアクセスポイントに対するDNSリバインディングのリスクを考える上で、もちろん設定変更もリスクではあるが、設定変更された場合、元々の所有者が無線LANにアクセスできなくなるなどの副作用が想定される。一方、パスフレーズの読み出しが行えれば、被害者のユーザに気づかれないままに攻撃される可能性が高く、それだけリスクも大きくなる。</p>
<p>また、Wi-Fiの普及に伴い、ゲーム機や携帯電話などでも広く無線LANが利用できるようになったことを受けて、無線LAN機器メーカー各社は無線LANの簡易設定方式を提唱・実現している。これはよいことだが、一方で、誰も無線LANの設定画面を見たこともなく、APの管理用パスワード（WEPやWPAのパスフレーズではない）がデフォルトのままになっているケースが大半であると予想される。これは危険な状態ではないか。</p>
<H4>AOSSによる簡単設定</H4>
<p>筆者が実験用に所有しているAPは、株式会社バッファローの<a href="http://buffalo.jp/products/catalog/item/w/wla2-g54c/">WLA2-G54C</a>である。auの携帯電話<a href="http://www.au.kddi.com/seihin/ichiran/kishu/biblio/">biblio</a>のWi-Fi機能を評価するために購入したものだ。バッファロー製APの特徴として<a href="http://buffalo.jp/aoss/">AOSS</a>という簡単設定機能により、ボタン一つで無線LANの設定が可能である。その一端を以下に示そう。</p>
<p>APの設定でまず行うことは、APのIPアドレスの設定だ。ブラウザでもできなくはないが、APのユーティリティを使用すれば簡単だ。</p>
<img src="/img/wlan-air-station-setting-x.png"><br clear=left>
<p>上図でパスワードを入力する欄があるが、これは現在の管理パスワードを入力する欄でデフォルトは空である。ここで管理パスワードを設定できるわけではない。その後、バッファローの接続ユーティリティからAOSSによるプロファイルの追加を指定すると以下のような画面となる。</p>
<img src="/img/wlan-setting-001.png"><br clear=left>
<p>この状態でAPのAOSSボタンを長押しすると、APとクライアントのネゴシエーションが始まり、SSIDや暗号化の方法、パスフレーズなどが自動的に設定される。</p>
<img src="/img/wlan-setting-006.png"><br clear=left>
<p>安全な設定が簡単に行えるのだが、この手順に従うと、APの管理画面を一度も起動することなく、またAPの管理パスワードを設定する機会もないのだ。AOSSはPC以外に、ゲーム機（ニンテンドーDSなど）や携帯電話でも利用できるもので、おそらくバッファロー製無線LAN製品のユーザの大半が、管理パスワードを設定しないままに使用していると予想される。</p>
<h4>APの管理画面からパスフレーズが見える</h4>
<p>この状態で、APの管理画面をブラウザから表示させる。無線LANのメニューを表示すると以下のような画面だ。</p>
<img src="/img/wlan-manager001.png"><br clear=left>
<p>これを見ていやな予感のしたあなたの勘は正しい。HTMLソースを表示させると以下のような部分がある（一部マスク表示にした）。</p>
<pre>
&lt;input name=&quot;wl_wpa_psk&quot; type=&quot;password&quot; maxlength=&quot;64&quot; size=&quot;56&quot; 
value=&quot;7c188cXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX67&quot;&gt;
</pre>
<p>すなわち、管理画面が起動できれば、パスフレーズを見ることができるのだ。実は、これはこれで便利な面もあって、AOSSで設定したパスフレーズを確認することにより、AOSS対応でないクライアントを手動設定できるのだが、そういう利用方法を意図したものとも思えない。ともかく、ここまで紹介した内容から以下のことが分かる。</p>
<ul>
<li>AOSSによる設定では管理画面を見る必要がない
<li>管理画面のデフォルトパスワードは空である
<li>管理画面にログインすると無線LAN暗号化のパスフレーズが参照できる
</ul>
<p>これらの事実から、バッファロー製AP WLA2-G54Cは、DNSリバインディング攻撃により無線LAN暗号化パスフレーズが読み出せると判断し、実験してみることにした。<a href="http://bcnranking.jp/award/sokuhou/index.html">BCNの調査</a>によると、バッファロー社は無線LAN分野の2009年のシェアが53.0%ということで、影響も大きいと思った。</p>
<h4>侵入実験の実際</h4>
<p>以下に、侵入実験に用いたスクリプトの一部を示す。ドメインは仮のものに置き換えた</p>
<pre>
// リクエスタのセット
var requester = new XMLHttpRequest();
requester.open('GET', '<a href="http://root:@wlan.example.com/advance/ad-lan-wireless_sec_g.htm');">http://root:@wlan.example.com/advance/ad-lan-wireless_sec_g.htm');</a>
...
// パスフレーズの切り出し
var response = requester.responseText;
var regexp = /wl_wpa_psk.*value="([^"]+)"/m;
if (response.search(regexp) != -1) {
    pass = RegExp.$1;
}
</pre>
このスクリプトはインターネット上のワナサイトに置かれる。このコンテンツが読み出された直後に上記FQDNに対するIPアドレスをAPのプライベートアドレスに書き換える。コンテンツ読み出しから4分後に上記リクエストが送出されるようにスクリプトを作成した。実行例を以下に示す。</p>
<br><br>
<img src="/img/wlan-hacked01x.png"><br clear=left>
<p>図示したように、パスフレーズが読み出されていることが分かる。この後、ワナサイトにこの値をPOSTして、攻撃は完成である。</p>
<h4>対策</h4>
<p>バッファロー製AP WLA2-G54Cをマニュアルの指示通りに設定した状態において、DNSリバインディングにより暗号化パスフレーズ（PSK）を読み出すことに成功した。ユーザ側の対策としては、以下に尽きるだろう。</p>
<pre>
管理パスワードを適切に設定する
</pre>
<p>しかし、コンシューマ向け製品ということを考慮すると、現在の製品仕様のままでは全てのユーザに管理パスワードを徹底させることも難しいだろう。したがって、製品提供者側の対策が今後は重要となる。以下のような対策案が考えられる。</p>
<ul>
<li>APの管理パスワードの初期値を機器毎に違うものにする（根本的対策）
<li>製品設定の流れの中で管理パスワードの変更を強制する（根本的対策）
<li>管理画面URLのホスト部は数値IPアドレスのみを許容する（保険的対策）
</ul>
<h4>まとめ</h4>
<p>バッファロー製AP WLA2-G54Cを対象として、DNSリバインディング攻撃により暗号化パスフレーズ（PSK）を外部から読み出せることを確認した。他社製品の場合は、パスフレーズが読み出せるかどうかは不明であるが、マニュアルを読む限りは管理パスワードの初期値が空で、変更も要求されないものが多いよう<span class="footnote">*2</span>なので、仮に暗号化パスフレーズが読み出せないとしても、設定変更は可能である可能性が高い。この場合、APの設定を「暗号化なし」に設定変更することにより、内部ネットワークへの侵入や盗聴などが行える。</p>
<p>無線LANの簡単設定機能は、AOSS以外にも「らくらく無線スタート」やWPSなどがある。これらは、安全な無線LAN設定を簡略化するという意味で社会的な意義のあるものだと思うが、基本的な想定として、「管理画面にはインターネットからアクセスできないので管理パスワードは設定しなくても大丈夫」と考えられているように見受ける。しかし、DNSリバインディングやクロスサイト・リクエスト・フォージェリ(CSRF)などの受動的攻撃により、インターネット越しに管理画面にアクセスすることは可能だ。ルータにCSRF脆弱性が多数指摘されてきた歴史は、<a href="http://www.google.co.jp/search?q=site%3Ajvn.jp+%E3%82%AF%E3%83%AD%E3%82%B9%E3%82%B5%E3%82%A4%E3%83%88%E3%83%BB%E3%83%AA%E3%82%AF%E3%82%A8%E3%82%B9%E3%83%88%E3%83%BB%E3%83%95%E3%82%A9%E3%83%BC%E3%82%B8%E3%82%A7%E3%83%AA%E3%80%80%E3%83%AB%E3%83%BC%E3%82%BF&btnG=%E6%A4%9C%E7%B4%A2">「site:jvn.jp クロスサイト・リクエスト・フォージェリ　ルータ」でGoogle検索</a>してみると直ぐ分かる。DNSリバインディングについては、パスワードの設定さえすれば対策できるため、製品の脆弱性としては指摘しにくいが、今後十分発生し得る脅威として、メーカー側には対策を要望する。</p>

</p>
<div class="footnote">
	<p class="footnote">*1&#160;ルータにCSRF脆弱性があればという前提だが</p>
	<p class="footnote">*2&#160;NECアクセステクニカ株式会社製のAtermシリーズは例外的にパスワードの変更が設定手順上で要求される</p>
</div>

<p><a href="http://www.tokumaru.org/d/20100329.html#c">ツッコミを入れる</a></p>]]></content:encoded>
</item>
<item rdf:about="http://www.tokumaru.org/d/20080601.html#p01">
<link>http://www.tokumaru.org/d/20080601.html#p01</link>
<xhtml:link rel="alternate" media="handheld" type="text/html" href="http://www.tokumaru.org/d/20080601.html#p01" />
<dc:date>2010-03-26T15:22:46+09:00</dc:date>
<title>SQLのエスケープ再考</title>
<dc:creator>徳丸浩(ockeghem)</dc:creator>
<description>本稿ではSQLインジェクション対策として、SQLのエスケープ処理の方法について検討する。 最近SQLインジェクション攻撃が猛威を振るっていることもあり、SQLインジェクションに対する解説記事が増えてきたようだが、対策方法については十分に書かれていないように感じる。非常に稀なケースの対応が不十分だと言っているのではない。ごく基本的なことが十分書かれていないと思うのだ。 SQLインジェクション対策には二通りある。バインド機構を使うものと、SQLのエスケープによるものだ。このうち、SQLのエスケープについて、十分に書かれているテキストが見当たらないのだ。このため、自分で書いてみようと思う。 IPAの「安全なウェブサイトの作り方改訂第三版」ではSQLのエスケープについて以下のように説明されている。      1)-2 バインド機構を利用できない場合は、SQL 文を構成する全ての変数に対しエスケープ処理を行う                解説       　これは、根本的解決 1) のバインド機構を利用した実装ができない場合に実施すべき実装です。 　利用者から入力されるパラメータや、データ..</description>
<content:encoded><![CDATA[<h3>SQLのエスケープ再考</h3><p>
<p>本稿ではSQLインジェクション対策として、SQLのエスケープ処理の方法について検討する。</P>
<P>最近SQLインジェクション攻撃が猛威を振るっていることもあり、SQLインジェクションに対する解説記事が増えてきたようだが、対策方法については十分に書かれていないように感じる。非常に稀なケースの対応が不十分だと言っているのではない。ごく基本的なことが十分書かれていないと思うのだ。</p>
<p>SQLインジェクション対策には二通りある。バインド機構を使うものと、SQLのエスケープによるものだ。このうち、SQLのエスケープについて、十分に書かれているテキストが見当たらないのだ。このため、自分で書いてみようと思う。</p>
<p>IPAの「<a href="http://www.ipa.go.jp/security/vuln/websecurity.html">安全なウェブサイトの作り方改訂第三版</a>」ではSQLのエスケープについて以下のように説明されている。</P>


</p>
<blockquote>
<p>
1)-2 バインド機構を利用できない場合は、SQL 文を構成する全ての変数に対しエスケープ処理を行う
<TABLE border="1">
  <TBODY>
    <TR>
      <TD valign="top" width="40">解説</TD>
      <TD>　これは、根本的解決 1) のバインド機構を利用した実装ができない場合に実施すべき実装です。<BR>
　利用者から入力されるパラメータや、データベースに格納された情報などに限らず、SQL 文を構成する全ての変数や演算結果に対し、エスケープ処理を行ってください。エスケープ処理の対象は、SQL文にとって特別な意味を持つ記号文字（たとえば、「'」→「''」、「\」→「\\」 など）です。<BR>
　なお、SQL 文にとって特別な意味を持つ記号文字は、データベースエンジンによって異なるため、利用しているデータベースエンジンに応じて対策をしてください。データベースエンジンによっては、専用のエスケープ処理を行うAPIを提供しているものがあります（たとえば、Perl ならDBIモジュールのquote()など）ので、それを利用することをお勧めします。</TD>
    </TR>
  </TBODY>
</TABLE>


</p>

</blockquote>
<p>
<P>引用した部分は、一般的な内容を網羅しているものの不満もある。短い文章の中で「など」が3回も現れることに象徴されるように、あいまい性の残る文章となっている。これはデータベースの製品依存のところでやむを得ないというのはよく理解できるのだが、結果として、読者に「データベースエンジンのマニュアルを読め」と言っているの等しい。それでいて、読者には、マニュアルのどこをどう調べたらよいかまでは示していない。「エスケープ処理の対象は、SQL文にとって特別な意味を持つ記号文字」と書かれているが、この説明だと、「;」や「=」、空白までエスケープしなければならないと誤解する読者が出てくるかもしれない。実際には、これらの文字をエスケープする必要はないし、SQLの標準規格には、そもそもこれらの文字をエスケープする手段が用意されていない。エスケープの必要がないので手段も用意されていないのだ。</P>
<P>そこで、「安全なウェプサイトの作り方」を補完するような形で、もう少しSQLエスケープについて書き足してみたい。</P>
<h4>SQLインジェクションのおさらい</h4>
<P>SQLインジェクション攻撃では、SQLに渡すパラメータ部分にSQL断片を挿入し、SQLの意味を書き換えることによって行われる。 バインド機構を使わずに自前でSQLを組み立てる場合、SQLに対するパラメータはSQLのリテラル(定数)の形で渡される。</P>
<p>リテラルには複数の型があるが、通常問題になるのは数値と文字列である。</p><P>数値リテラルの場合:

</p>
<blockquote>
<p>
SELECT * FROM XXXXX WHERE NNUM=●●●&#160;&#160;&#160;&#160;&#160; -- ●●●は数値、例えば 123 


</p>

</blockquote>
<p>
文字列リテラルの場合:

</p>
<blockquote>
<p>
SELECT * FROM XXXXX WHERE EID='■■■'&#160;&#160;&#160;&#160;&#160; -- ■■■は文字列、例えば S853


</p>

</blockquote>
<p>

<P>なぜリテラルを構成する文字列(●●●や■■■)を操作することでSQLの構文まで変わるのか。それは特殊記号などでリテラルを終端させ、その後にSQL断片を埋め込むからだ。</P><p>数値リテラルを終端させるには、数値以外の文字を加えればよい。

</p>
<blockquote>
<p>
例: 123OR TRUE&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; -- 数値リテラル123の後に、OR TRUE が続く。123 OR TRUEと同じ


</p>

</blockquote>
<p>
<p>文字列リテラルを終端させるには、単一引用符「'」を加えればよい

</p>
<blockquote>
<p>
例: A'OR'A'='A<BR>
<BR>
この例を先のSQLに適用すると、<BR>
<BR>
SELECT * FROM XXXXX WHERE EID='A'OR'A'='A'<BR>
<BR>
となる。つまり、WHERE句は常に真となる。


</p>

</blockquote>
<p>
<H4>SQLインジェクション対策の基本的な考え方</H4>
<p>
すなわち、SQLインジェクション対策の方針としては、リテラルを勝手に終端させないようにすることが必要なのだ。そして、この処理は数値リテラルと文字列リテラルとでは、方法が異なる。</p><p>
数値リテラルの場合は、数値以外の文字が出てきた時点でリテラルの終端となるので、数値としての妥当性検証を行うことになる(<a href="http://www.tokumaru.org/d/20070924.html#p01">数値項目に対するSQLインジェクション対策のまとめ</a>参照)
。</p><p>一方、文字列リテラルの場合は、文字列リテラルのエスケープを行えばよい。SQL92などSQLの標準規格で規定しているのは、単一引用符「'」のエスケープであるが、データベースの種類によっては、円記号(バックスラッシュ)「\」のエスケープも必要となる。</p>
<h4>商用データベースの場合</h4>
<p>商用データベースの場合は、SQL標準に従い、単一引用符「'」を「''」と重ねる処理を行う。<a href="http://otndnld.oracle.co.jp/document/products/oracle10g/102/doc_cd/server.102/B19201-02/sql_elements.html#41297">Oracle</a>、<a href="http://msdn.microsoft.com/ja-jp/library/ms179899.aspx">SQL Server</a>、<a href="http://publib.boulder.ibm.com/infocenter/db2luw/v9r5/index.jsp?topic=/com.ibm.db2.luw.sql.ref.doc/doc/r0000731.html">IBM DB2</a>についてはリファレンスと動作の両方で確認した。
</P>
<h4>オープンソース・データベースの場合</h4>
<p>
オープンソースのデータベースとして広く普及しているMySQLの場合、<a href="http://dev.mysql.com/doc/refman/5.1/ja/string-syntax.html">文字列リテラル中にC言語風の「\」を使ったエスケープシーケンスが記述できる</a>。従って、文字列リテラル中に「\」自体を記述する際には、「\\」とする必要がある。一方、単一引用符「'」は「''」としてもよいし、「\'」としてもよい。その他、二重引用符「"」が利用できるなど自由度が高い。</p>
<p>オープンソース・データベースのもう一方の雄<a href="http://www.postgresql.jp/document/pg831doc/html/sql-syntax-lexical.html#SQL-SYNTAX-STRINGS">PostgreSQL</a>の場合は事情が少し複雑となるが、デフォルトではMySQLと同じで、単一引用符と円記号(バックスラッシュ)の両方をエスケープする必要がある。しかし、設定パラメータstandard_conforming_stringsがonの場合(デフォルトはoff)は、Oracleなどと同じ挙動となる(現実にはもう少し複雑だが稿をあらためて説明したい)。<p>
まとめると以下のようになる。</p>

<TABLE border="1">
  <TBODY>
    <TR>
      <TD>データベース</TD>
      <TD>元の文字</TD>
      <TD>エスケープ後</TD>
    </TR>
    <TR>
      <TD>Oracle<BR>MS SQL<BR>IBM DB2</TD>
      <TD align="center">'</TD>
      <TD align="center">''</TD>
    </TR>
    <TR>
      <TD rowspan="2">MySQL<BR>PostgreSQL</TD>
      <TD align="center">'</TD>
      <TD align="center">'' または \'</TD>
    </TR>
    <TR>
      <TD align="center">\</TD>
      <TD align="center">\\</TD>
    </TR>
  </TBODY>
</TABLE>
<p>なお、念のため補足すると、エスケープ処理はセキュリティ対策のために行うものでは元々なく、与えられたパラメータに対して正しく処理を行うために必要な処置である。入力に「'」や「\」が使えないと不便で仕方がないし、現実的に不具合が生じるだろう。
</p>
<h4>その他のデータベース製品の場合はどうしたらよいか</h4>
<p>今回説明した内容にもっとも近い記述があるドキュメントとしては、佐名木智貴氏の近著「<a href="http://www.amazon.co.jp/dp/4883732568?tag=jisakucompile-22">セキュアWebプログラミングTips集(ソフト・リサーチ・センター)</a>」がある。同書では、SQLエスケープの基本として</p>

</p>
<blockquote>
<p>
「'」は、「''」(シングル・クォート2個)にエスケープ処理することで、SQLインジェクションから防御することができる(同書P210)


</p>

</blockquote>
<p>
<p>とした上で、</p>

</p>
<blockquote>
<p>
mySQLとPostgreSQLの場合のSQLインジェクション対策として、入力データをSQL文の文字列リテラルとして使う場合、「'(シングル・クォート)」と「\」をSQLエスケープすること(同書P213)


</p>

</blockquote>
<p>
<p>と指摘している。</p>
<p>非常に丁寧な仕事ぶりで好感を持った。ただ、同じページの以下はいただけない</p>

</p>
<blockquote>
<p>
筆者の知らないデータベース・ソフトウェアでは、SQLが拡張され、それ以外のメタキャラクタもあるかも知れない。ぜひ読者諸氏には今一度、自分の使っているデータベース・ソフトウェアの<B>SQLリファレンスを通読することを推奨する</B>(同書P213)。


</p>

</blockquote>
<p>
<p>「SQLリファレンスを<B>通読</B>」とは・・・無茶言うなよと思う。</p>
<p>実際には通読する必要はなく、「リテラル」、「定数」、「文字列」などのキーワードを手掛かりに、文字列リテラルの項を探すとよい。本稿で引用したリファレンスもこのようにして探したものである。</p>
<p>Oracleの場合を例にマニュアルの見方を説明しよう。題材として、<a href="http://otndnld.oracle.co.jp/document/products/oracle10g/102/doc_cd/server.102/B19201-02/toc.html">Oracle10gのオンラインマニュアル</a>を利用する。</p>
<p>まず、目次から「リテラル」を探すと、「<a href="http://otndnld.oracle.co.jp/document/products/oracle10g/102/doc_cd/server.102/B19201-02/sql_elements.html">2  Oracle SQLの基本要素</a>」に「<a href="http://otndnld.oracle.co.jp/document/products/oracle10g/102/doc_cd/server.102/B19201-02/sql_elements.html#41119">リテラル</a>」や「<a href="http://otndnld.oracle.co.jp/document/products/oracle10g/102/doc_cd/server.102/B19201-02/sql_elements.html#41297">テキスト・リテラル</a>」という項が見つかる。「<a href="http://otndnld.oracle.co.jp/document/products/oracle10g/102/doc_cd/server.102/B19201-02/sql_elements.html#41297">テキスト・リテラル</a>」の項を読むと、</p>

</p>
<blockquote>
<p>
<UL>
  <LI>cは、データベース・キャラクタ・セットの任意の要素です。リテラル内の一重引用符（'）の前には、エスケープ文字を付ける必要があります。リテラル内で一重引用符を表すには、一重引用符を2つ使用します
  <LI> ''は、テキスト・リテラルの始まりと終わりを示す2つの一重引用符です。
</UL>


</p>

</blockquote>
<p>
<p>このように、エスケープの必要な文字は一重引用符「'」であること、エスケープの仕方は一重引用符を2つ使用することであることがわかる。他のデータベース・ソフトウェアでも、同様に探すことができるだろう。</p>
<p>本稿を参考に正しいSQLインジェクション対策を実施していただきたい。</p>
<BR>
<p>続く(<a href="http://www.tokumaru.org/d/20080602.html#p01">徳丸浩の日記 - SQLインジェクション対策 - SQLエスケープにおける「\」の取り扱い</a>)
</p>
<p>参考:<a href="http://www.hash-c.co.jp/archive/wasf2008.html">WASForum Conference 2008講演資料「SQLインジェクション対策再考」</a></p>
<h4>追記（2010/03/26）</h4>
<p>このエントリを書いた後、IPA非常勤研究員として、SQLインジェクションの正しい対策方法について調査・検討しました。その成果は「安全なSQLの呼び出し方」という冊子（安全なウェブサイトの作り方別冊）という形にまとめられました。ぜひご活用いただければと思います。ダウンロードは<a href="http://www.ipa.go.jp/security/vuln/websecurity.html">こちら</a>から。</p>

</p>

<p><a href="http://www.tokumaru.org/d/20080601.html#c">ツッコミを入れる</a></p>]]></content:encoded>
</item>
<item rdf:about="http://www.tokumaru.org/d/20100325.html#p01">
<link>http://www.tokumaru.org/d/20100325.html#p01</link>
<xhtml:link rel="alternate" media="handheld" type="text/html" href="http://www.tokumaru.org/d/20100325.html#p01" />
<dc:date>2010-03-25T07:29:03+09:00</dc:date>
<title>DNSリバインディングによるルータへの侵入実験</title>
<dc:creator>徳丸浩(ockeghem)</dc:creator>
<description>このエントリでは、DNSリバインディング攻撃によりブロードバンドルーターの設定を外部からの侵入を許すように変更してみたので報告する。 DNSリバインディングに対する関心が高まってきている。本年1月12日には、読売新聞夕刊一面トップで、iモードブラウザ2.0のDNSリバインディングによる不正アクセスが報じられた。3月17日のcomputerworld.jpでは、『2010年に最も警戒すべきセキュリティ脅威は「DNSリバインディング」』という翻訳記事が紹介された。実は「最も警戒すべきセキュリティ脅威」というタイトルは誤報だったわけだが*1、DNSリバインディングというマニアックな攻撃手法が注目を浴びるきっかけにはなったと思う。 そこで、専門家の方にはいまさらかもしれないが、DNSリバインディング攻撃により、自宅のブロードバンドルーターの設定を変更してみた。思いの外簡単にできたが、対策も容易であるので、その両方を説明しよう。 侵入実験の前提 まず一般的なDNSリバインディングの概要説明は、「DNS Rebinding」を参照頂きたい。この説明では、イントラネット内のサーバーへの侵入の例を..</description>
<content:encoded><![CDATA[<h3>DNSリバインディングによるルータへの侵入実験</h3><p>
<p>このエントリでは、DNSリバインディング攻撃によりブロードバンドルーターの設定を外部からの侵入を許すように変更してみたので報告する。</p>
<p>DNSリバインディングに対する関心が高まってきている。本年1月12日には、読売新聞夕刊一面トップで、iモードブラウザ2.0のDNSリバインディングによる不正アクセスが報じられた。3月17日のcomputerworld.jpでは、<a href="http://www.computerworld.jp/topics/vs/177029.html">『2010年に最も警戒すべきセキュリティ脅威は「DNSリバインディング」』</a>という翻訳記事が紹介された。実は「最も警戒すべきセキュリティ脅威」というタイトルは<a href="http://d.hatena.ne.jp/ockeghem/20100323/p1">誤報</a>だったわけだが<span class="footnote">*1</span>、DNSリバインディングというマニアックな攻撃手法が注目を浴びるきっかけにはなったと思う。</p>
<p>そこで、専門家の方にはいまさらかもしれないが、DNSリバインディング攻撃により、自宅のブロードバンドルーターの設定を変更してみた。思いの外簡単にできたが、対策も容易であるので、その両方を説明しよう。
<h4>侵入実験の前提</h4>
<p>まず一般的なDNSリバインディングの概要説明は、「<a href="http://www.tokumaru.org/d/20071126.html#p01">DNS Rebinding</a>」を参照頂きたい。この説明では、イントラネット内のサーバーへの侵入の例を挙げているが、今回の実験では、ブロードバンドルータへの侵入となる。実験に用いた自宅のルータは、プライベートアドレス（内部ネットワーク）からは設定が変更できるが、インターネット側からは設定できないという仕様となっている。そのため、DNSリバインディング攻撃が有効だ。この種のルータに対する攻撃手法としてはクロスサイト・リクエスト・フォージェリ(CSRF)という選択肢も考えられるが、このエントリでは言及しない。</p>
<p>実験では、まず、ルータの設定変更に必要なHTTPリクエストを調査した。その結果、POSTリクエストを3回送信すれば、外部からの侵入を許すように変更できることがわかった。</p>
<p>次に、インターネット上にワナサイトを用意して、ワナサイトをリクエストした後にDNSの内容を書き換え、一定時間置いた後に上記3つのPOSTリクエストを送出するようにした。実験に用いたブラウザはFirefox 3.6.2であり、最初のリクエストから4分間の間隔をとれば、DNSリバインディングが成立することがわかった<span class="footnote">*2</span>。このため、3回のリクエストはそれぞれ、4分後、4分10秒後、4分20後に送出されるように、JavaScriptによるスクリプトを作成した。</p>
<p>ここで問題になるのが、ルータの認証をどうやってすり抜けるかだ。他の攻撃手法、たとえばCSRFの場合は、ユーザが認証している状態を悪用するわけだが、DNSリバインディングではこの方法は使えない。なぜなら、DNSリバインディングによるリクエストのHost:フィールドはワナサイトのドメインになっているからだ。このため、実験では、攻撃者がルータのパスワードを推測できるという想定にした。以下の説明では、ユーザIDとパスワードがともに「admin」になっていると想定する。これはそれほど突飛な想定ではない。この種のルータの初期設定はパスワードなしか、固定の初期パスワードになっていることが多いからだ。</p>
<h4>侵入実験の実際</h4>
<p>下図に侵入前のルータの設定を示す。赤い四角で囲った部分に、新たな設定を追加する。</p><BR>
<img src="/img/before.png"><br clear="left">
<p>次に、以下は侵入実験に用いたスクリプトのごく一部だ。このルータはBASIC認証が使われているので、以下のようにURLの中にBASIC認証のIDとパスワードを記述した。スクリプトキディが真似するとまずいので、スクリプトの全容は非公開とする。また、router.example.comはワナサイトのドメインだが、仮にものに置き換えた。</p>
<pre>
    var requester = new XMLHttpRequest();
    requester.open('POST', ''<a href="http://admin:admin@router.example.com/entry_ipnat_main_bottom.html');">http://admin:admin@router.example.com/entry_ipnat_main_bottom.html');</a>
</pre>
<p>このスクリプトを含むワナが閲覧されたら直ぐに、router.example.comのIPアドレスを192.168.0.1（ルータのアドレス）に書き換える。その後3回のリクエストが正常にルータに送信されると、設定を反映するためにルータがリセットされた。攻撃成功である。攻撃成功後のルータの設定を下図に示す。</p><BR>
<img src="/img/after.png"><br clear="left">
<p>ご覧のように、192.168.0.10の端末に対して、インターネットからTCP3389ポートを受け付けるようになった。3389はWindowsのリモートデスクトップが使用するポートなので、この設定変更により外部からの侵入が可能になった。</p>
<h4>対策</h4>
<p>ルータやファイアウォールの設定変更は、DNSリバインディングのデモとしては定番と言えるものだが、実際の結果を見るとギョッとした人も多いのではないか。しかし、幸いなことに、対策は容易である。前述のように、DNSリバインディング攻撃は、ユーザの認証状態を引き継ぐことができないので、認証がかかっているサイトの場合、パスワードが分からないと侵入できない。従って、良質のパスワードを設定するだけで、侵入を食い止めることができる。</p>
<p>しかし、問題は、これだけブロードバンドのインターネットが普及した状況下で、ブロードバンドルータの多くがデフォルトパスワードのまま（パスワードなしも含めて）の設定と予想されることだ。従って、DNSリバインディングによる攻撃はいつ起こっても不思議ではないし、既に起こっているかもしれない。</p>
<p>従来、ブロードバンドルータのパスワード初期設定がいい加減だった理由は、「外部からは設定変更できないから安全だ」という意識が働いていたからだと推測する。しかし、ルータに対する外部からの侵入手法は、DNSリバインディングの他、ルータのCSRF脆弱性を悪用するなど複数存在する。一方で、ブラウザ側でDNSリバインディングを完璧に対策するのは困難だ。その理由は、IPアドレスの変更は、DNSの正式な仕様として認められた挙動であるからだ。このため、ルータやファイアウォールの初期パスワードやパスワードの管理について、さらなる工夫が求められる。</p>
<p>さらに網羅的なDNSリバインディング対策については、稿を改めて説明する。</p>


</p>
<div class="footnote">
	<p class="footnote">*1&#160;原題は「Top Ten Web Hacking Techniques」なので脅威という訳もおかしいが</p>
	<p class="footnote">*2&#160;4分間が長すぎると感じる人もいると思うが、この時間を短くするAnti-DNS Pinningという手法が存在するし、ワナサイト上でYoutubeの映像でも流しておけば4分くらいはワナサイト上にとどまるユーザもいるだろう</p>
</div>

<p><a href="http://www.tokumaru.org/d/20100325.html#c">ツッコミを入れる</a></p>]]></content:encoded>
</item>
<item rdf:about="http://www.tokumaru.org/d/20100222.html#p01">
<link>http://www.tokumaru.org/d/20100222.html#p01</link>
<xhtml:link rel="alternate" media="handheld" type="text/html" href="http://www.tokumaru.org/d/20100222.html#p01" />
<dc:date>2010-02-22T11:54:11+09:00</dc:date>
<title>ケータイtwitter(twtr.jp)においてDNS Rebinding攻撃に対する脆弱性を発見・通報し、即座に修正された</title>
<dc:creator>徳丸浩(ockeghem)</dc:creator>
<description>twitterのケータイ版twtr.jpにおいて、DNS Rebindingによるなりすましを許す脆弱性が発見され、1/15に通報したところ、その日のうちに修正された。以下、その経緯について報告する。 経緯 今年の1月12日に読売新聞の記事が出たのを受けて、現実のサイトはどうなのだろうかと改めて気になった。   　ＮＴＴドコモの携帯電話のうち、インターネット閲覧ソフト「ｉモードブラウザ２・０」を搭載した最新２９機種を通じて、利用者の個人情報を不正取得される恐れのあることが、専門家の指摘で明らかになった。 　同社は携帯サイトの運営者にパスワード認証などの安全対策を呼びかけている。携帯電話の機能が高機能化するにつれ、こうした危険は増しており、利用者も注意が必要になってきた。   [ドコモ携帯、情報流出の恐れ…最新２９機種より引用]    私自身も携帯電話でいくつかのサイトを巡回しており、その一つにtwitter.comの日本の携帯電話向けフロントエンドであるtwtr.jpも含まれる。ご存じのように、twitterは政府要人や有名人も数多く使っているし、twitter.comの画面で確認..</description>
<content:encoded><![CDATA[<h3>ケータイtwitter(twtr.jp)においてDNS Rebinding攻撃に対する脆弱性を発見・通報し、即座に修正された</h3><p>
<p>twitterのケータイ版twtr.jpにおいて、DNS Rebindingによるなりすましを許す脆弱性が発見され、1/15に通報したところ、その日のうちに修正された。以下、その経緯について報告する。</p>
<h4>経緯</h4>
<p>今年の1月12日に読売新聞の記事が出たのを受けて、現実のサイトはどうなのだろうかと改めて気になった。
</p>
<blockquote cite="http://www.yomiuri.co.jp/net/news/20100112-OYT8T01018.htm" title="ドコモ携帯、情報流出の恐れ…最新２９機種">
<p>　ＮＴＴドコモの携帯電話のうち、インターネット閲覧ソフト「ｉモードブラウザ２・０」を搭載した最新２９機種を通じて、利用者の個人情報を不正取得される恐れのあることが、専門家の指摘で明らかになった。</p>
<p>　同社は携帯サイトの運営者にパスワード認証などの安全対策を呼びかけている。携帯電話の機能が高機能化するにつれ、こうした危険は増しており、利用者も注意が必要になってきた。</p>

</blockquote>
<p class="source">[<cite><a href="http://www.yomiuri.co.jp/net/news/20100112-OYT8T01018.htm" title="ドコモ携帯、情報流出の恐れ…最新２９機種より引用">ドコモ携帯、情報流出の恐れ…最新２９機種</a></cite>より引用]</p>

<p>
<img src="/img/dnsr00.jpg" align="right">
私自身も携帯電話でいくつかのサイトを巡回しており、その一つにtwitter.comの日本の携帯電話向けフロントエンドであるtwtr.jpも含まれる。ご存じのように、twitterは政府要人や有名人も数多く使っているし、twitter.comの画面で確認する限り、<a href="http://twitter.com/hatoyamayukio">鳩山由紀夫首相</a>や<a href="http://twitter.com/kharaguchi">原口一博総務相</a>などの閣僚の方々は携帯から書き込みをされることも多いようなので、仮に脆弱性があった場合、影響も大きくなると思った。原口総務相に関しては、記者団からの「<a href="http://bizmakoto.jp/makoto/articles/1001/23/news004_4.html#ah_hara3.jpg">Twitterの質問を受けて、つぶやきを確認する原口氏</a>」という報道写真も公開されているので、（スタッフ任せではなく）自ら携帯電話を使いこなしてtwtr.jpにアクセスしておられることは間違いないだろう。
</p>
<p>
手始めにtwtr.jpのIPアドレスを別のドメインにセットして、携帯電話からアクセスすると、正常に画面が表示される（右の写真）。これはまずい。このため、DNS Rebindingを使ってなりすましができてしまわないか調べることにした。当然ながら、不正アクセス禁止法に抵触しないよう、自分のアカウントを使用して確認を行った。
<br clear=right>
</p>
<h4>調査の概要</h4>
<p>
調査にあたっては、自宅の調査用サーバと調査専用のドメインを用いた。DNS Rebindingを使ったかんたんログインのなりすましは、<a href="http://www.hash-c.co.jp/info/20091124.html">iモードIDを用いた「かんたんログイン」のDNS Rebinding脆弱性</a>を発表する際に実験で確認していたが、twtr.jpのログイン画面は、次の点で私の実験とは異なっていた。
</p>
<ul>
<li>実験ではGETメソッドだったが、twtr.jpはPOSTを使用
<li>twtr.jpはログイン時にトークンの受け渡しをしていた
</ul>
<p>認証機能は副作用を伴うので本来はPOSTメソッドを使うのが正しいし、トークンは、外部から認証リクエストを強要される行為（CSRFに似ているが、認証前なのでCSRFではない）を防ぐためだろう。デジタルガレージ社の実装はセキュリティ上の考慮がなされていると感じた。
</p><p>
しかし、DNS Rebindingを使用すれば、ログイン画面のトークンを読み出すことが可能である。すぐに確認作業が終わるだろうと思っていたが、意外なところで失敗した。ログイン・リクエストのPOSTがうまくいかないのだ<span class="footnote">*1</span>。早く確認を終わらせないと、もたもたしているうちに脆弱性を悪用されるとまずい。結局、XMLHttpRequestをあきらめ、IFRAME要素を用いることにした。
</p><p>
最初、IRAME要素をDOMで動的に作ったりしていたのだが、IFRAME内のFORMをうまくSUBMITできない。このため、以下のような構成にした。検証コードを公開すると、スクリプトキディが他のサイトで悪用するといけないので、コードは非公開とする。
</p>
<pre>
<img src="/img/fig01.png" align="right">
一般ユーザ（被害者）からリクエストあり
①DNS情報書き換え　→　これ以降、ワナサイトは twtr.jpのIPアドレスを指す

・以下はIFRAME内の処理
　②ログイン画面を要求 → 認証成功
　③トークン取り出し　→　ログイン画面のINPUTにセット（写真2）
　④ログイン実行　→ セッションIDがCookieにセットされる（写真3）

・以下はIFRAME外の処理
　⑤CookieをINPUTにセット
　⑥Cookie値を情報収集サーバにPOST

以下は、攻撃者の立場
・セッションID受信を確認
・別の携帯電話にCookieをセット
・twtr.jpにアクセス　→　なりすましを確認
・書き込みをしてみる → 成功（写真4、写真5）
</pre>

<table border=0>
<tr>
<td valign="top">写真2<br><img src="/img/dnsr01.jpg"></td>
<td valign="top">写真3<br><img src="/img/dnsr02x.jpg"></td>
<td valign="top">写真4<br><img src="/img/dnsr03.jpg"></td>
</tr>
<tr>
<td colspan=3>
写真5<br>
<img src="/img/dnsr03x.png"></td>
</tr>
</table>
<p>写真2はトークンを受信した様子、写真3はIFRAME上でログイン後にCookie上のセッションIDをINPUTにセットしている様子である。このセッションIDを別の端末にセットして、書き込みをしてみたところが写真4である。</p>
<h4>通報・届出およびデジタルガレージ社の対応</h4>
<p>脆弱性を確認したので、twtr.jpの運営元である株式会社デジタルガレージに通報するとともに、IPAの脆弱性届出窓口に届け出た。その経緯を時系列で示す。</p>
<pre>
2010/01/14 深夜  脆弱性の確認完了
2010/01/15 11:37 デジタルガレージ社への通報
2010/01/15 12:52 IPAへの届出 取扱い番号 IPA#04364080 として受信される
2010/01/15 19:18 IPAより届出受理および取り扱い開始の連絡
2010/01/15 21:51 デジタルガレージ社の担当者より修正済みの返信。手元でも修正を確認。
2010/01/19 10:53 IPAより修正完了の連絡。その後取り扱い終了となる。
</pre>
<p>下図に、修正を確認した様子を写真で示す。</p>
<img src="/img/dnsr04x.jpg">
<p>通知からわずか10時間あまりでの修正である。
<a href="http://takagi-hiromitsu.jp/diary/20100221.html#p01">高木浩光＠自宅の日記 - はてなのかんたんログインがオッピロゲだった件</a>によると、はてなは通知から修正完了まで20日も掛かったようだが（修正内容は異なるものの）株式会社デジタルガレージの対応の素早さは際だっている。</p>
<h4>脆弱性の影響範囲</h4>
<p>当該脆弱性の影響を受けるユーザは以下の条件を全て満たす利用者である。</p>
<ol>
<li>twtr.jpを一度でも使ったことがある
<li>iモードブラウザ2.0の対応機種(2009年夏モデル以降)の利用者
<li>iモードIDを通知設定をONにしている（デフォルトはON）
<li>JavaScriptの設定を有効にしている（デフォルトは有効）
</ol>
<p>携帯電話のユーザは、大半の方がデフォルト設定で端末を使っていると思われるので、簡単に言えば、iモードブラウザ2.0端末でtwtr.jpを使ったことのあるユーザ、ということになる。</p>
<p>当該脆弱性の影響は、セッションハイジャックによって受ける影響と等しい。すなわち、ワナサイトを閲覧してしまったユーザの当該ユーザでの投稿、ダイレクトメッセージの送信、ダイレクトメッセージの履歴閲覧、自己紹介やプロフィール画像の変更などである。また、「メールでツイートの設定」画面から投稿用メールアドレスを確認しておけば、後からいつでも当該アカウントでのつぶやきが行える。個人情報に関しては、メールアドレスも含めて閲覧できる内容はあまりないようだ。</p>
<p>先にtwtr.jpのユーザの例として挙げた鳩山首相や原口総務相が仮にワナサイトを閲覧させられた場合は、首相や総務相のアカウントで、攻撃者は任意のつぶやきが行えたことになる。</p>
<h4>保険的対応</h4>
<p><img src="/img/mail-tweet01x.jpg" align="right">twtr.jpの脆弱性を悪用された書き込みなどは、私の知る限りは公表されていないようだが、脆弱性が修正された今でも油断はできない。仮に、攻撃者がなりすましを成功させていた場合、後から書き込みをする手段があるからだ。それは前述の「メールでツイート」機能を利用する方法だ。これは、その名の通りメール経由でtwitterの投稿をするもので、ユーザ毎の専用メールアドレスに文章を送信すると、その内容がtwitterに投稿される。右の写真は、私の「専用の投稿先メールアドレス」を表示させたものである。このメールアドレスはいつでも変更できるので、twtr.jpユーザは念のため変更しておいた方が良いだろう。</p>
<p>また、twtr.jpはかんたんログインを禁止設定することができない。メニュー上は「各種設定」から「かんたんログインの無効化」というメニューがあるが、試してみたところ、かんたんログインの設定内容を削除するだけで、その後パスワード認証でログインすると、再びかんたんログインが有効となる。このため、ユーザがtwtr.jp上でかんたんログイン設定を残したくない場合は、twtr.jpにアクセスするたびに「かんたんログインの無効化」を実行する（現実的ではない）か、iモードIDを無効化するしかないだろう。iモードIDは、iモードのマイメニューから無効化できる。
</p>
<p>利用者がDNS Rebinding攻撃を避ける目的では、JavaScriptの無効化が現実的かつ有効な方法だと考える。</p>
<br clear="right">
<h4>かんたんログイン手法の脆弱性に対する責任は誰にあるのか（再）</h4>
<p>デジタルガレージ社がかんたんログインのDNS Rebinding問題を対策していなかった理由は何だろうか。おそらく、単純にこの問題を知らなかったのだろう。無理もない。<a href="http://www.hash-c.co.jp/info/20091124.html">私が昨年11月に公表していた</a>とはいえ、小さなセキュリティ会社が公表した内容まで含めて、セキュリティ情報をすべて拾い上げて検証・対応しなければならないとするのも酷な話だと思う。しかも、脆弱性を通知したらその日のうちに対策する能力がデジタルガレージ社にあったのだ。IPAの届出制度は、個別のアプリケーションやWebサイトの脆弱性を扱うもので、かんたんログインのような「認証手法」は取り扱い対象外だ<span class="footnote">*2</span>。このあたり、問題を周知できない自分自身の力のなさを痛感するとともに、やはり携帯電話事業者に『<a href="http://takagi-hiromitsu.jp/diary/20100221.html#p01">どうやったら「かんたんログイン」なるものが実現できるのか、ちゃんとした実装方法の公式解説を出</a>』してもらわないと、この種の問題はなくならないだろうと改めて感じた。</p>

</p>
<div class="footnote">
	<p class="footnote">*1&#160;これは、後にiモードブラウザ2.0の制限のためだと分かった。<a href="http://www.tokumaru.org/d/20100118.html#p02">こちら</a>を参照されたし</p>
	<p class="footnote">*2&#160;だからtwtr.jpという個別サイトの脆弱性は届け出た</p>
</div>

<p><a href="http://www.tokumaru.org/d/20100222.html#c">ツッコミを入れる</a></p>]]></content:encoded>
</item>
<item rdf:about="http://www.tokumaru.org/d/20100212.html#p01">
<link>http://www.tokumaru.org/d/20100212.html#p01</link>
<xhtml:link rel="alternate" media="handheld" type="text/html" href="http://www.tokumaru.org/d/20100212.html#p01" />
<dc:date>2010-02-22T11:06:44+09:00</dc:date>
<title>かんたんログイン手法の脆弱性に対する責任は誰にあるのか</title>
<dc:creator>徳丸浩(ockeghem)</dc:creator>
<description>id:ikepyonの日記経由で、NTTドコモのサイトに以下のセキュリティ・ガイドラインが掲示されていることを知った。    iモードブラウザ機能の多様化により、機種によってiモードサイトにおいてもJavaScriptを組み込んだ多様な表現、CookieやReferer情報を有効に活用したサイト構築が行えるようになりました。 しかし、PC向けインターネットサイト同様に、セキュリティ対策が十分に行われていないサイトでは、そのサーバの脆弱性を突き（クロスサイトスクリプティング、SQLインジェクション、DNSリバインディングなど様々な攻撃手法が存在しています）、これらの機能が悪用される危険性があります。十分にご注意ください。   [作ろうiモード：iモードブラウザ | サービス・機能 | NTTドコモより引用]  XSSやSQLインジェクションと並んで、DNSリバインディングというマニアックな手法が紹介されていることは驚きだが、おそらく私が昨年発表したiモードIDを用いた「かんたんログイン」のDNS Rebinding脆弱性のことを指しているのであろう。 しかし、引用部の表現には違和感が..</description>
<content:encoded><![CDATA[<h3>かんたんログイン手法の脆弱性に対する責任は誰にあるのか</h3><p>
<p><a href="http://d.hatena.ne.jp/ikepyon/">id:ikepyon</a>の<a href="http://d.hatena.ne.jp/ikepyon/20100210#p1">日記</a>経由で、<a href="http://www.nttdocomo.co.jp/">NTTドコモ</a>のサイトに以下のセキュリティ・ガイドラインが掲示されていることを知った。
</p>
<p></p>
<blockquote cite="http://www.nttdocomo.co.jp/service/imode/make/content/browser/index.html" title="作ろうiモード：iモードブラウザ | サービス・機能 | NTTドコモ">
<p>iモードブラウザ機能の多様化により、機種によってiモードサイトにおいてもJavaScriptを組み込んだ多様な表現、CookieやReferer情報を有効に活用したサイト構築が行えるようになりました。</p>
<p>しかし、PC向けインターネットサイト同様に、セキュリティ対策が十分に行われていないサイトでは、そのサーバの脆弱性を突き（クロスサイトスクリプティング、SQLインジェクション、<b>DNSリバインディング</b>など様々な攻撃手法が存在しています）、これらの機能が悪用される危険性があります。十分にご注意ください。</p>

</blockquote>
<p class="source">[<cite><a href="http://www.nttdocomo.co.jp/service/imode/make/content/browser/index.html" title="作ろうiモード：iモードブラウザ | サービス・機能 | NTTドコモより引用">作ろうiモード：iモードブラウザ | サービス・機能 | NTTドコモ</a></cite>より引用]</p>

<p>XSSやSQLインジェクションと並んで、DNSリバインディングというマニアックな手法が紹介されていることは驚きだが、おそらく私が昨年発表した<a href="https://www.hash-c.co.jp/info/20091124.html">iモードIDを用いた「かんたんログイン」のDNS Rebinding脆弱性</a>のことを指しているのであろう。</p>
<p>しかし、引用部の表現には違和感がある。DNSリバインディング自体は既知の攻撃手法であるが、「PC向けインターネットサイト」に対する攻撃ではなく、インターネットサイトを閲覧しているPC自身やファイアウォールの内側のローカルネットワーク上の端末に対する攻撃手法として知られている。このあたりの解説については、<a href="http://www.tokumaru.org/d/20071126.html#p01">ここ</a>や<a href="http://bakera.jp/ebi/topic/3976">ここ</a>を参照頂きたい。</p>
<p>しかも、先のセキュリティ・ガイドラインには、これら脆弱性についての説明はなく、「十分にご注意ください」とあるだけで、参考情報としては<a href="http://www.ipa.go.jp/">IPAのトップページ</a>が紹介されている。</p>
</p>
<p>
<blockquote cite="http://www.nttdocomo.co.jp/service/imode/make/content/browser/index.html" title="作ろうiモード：iモードブラウザ | サービス・機能 | NTTドコモ">
<p>なお、セキュリティ対策情報については、「独立行政法人 情報処理推進機構」（IPA）が公開する情報なども参考にしてください。</p>

<p><a href="http://www.ipa.go.jp/">独立行政法人 情報処理推進機構（IPA）のウェブサイト</a>へ</p>
<p></p>
</blockquote>
<p class="source">[<cite><a href="http://www.nttdocomo.co.jp/service/imode/make/content/browser/index.html" title="作ろうiモード：iモードブラウザ | サービス・機能 | NTTドコモより引用">作ろうiモード：iモードブラウザ | サービス・機能 | NTTドコモ</a></cite>より引用]</p>


<p>IPAにDNSリバインディングの解説があったかなと疑問に思い、「<a href="http://www.google.co.jp/search?q=DNS+%22%E3%83%AA%E3%83%90%E3%82%A4%E3%83%B3%E3%83%87%E3%82%A3%E3%83%B3%E3%82%B0%22+site%3Aipa.go.jp">DNS "リバインディング" site:ipa.go.jp</a>」や「<a href="http://www.google.co.jp/search?q=DNS+rebinding+site%3Aipa.go.jp">DNS rebinding site:ipa.go.jp</a>」などのキーワードで検索してみたが、ヒットしない。ひょっとしたらどこかに存在する可能性はあるが、リンクもなく、サーチでも引っかからないのでは、ないのと同じだ。これでは、単に危険があるから注意しろと言っているだけで、解決策を示していないことになる。</p>
<p>このような状況から、この文書は次のような意図をもって書かれたのではないかという感想を持った。</p>

</p>
<ul>
<li>同DNSリバインディングの問題は、携帯端末や事業者設備の問題ではなく、Webアプリケーション側の問題である（<s>私も同意</s>追記参照）
</li>
<li>NTTドコモは、かんたんログインのDNSリバインディング脆弱性を、PCも含め昔から存在していた問題と印象づけたいのではないか（実際は違う）
</li>
<li>DNSリバインディングの解決方法を明確にリンクしなかったのは、「NTTドコモ公認の解決策」という印象を与えることを避けたかったからではないか
</li>
<li>一方で、DNSリバインディングに対する注意喚起を行ったという実績は作りたいのではないか
</li>
</ul>
<p>

<p>「実績作り」で思い浮かぶのは、Yomiuri Onlineにも掲載された以下の記事だ。この記事は、かんたんログインのDNSリバインディング脆弱性に関して、NTTドコモのコメントを掲載している。</p>

<blockquote cite="http://www.yomiuri.co.jp/net/news/20100112-OYT8T01018.htm" title="ドコモ携帯、情報流出の恐れ…最新２９機種">
<p>　ＮＴＴドコモでは、公式サイトを運営する約３０００社には注意喚起したが、それ以外の無数にある「勝手サイト」には「ジャバスクリプトの安全な利用はサイトを作る側にとって基本的知識であり、具体的に説明はしていない」という。</p>

</blockquote>
<p class="source">[<cite><a href="http://www.yomiuri.co.jp/net/news/20100112-OYT8T01018.htm" title="ドコモ携帯、情報流出の恐れ…最新２９機種より引用">ドコモ携帯、情報流出の恐れ…最新２９機種</a></cite>より引用]</p>

<p>勝手サイトに対して従来説明していなかったので、新たに説明したということなのかもしれない。しかし、先の説明ではまったく不十分だ</p>
<p>NTTドコモ（および他の携帯電話事業者）は、かんたんログインのセキュリティ問題について、そろそろ態度を明確にする必要があるのではないだろうか。その態度とは、以下の選択肢のどれを選ぶのかということだ。</p>

</p>
<ul>
<li>かんたんログインという手法は各サイトが独自に実装しているもので、携帯電話事業者はガイドラインなども提示していないので責任は一切負わない
</li>
<li>かんたんログインは、携帯電話事業者が提供している端末固有IDの応用であるので、安全な使い方を示すなど携帯電話事業者としても一定の責任が生じる
</li>
</ul>
<p>
<p>くだんの「セキュリティ・ガイドライン」を読む限り、NTTドコモは（本音では）事業者として一切責任を負わないと姿勢なのだと想像する。しかし、そう明言すると反発も予想されることから、あいまいな態度をとっているように見うけられる。</p>
<p>しかし、このようなあいまいな状況がもっとも危険なのだ。かんたんログインがこれだけ普及した現在でも、この手法に対する責任がどこにあるのか、非常に不明確な状態が続いている。最終的には、Webサイトの運営者が責任を負うべき問題ではあるだろうが、中小零細企業が多いケータイサイトの運営者がそのような問題意識を持っているとは考えにくいし、DNSリバインディングを含む複雑なセキュリティ問題を独自に研究・解決する能力もないだろう。であれば、日本独自の進化を遂げた携帯電話コンテンツのセキュリティ問題に対して、もっと広い枠組みでの検討が行われる必要があるし、そこにもっとも近い位置にいるのが携帯電話事業者であると私は考える。</p>
<h4>追記(2010/2/16)</h4>
<p>括弧内で「私も同意」と書いた部分について指摘を頂戴しました。</p>
<blockquote cite="http://b.hatena.ne.jp/HiromitsuTakagi/20100215#bookmark-19264744" title="HiromitsuTakagiのブックマーク / 2010年2月15日 (3)">
<p>ここは同意しちゃだめ。Webアプリ側は「対策可能」なのであって、元からそこに問題があるわけじゃない。</p>

</blockquote>
<p class="source">[<cite><a href="http://b.hatena.ne.jp/HiromitsuTakagi/20100215#bookmark-19264744" title="HiromitsuTakagiのブックマーク / 2010年2月15日 (3)より引用">HiromitsuTakagiのブックマーク / 2010年2月15日 (3)</a></cite>より引用]</p>

<blockquote cite="http://bakera.jp/ebi/topic/4054" title="DNS Rebinding問題の所在 | 水無月ばけらのえび日記">
<p>少なくともWebアプリケーション側の「不具合」ではないように思いますし、実際のところはこんな感じではないでしょうか。<ul></p>
<p><li>iモードブラウザ2.0対応のdocomo端末は、DNS Rebindingの攻撃に対して脆弱である。</p>
<p><li>端末の問題であるため端末側で対応することが望ましいが、名前解決はdocomoのゲートウェイ側で行われる場合があり、端末側では対応が難しい。</p>
<p><li>docomoのゲートウェイの問題についてはdocomo側で対応することが望ましいが、問題の性質上、対応が難しい (参考: Re:「docomoケータイのDNS Rebinding問題、全国紙で報道」)。</p>
<p><li>これらの問題に対してはWebサイト側で対応することが可能であり、しかも簡単に対応できる方法が存在する。</p>
<p><li>従って、Webサイト側での対応が推奨される。</p>
<p></li></p>

</blockquote>
<p class="source">[<cite><a href="http://bakera.jp/ebi/topic/4054" title="DNS Rebinding問題の所在 | 水無月ばけらのえび日記より引用">DNS Rebinding問題の所在 | 水無月ばけらのえび日記</a></cite>より引用]</p>

<p>まことに指摘の通りで、私の本意は、ばけらさんがわかりやすく要約していただいたとおりです。</p>
<p>したがって、携帯電話事業者はこの問題に対して免責されるわけではなく実施可能な対策はとるべきであり、具体的には、<a href="https://www.hash-c.co.jp/info/20091124.html">iモードIDを用いた「かんたんログイン」のDNS Rebinding脆弱性</a>に書いたように、DNSキャッシュの最短TTLを長くする程度の対策はとるべきだと考えます。</p>
<h4>追記(2010/2/22)</h4>
<p>かんたんログインのDNS Rebinding脆弱性の実例として、「<a href="http://www.tokumaru.org/d/20100222.html#p01
">ケータイtwitter(twtr.jp)においてDNS Rebinding攻撃に対する脆弱性を発見・通報し、即座に修正された</a>」を書きましたのでご参照ください。</p>
</p>

<p><a href="http://www.tokumaru.org/d/20100212.html#c">ツッコミを入れる</a></p>]]></content:encoded>
</item>
<item rdf:about="http://www.tokumaru.org/d/20100118.html#p02">
<link>http://www.tokumaru.org/d/20100118.html#p02</link>
<xhtml:link rel="alternate" media="handheld" type="text/html" href="http://www.tokumaru.org/d/20100118.html#p02" />
<dc:date>2010-01-18T07:21:48+09:00</dc:date>
<title>iモードブラウザ2.0のXMLHttpRequestでPOSTデータの扱いが困難になった</title>
<dc:creator>徳丸浩(ockeghem)</dc:creator>
<description>このエントリでは、iモードブラウザ2.0の制限により、XMLHttpRequestでPOSTメソッドの利用が困難になっていることを確認したので報告する。 iモードブラウザ2.0のJavaScriptを試していて、POSTメソッドでデータが渡せていないことに気がついた。以下のようなプログラムで検証してみた。  【post.html】 html head script function test() {   try {     var requester = new XMLHttpRequest();     requester.open('POST', '/dumppost.php', true);     requester.onreadystatechange = function() {        if (requester.readyState == 4) {            onloaded(requester);        }     };     requester.setRequestHeader(&quot;Content-Type&quot; , &quot;applicatio..</description>
<content:encoded><![CDATA[<h3>iモードブラウザ2.0のXMLHttpRequestでPOSTデータの扱いが困難になった</h3><p>
<p>このエントリでは、iモードブラウザ2.0の制限により、XMLHttpRequestでPOSTメソッドの利用が困難になっていることを確認したので報告する。</p>
<p>iモードブラウザ2.0のJavaScriptを試していて、POSTメソッドでデータが渡せていないことに気がついた。以下のようなプログラムで検証してみた。</p>
<pre>
【post.html】
&lt;html&gt;
&lt;head&gt;
&lt;script&gt;
function test() {
  try {
    var requester = new XMLHttpRequest();
    requester.open('POST', '/dumppost.php', true);
    requester.onreadystatechange = function() {
       if (requester.readyState == 4) {
           onloaded(requester);
       }
    };
    requester.setRequestHeader("Content-Type" , "application/x-www-form-urlencoded");
    requester.send("aaa=bbb&ccc=ddd");
  } catch (e) {
    res = requester.responseText;
    document.getElementById('result').innerHTML = e.toString();
  }
}

function onloaded(requester) {
  res = requester.responseText;
  document.getElementById('result').innerHTML = res;
}
&lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;input type=button value="go" onclick="test()"&gt;
&lt;div id="result"&gt;&lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;

【dumppost.php】
&lt;?php
echo "aaa=" . htmlspecialchars($_POST['aaa'], ENT_QUOTES, 'Shift_JIS') . "&lt;br&gt;";
echo "ccc=" . htmlspecialchars($_POST['ccc'], ENT_QUOTES, 'Shift_JIS') . "&lt;br&gt;";
?&gt;
</pre>
<p>実行結果は、以下のようになった。まずはChromeのものだが、IEやFirefoxでも同等の結果だ。</p>
<img class="left" src="http://www.tokumaru.org/d/images/20100118_0.png" alt="Choromeでの結果" title="Choromeでの結果" width="545" height="198">
<br clear=left>
<p>次に、ドコモP-07Aによる結果</p>
<img class="left" src="http://www.tokumaru.org/d/images/20100118_1.jpg" alt="P-07Aでの結果" title="P-07Aでの結果" width="280" height="153">
<br clear=left>
<p>ドコモの場合を検証するために、Webサーバーに来ているリクエストをキャプチャしてみた。</p>
<pre>
POST /dumppost.php HTTP/1.1
X-UE-Version: 1
Host: XXXXXXXXXXXXX
User-Agent: DoCoMo/2.0 P07A3(c500;TB;W24H15)
Content-Type: text/xml
Content-Length: 15

aaa=bbb&ccc=ddd
</pre>
<p>ご覧のようにPOSTデータそのものは送信されてきているが、Content-Typeがtext/xmlになっているために、Webアプリケーション側で受け取れないようだ。</p>
<p>JavaScript側では、この値をapplication/x-www-form-urlencodedに変更しているが、<a href="http://d.hatena.ne.jp/ockeghem/20091117/p1">P-07AでもJavaScriptが再開され、あらたな制限がみつかった</a>で報告したように、setRequestHeaderが無効化されているために、この設定が無視されていることが原因のようだ。</p>
<p>これは明らかに、setRequestHeader無効化の副作用であるが、その代償は大きいように思う。PHP以外に、ASP/ASPX、J2EE(JSP)にこのデータを入力してみたが、いずれも値を読み取ることはできなかった。一方、PerlのCGIモジュールでは、POSTDATAという名称のデータとして、POSTデータ全体を読み取ることができた。Perl以外の場合でも、Webサーバーにデータ自体は到達しているのだから値を利用する手段はあるかもしれないが、私が調べた範囲では分からなかった。</p>
<p>上記の結果として、AjaxでPOSTメソッドを扱うには、標準的でない方法を用いる必要があるわけだが、その方法を検討してみた。</p>
<ol>
<li>POSTをあきらめてGETを使う
<li>Perlのように、text/xml形式のデータを読み出せる言語を選択する
<li>DOMにより、IFRAME内にFORMを作成してSUBMITする
</ol>
<p>このうち、上記1.については、セキュリティ上の問題が発生し得る。Ajaxのセキュリティ対策として、「GETメソッドを拒絶する」という方法があるからだ。具体的には、SCRIPT要素を使ってSame Origin Policyを回避してAjaxデータを読み出す手法に対抗して、SCRIPT要素では必ずGETメソッドになることから、POSTのみを許容することで対策するという方法だ。既存のアプリケーションがこのような手法によりセキュリティ対策されている場合に、安易にGETメソッドを許容してしまうと、セキュリティホールが混入することになりかねない。</p>
<p>3.については、私が試した範囲ではうまくいっていない。JavaScriptからIFRAME内のFORM操作がうまくいかないのだ。これも、ひょっとすると制限を掛けているのかもしれない。アドホックな方法ならありそうだが、まだ十分に検証できていない。</p>
<p>一つの疑問は、このような情報がインターネット上に見あたらないことだ。AjaxでPOSTメソッドが使えないというのはとんでもないことだが、検索してもそのような情報がみあたらないのだ。iモードブラウザ2.0のAjaxを誰も使っていないのか、それとも事業者が恐ろしくて口をつぐんでいるのか。</p>
<p>しかし、このような技術情報が流通していかない限り、iモードブラウザ2.0のJavaScriptを使ったコンテンツは普及していかないだろう。NTTドコモにはさらなる情報開示を期待したいし、ケータイWebの開発者にも、もっとブログなどでの情報公開を期待する。</p>


</p>

<p><a href="http://www.tokumaru.org/d/20100118.html#c">ツッコミを入れる</a></p>]]></content:encoded>
</item>
<item rdf:about="http://www.tokumaru.org/d/20100118.html#p01">
<link>http://www.tokumaru.org/d/20100118.html#p01</link>
<xhtml:link rel="alternate" media="handheld" type="text/html" href="http://www.tokumaru.org/d/20100118.html#p01" />
<dc:date>2010-01-18T07:21:48+09:00</dc:date>
<title></title>
<dc:creator>徳丸浩(ockeghem)</dc:creator>
<description></description>
<content:encoded><![CDATA[<p>



</p>

<p><a href="http://www.tokumaru.org/d/20100118.html#c">ツッコミを入れる</a></p>]]></content:encoded>
</item>
</rdf:RDF>
