はじめに
脆弱性がたまに話題になりますが、一週間の間にいくつの脆弱性が公開されているか知っていますか?
本記事では、2024/04/27~2024/5/03の一週間の間に公開されたCVEの件数とその中で個人的に気になったものについてまとめてみました。
2024/04/27~2024/05/03に公開されたCVE
概要 | 件数 |
---|---|
公開されたCVEの件数 | 1647件 |
CVSSスコアが7.0以上であるCVEの件数 | 694件 |
今週は1647件と公開されたCVEの数が多数ありました。先週と比べると3倍以上です。先週は約500件程度と平均は約1000件程度少ない数でしたが、平均と比べても約1.5倍と多いです。
また、CVSSスコアが7.0以上であるCVEの件数も多いです。先週や先々週はCVEの公開件数は異なりますが、CVSSスコアが7.0以上であるCVEは2,3割でした。しかし、今週は約4割とこの割合も多いです。
なぜ、このような差があるのか気になります。様々な理由(政治的なこととか)があると思いますが、こういったディープなところも考えていきたいです。
先週のCVEの件数:https://qiita.com/fum1h1to/items/3972601f6282623d0288
先々週のCVEの件数:https://qiita.com/fum1h1to/items/b5597a97bd9f585b7862
気になったもの
CVE-2024-2876
概要
CVSS Base Score: 9.8
EPSS Score: 1.15%
WordPress向けプラグイン「Icegram Express」に見つかった脆弱性。
「Icegram Express」は登録者に対するメールによるマーケティング機能を提供するプラグインであり、9万以上のWordPress環境にインストールされているようです。
このプラグインの5.7.14以前のバージョンには、ユーザが提供するパラメータのエスケープが不十分であるためにSQLインジェクションの脆弱性があります。これにより、認証されていない攻撃者が、データベースから機密情報を抽出できてしまいます。
このプラグインは、有効インストール数が9万以上と多くのWordPressで使用されており、使い方を説明する記事や動画などもありました。こうしたプラグインにSQLインジェクションの脆弱性が見つかったということで、悪用される確率を示すEPSS scoreも高い数値を示しているようです。
また、このプラグインは過去にもCVE-2022-45810の脆弱性があり、今回と同じくCVSS base Scoreが高い脆弱性でした。
詳細(脆弱性の仕組み)
脆弱性があったのはIG_ES_Subscribers_Query
クラスのrun
関数です。
このコードでは、ユーザからのリクエストに応じてSQLを構築していますが、その構築の際にSQL文字列エスケープの不備があり、今回のような脆弱性に発展してしまったようです。
バージョン5.7.14からの変更履歴を見てみると、追加のSQL文や、SQL文字列エスケープのための関数であるesc_sql
が追記されているのがわかります。
対策
- 5.7.15以上にバージョンアップ
脆弱性を修正したversionは公開されています。脆弱性のあるversionは5.7.14以下。
対策としては、5.7.15以上にアップデートすることです。
- セキュリティ・プラグインの導入
脆弱性が修正される前の攻撃を防ぐという観点からもセキュリティ・プラグインの導入は有効と考えます。
我々、開発者はどうするべきか
この脆弱性から我々開発者は何を学べばよいでしょうか?
SQLインジェクションの基本的な対策は、SQL文字列をエスケープすることです。ただ、ソースコードを拝見すると、そうした基本的な対策を取りにくい状況にあったのではないかと私は思いました。
読みにくいコード
脆弱性のあったIG_ES_Subscribers_Query
クラスのrun
関数には、多数あるパラメータを処理するため、if文が多量にありました。また、条件に応じて$join
という変数にSQLを追記するといった書き方になっていました。
下記はコードの一部です。
$join = "LEFT JOIN {$wpbd->prefix}ig_actions AS $alias ON $alias.type = " . IG_LINK_CLICK . " AND subscribers.id = $alias.contact_id";
if ( ( '_click' === $field || '_click__not_in' === $field ) ) {
if ( $value ) {
$join .= " AND $alias.campaign_id IN (" . implode( ',', array_filter( $value, 'is_numeric' ) ) . ')';
} else {
$join .= " AND $alias.campaign_id IS NOT NULL AND $alias.campaign_id <> 0";
}
} elseif ( '_click_link' === $field || '_click_link__not_in' === $field ) {
$join .= " AND $alias.link_id = {$alias}{$field}.ID";
// 一部省略
if ( ! empty( $campaigns ) ) {
$join .= " AND $alias.campaign_id IN (" . implode( ',', array_filter( $campaigns, 'is_numeric' ) ) . ')';
}
$joins[] = "LEFT JOIN {$wpbd->prefix}ig_links AS {$alias}{$field} ON {$alias}{$field}.link IN ('" . implode( "','", $value ) . "')";
}
多量のパラメータがあるため、しょうがないような気はしてしまいますが、このようなコードによって、本来できるはずの対策を行えなかったのではと私は思いました。
バグや脆弱性に発展させないためにも、コーディングするときは、分かりやすいコードを心がけていくべきですね。
おわりに
改めて、分かりやすいコードの大切さを理解しました。でも、開発中は機能の実装に集中してしまうので、細かいところに気が回らないのもとても分かります。難しい。
何かおかしな点がありましたらご指摘ください!