JPCERT コーディネーションセンター

PRE09-C. セキュアな関数を非推奨関数や時代遅れの関数に置き換えない

既存のAPIが変更された場合など、既存のコードに含まれるある識別子をまとめて他の識別子に変更するために、マクロが活用されることがよくある。一般にこのようなアプローチはリスクをともなうものだが、非推奨関数や時代遅れの関数への置き換えはとくに危険である。非推奨関数は C 言語規格および「技術に関する正誤表」で定義されている。時代遅れの関数は「MSC24-C. 非推奨関数や時代遅れの関数を使用しない」で定義されている。

MSC24-C. 非推奨関数や時代遅れの関数を使用しない」に適合すればこのレコメンデーションにも適合することになるが、このレコメンデーションでは、よりセキュアでない関数への置き換えの危険性について述べている。

違反コード

Internet Systems Consortium (ISC) の Dynamic Host Configuration Protocol (DHCP) 実装には、複数のバッファオーバーフローの脆弱性が存在した[VU#654390]。ISC DHCP は、ログファイルへの出力のために vsnprintf() 関数を使って様々な文字列を組み立てていた。vsnprintf() は Open Group Base Specifications Issue 6 [Open Group 2004] や C 言語規格で定義されている関数である。vsnprintf() をサポートしていないシステムのために、vsprintf() を使って vsnprintf() 関数を定義するインクルードファイルが作成された。以下のコード例にそれを示す:

#define vsnprintf(buf, size, fmt, list) \
vsprintf(buf, fmt, list)

vsprintf() 関数は範囲チェックを行わない。したがって、サイズ引数は破棄されており、信頼できないデータが引数に使われるとバッファオーバーフローにつながる可能性がある。

適合コード

次の適合コードでは、vsnprintf() を実装するコードを my_stdio.h に用意しておき、vsnprintf() が提供されていない場合には vsnprintf() をインクルードしている。vsnprintf() を提供していないシステムではシンボル __USE_ISOC99 が定義されていないことが前提である。

#include <stdio.h>
#ifndef __USE_ISOC99
  /* vsnprintf() を再実装 */
  #include "my_stdio.h"
#endif
リスク評価

セキュアな関数をよりセキュアでない関数に置き換えるのはとても危険なことである。なぜなら開発者は、実際には行われていないセキュリティチェックを関数が行ってくれていると信じこんでしまうからである。これはたとえば、ISO/IEC TR 24731-1 関数のように全てのプラットフォームで利用できるとは限らない、よりセキュアな関数を採用しようとするときに、問題になる可能性がある。(「STR07-C. 境界チェックインタフェースを使用し、文字列操作を行う既存のコードの脅威を緩和する」を参照。)

レコメンデーション

深刻度

可能性

修正コスト

優先度

レベル

PRE09-C

P18

L1

自動検出
ツール バージョン チェッカー 説明
PRQA QA-C 8.1 Secondary Analysis 実装済み
関連するガイドライン
CERT C++ Secure Coding Standard PRE09-CPP. Do not replace secure functions with less secure functions
ISO/IEC TR 24772:2013 Executing or Loading Untrusted Code [XYS]
MITRE CWE CWE-684, Failure to provide specified functionality
参考資料
[Open Group 2004] vsnprintf()
[Seacord 2013] Chapter 6, "Formatted Output"
[VU#654390]  
翻訳元

これは以下のページを翻訳したものです。

PRE09-C. Do not replace secure functions with deprecated or obsolescent functions (revision 76)

Top へ

Topへ
最新情報(RSSメーリングリストTwitter