本サイトは、快適にご利用いただくためにクッキー(Cookie)を使用しております。
Cookieの使用に同意いただける場合は「同意する」ボタンを押してください。
なお本サイトのCookie使用については、「個人情報保護方針」をご覧ください。
先日、アメリカのラスベガスで開催されたBlack Hat USA 2015 とDEFCON 23に参加してきました。カンファレンスではセッションだけでなく、ツールの展示やCTF(Capture The Flag)なども行われていました。弊社では毎年数名のエンジニアやコンサルタントが参加していますが、筆者らは初めての参加だったので、見るもの聞くもの全てに興味が湧きました。
今回のカンファレンスではジャンルを問わずさまざまなセキュリティに関するセッションが行われ、MMSを介してAndroid端末上で不正なコードが実行される「Stagefright」の脆弱性に関するセッションや、Linuxを搭載したライフルへのハッキングに関するセッションが会場を賑わせていました。
今回のブログでは、筆者らが普段携わっているWebセキュリティに関するセッションの中から興味深かったものを取り上げ、そこからヒントを得て独自に行った検証の結果を紹介していきます。
■XSLTプロセッサにおける問題
Black HatでFernando Arnaboldi氏によりXSLT に関するセキュリティ上の問題[1]が発表されました。筆者らは今までXSLTを使用したWebアプリケーションの診断を行った経験が少なかったことから、XSLTという技術への興味もあり今回の発表には注目していました。
XSLT(XSL Transformations)はXMLデータをHTMLやTeXなどの別の形式に変換する際に用いられる言語で、現在はXSLTのバージョン1.0、2.0および3.0があります。このXSLTを解釈して変換処理を行なうXSLTプロセッサは、一般的なブラウザにも組み込まれています。
発表では、最も普及しているXSLTのバージョン 1.0を対象に、XSLTプロセッサの処理で見つかった問題が報告されました。報告された問題には、乱数生成に関する問題や同一生成元ポリシーを回避できる問題、エラーメッセージからファイルの内容を取得できる問題などがありました。
この他に、XSLTのLibxsltプロセッサにおけるformat-number関数についての報告がありました。format-number関数は引数の数値を、指定した形式の文字列へ変換する関数です。発表では以下のように10^26乗の整数値を文字列に変換した場合を例に、非常に大きな値を変換すると変換後の値に誤差が生じることを報告しました。
変換前: 100000000000000000000000000
変換後(想定値): 100,000,000,000,000,000,000,000,000
変換後(実証値): 100,000,000,000,000,000,000,002,660
実証値の下4桁が想定値とは異なっており、誤差が生じているのがわかると思います。発表の中では、この問題が及ぼす影響について言及されていませんでしたが、そもそも format-number関数は文字列を出力する関数であり、変換後の値をそのまま数値計算で利用することはできません。そのためこの問題は、帳票や画面上に出力する数値の誤表示にはつながりえますが、数値計算の誤差につながる可能性は少ないと考えられます。
数値計算の誤差については、同氏の発表内に算術演算子についての報告がありました。実数値を「+」演算子で加算する場合に、丸め誤差が発生するという内容です。
筆者らは、同様の数値計算を行うXPath・XSLT関数でも誤差が生じるのではと思い調査を行いました。その結果sum関数でも誤差が生じることを確認しましたので、その内容を紹介したいと思います。
以下は検証に利用したソースコードになります。このコードはvalue要素の値(1000.41と1001)の合計を計算するもので、期待される出力は2001.41です。
XMLファイル(test.xml)
<xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="test.xsl"?>
<num>
<value> 1000.41 </value>
<value> 1001</value>
</num>
XSLファイル(test.xsl)
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<output>
<xsl:value-of select='sum(//value)'/>
</output>
</xsl:template>
</xsl:stylesheet>
以下はIE、Firefox、Safari、Chromeの 4ブラウザに組み込まれたXSLTプロセッサを対象に検証した結果です。
IEとFirefoxでは加算した結果がわずかに減少することを確認しました。また、加算する値によってはわずかに増加することも確認しています。なお、SafariとChromeでは誤差は生じませんでしたが、値によっては情報落ち誤差等が生じる可能性があります。
今回はブラウザに組み込まれたXSLTプロセッサで検証を行いましたが、もしサーバ側のXSLTプロセッサにもこのような問題の挙動がみられた場合、どのような影響を及ぼすか考えてみます。
現在、XMLは電子部品、自動車、金融、医療などさまざまな分野で利用されており、そういった分野のシステムの内部でXSLTの数値計算が行われている可能性は充分に考えられます。
例えば、金額の計算などを行う金融や銀行などの勘定システムの内部でXSLTが使用されていたと仮定します。このようなシステムにおいて、外国為替や金利などの小数点以下も含めた値をsum関数で処理していた場合、処理後の値にわずかな誤差が生じる可能性があります。誤差が生じた値をもとに金額の計算を行ってしまうと、正しくない金額が算出されるなどの影響につながるおそれがあります。
なお、今回はXSLTの一部の関数でしか検証を行っていないため、他の関数にも数値の誤差が生じる可能性があります。
また、このような演算誤差の問題はXSLTに特有のものではありません。弊社のセキュリティ診断でも、(XSLTを使用していない)金融系のアプリケーション等において、精度が不十分なデータ型を不用意に使用しており潜在的に誤差が生じかねない状態となっている事例などがありました。
このような問題への一般的な対策は、扱う数値の範囲・精度・丸めの方法等を要件定義段階で定めて、それを実現できる言語・データ型・関数等を使用して実装することです。もちろん、テスト段階では様々な条件を想定した動作検証が必要です。
筆者らは帰国後、カンファレンス期間中の経費をドル金額の少数点以下まで含め、きっちり経理へ申請しました。弊社で使用している勘定システムに今回取り上げたような問題がないことを祈ります。
以上
おすすめ記事