Jump to content

開発者向けセキュリティ チェックリスト

From mediawiki.org
This page is a translated version of the page Security checklist for developers and the translation is 56% complete.

この文書は、開発者向けセキュリティ の補足として提供されています。 これは、一般的な開発タスクと、実行する必要のあるセキュリティ対策のリストです。

セキュリティ チェックリスト

作業の対象 チェックリスト

ブラウザーのCookie

  • $_COOKIE の代わりに $wgRequest を使用することでレビュアーの不安を軽減しましたか?
    • $wgRequest->getCookie(...) を使用して Cookie を取得しましたか?
    • $wgRequest->response()->setCookie(...) を使用して Cookie を設定しましたか?
# UserID の Cookie 値を取得しようとする。
# 注: 戻り値は信頼できず、int に強制される。
$sId = intval( $wgRequest->getCookie( 'UserID' ) );

動的コード生成

eval() 関数、create_function() 関数、preg_replace() 関数の /e パターン修飾子を使用することは避けてください。 これらの機能は強力で便利ですが、本質的に安全ではありません:[1][2]

  • 正規表現で処理されるテキストに任意の文字列を入れることが簡単で、/e パターン修飾子と組み合わせると、コード インジェクション攻撃を引き起こす可能性があります。
  • 文字列の一部であるコードを読み取り、メンテナンスすることが難しくなります。
  • 静的解析ツールは、コードの警告やエラーをキャッチできません。
  • opcode キャッシュ (APC など) は、文字列に混在するコードをキャッシュできません。
  • create_function() には、ガベージ コレクションの問題点がある場合があります。
  • ループの中に create_function() 関数がある場合、各イテレーションで新しい関数が作成されます。

これらの機能が本当に必要な場合もあります (明らかに eval.php eval(); を実行する必要がある)。しかし、ほとんどの場合、関数を分割してコールバックとして参照したいと思います。

インライン ラムダ関数を使用すると、ネイティブ構文で書かれたコードの利点を保持しながら、コールバックをインラインで作成するのが容易になります。

  • 正規表現の一部として使用される外部のすべてのものは、preg_quote ($externalStr, $delimiter) でエスケープする必要があります。 これにより、正規表現構文の一部であるすべての文字の前にバックスラッシュが挿入され、2 番目のパラメーターとして与えられた区切り文字もエスケープされます:
$str = preg_replace( "!" . preg_quote( $externalStr, '!' ) . "!", $replacement, $str );

外部プログラム

  • executed the program via Shell::command() from namespace MediaWiki\Shell?
  • quoted all arguments to external programs using the above's secure parameter passing facilities (which is basically everything except for unsafeParams())?
// Automatically escape any naughty characters
$result = Shell::command( $cmd, '--version' )
    ->params( 'some', 'extra', 'parameters' )
    ->execute();

Note that old wfShellExec()/wfEscapeShellArg() are not recommended because they make it easier for developers to miss escaping a parameter.

フォーム

GET データ

  • reduced reviewer anxiety by using $wgRequest instead of $_GET?
# Check if the action parameter is set to 'purge'
if ( $wgRequest->getVal( 'action' ) == 'purge' ) {
    ...

出力 (API、CSS、JavaScript、HTML、XML など)

Any content that MediaWiki generates can be a vector for XSS attacks.

  • used the Html and Xml helper classes?
# rawElement() escapes all attribute values
# (which, in this case, is provided by $myClass)
echo Html::rawElement( 'p', [ 'class' => $myClass  ] );
  • reduced reviewer anxiety by using ResourceLoader to deliver CSS and JavaScript resources?

利用者提供 CSS

User provided CSS (Say for use in a style attribute) needs to be sanitized to prevent XSS, as well as to disallow insertion of tracking images (via background-image), etc

  • Use the Sanitizer::checkCss method for any css received from a user, possibly along with the Html class.
# let $CSSFromUser be the user's CSS.
echo Html::rawElement( 'p', [ 'style' => Sanitizer::checkCss( $CSSFromUser ) ] );
  • For CSS provided by the extension (and not the user), this is not needed (and will remove some valid things like background-image:). However, extension provided CSS should go in stylesheets loaded by ResourceLoader, and not in style attributes.

POST データ

  • reduced reviewer anxiety by using $wgRequest instead of $_POST
  • Always validate that any POST data received is what you expect it to be
# Check if the action parameter is set to 'render'
if ( $wgRequest->getVal( 'action' ) == 'render' ) {
    ...

クエリ文字列

セッション

レビュアーの不安

  • Clearly added comments to explain unexpected or odd parts of your code?
# $wgRequest isn't yet available. Forced to use $_GET instead.
if ( $_GET['setupTestSuite'] !== null ) {
 	$setupTestSuiteName = $_GET['setupTestSuite'];
 	...

SQL クエリ


自動チェック

Some of these issues can be checked with phan-taint-check-plugin, which is required for all MediaWiki code in Wikimedia production. This is of course just a tool, and it cannot detect all issue types, and may miss issues even in the issue types it can check for.

関連項目

脚注