脆弱性についての対策・対応について

サムネイル

2025年3月21日に発覚した重大な脆弱性により、皆様には多大なるご迷惑をおかけしておりますことを、心よりお詫び申し上げます。

本記事では、この脆弱性を悪用した攻撃への対策および対応について、改めてまとめております。

対応バージョンへのアップデート

脆弱性対応バージョンへのアップデートを必ずお願いします。

影響を受けるバージョン

  • a-blog cms Ver. 3.1.37 未満のバージョン (Ver.3.1.x系)
  • a-blog cms Ver. 3.0.41 未満のバージョン (Ver.3.0.x系)
  • a-blog cms Ver. 2.11.70 未満のバージョン (Ver.2.11.x系)
  • a-blog cms Ver. 2.10.58 未満のバージョン (Ver.2.10.x系)
  • a-blog cms Ver. 2.9.46 未満のバージョン(Ver. 2.9.x系)
  • a-blog cms Ver. 2.8.80 未満のバージョン(Ver. 2.8.x系)
  • a-blog cms Ver. 2.7.x 以下全てのバージョン

3/25時点の各バージョン最新バージョン

  • Ver. 3.1.41(Ver. 3.1.x系)
  • Ver. 3.0.45(Ver. 3.0.x系)
  • Ver. 2.11.74(Ver. 2.11.x系)
  • Ver. 2.10.62(Ver. 2.10.x系)
  • Ver. 2.9.50(Ver. 2.9.x系)
  • Ver. 2.8.84(Ver. 2.8.x系)

Ver. 2.7系以下であっても脆弱性はあるため、大変お手数ですがVer. 2.8以上へのアップデートをお願いします。

現状確認されている範囲では、Ver. 2.8以上の場合のみ攻撃が成功しているようですが、念の為Ver. 2.7以下であってもバージョンアップをお願いします。

PHPのバージョンアップ

php7.0未満である場合、出来ればphp7.0以上へアップデートすることにより、よりセキュアにすることができます。

php公式でサポートされているバージョンも、php8.1以上になり、php8.0以下はサポートが切れております。

攻撃に利用されたファイルの削除

この対応により、本脆弱性の影響を軽減することができます。 CMSアップデート前提ですが、アップデートするまでの応急処置としてご対応ください。

以下ディレクトリ・ファイルを削除ください。

  • php/vendor/guzzlehttp/guzzle/src/Cookie
  • php/vendor/guzzlehttp/psr7/src/FnStream.php
  • php/vendor/phpseclib/phpseclib/phpseclib/File
  • php/vendor/phpseclib/phpseclib/phpseclib/Math
  • php/vendor/phpseclib/phpseclib/phpseclib/Net
  • php/vendor/phpseclib/phpseclib/phpseclib/System

不審なファイルの削除

すでに攻撃がされて悪意あるファイルが設置されている可能性があります。以下のようなコマンドで、悪意あるファイルが設置されていないか確認してください。 ファイルが設置されていましたら、パーミッションを「000」に設定してください。

攻撃が確認されたのは、2025年03月20日以降になりますので、この期間が入るように検索ください。

CMSアップデート前の場合(コマンドで確認)

cacheを除いて、ここ10日間で作成・更新されたファイルを列挙する

$ cd /path/to/ドキュメントルート
$ find . -type d -name "cache" -prune -o -type f  -mtime -10 -print
$ find . -type d -name "cache" -prune -o -type f  -ctime -10 -print

cacheディレクトリを除いて検索していますので、念の為cacheディレクトリ内は「.htaccess」を残して全て削除ください。

CMSアップデート前の場合(ブラウザで確認)

SSHでサーバーに入るのが難しい場合は、以下内容のphpファイルを設置することで、ブラウザで確認することができます。

scan.php

<?php

// 何日前を対象にするか(変更可能)
$daysAgo = 10;

// 実行する find コマンド
$commands = [
    "find . -type d -name 'cache' -prune -o -type f -mtime -$daysAgo -print",
    "find . -type d -name 'cache' -prune -o -type f -ctime -$daysAgo -print"
];

// 結果を格納する配列
$results = [];

foreach ($commands as $cmd) {
    // コマンドの実行
    $output = shell_exec($cmd);

    if ($output) {
        // 出力を改行ごとに分割
        $results[$cmd] = explode("\n", trim($output));
    } else {
        $results[$cmd] = ["No results found"];
    }
}

// HTML出力
echo "<html><head><meta charset='UTF-8'><title>Find Command Results</title></head><body>";
echo "<h1>{$daysAgo}日前から更新されたファイル</h1>";

foreach ($results as $cmd => $files) {
    echo "<h2>Command: <code>$cmd</code></h2>";
    echo "<ul>";
    foreach ($files as $file) {
        echo "<li>" . htmlspecialchars($file) . "</li>";
    }
    echo "</ul>";
}

echo "</body></html>";

$daysAgo = 10; を調整することで、検索する日数を調整できます。2025年03月20日からの差分を確認ください。

phpファイルを設置したら、以下のようなURLで確認します。

https://example.com/scan.php

調査後は必ず、scan.phpはサーバーから削除ください。

CMSアップデート後の場合(コマンドで確認)

CMSアップデート後は、新しいバージョンで上書きされますので、以下箇所をご確認ください。

$ cd /path/to/ドキュメントルート
$ find . -maxdepth 1 -type f -mtime -10 -print
$ find archives  -type f  -mtime -10 -print
$ find archives_rev  -type f  -mtime -10 -print
$ find media  -type f  -mtime -10 -print
$ find storage  -type f  -mtime -10 -print
$ find cron  -type f  -mtime -10 -print
$ find extension  -type f  -mtime -10 -print
$ find private  -type f  -mtime -10 -print
$ find themes -type d -name "system" -prune -o -type f  -mtime -10 -print

$ find . -maxdepth 1 -type f -ctime -10 -print
$ find archives  -type f  -ctime -10 -print
$ find archives_rev  -type f  -ctime -10 -print
$ find media  -type f  -ctime -10 -print
$ find storage  -type f  -ctime -10 -print
$ find cron  -type f  -ctime -10 -print
$ find extension  -type f  -ctime -10 -print
$ find private  -type f  -ctime -10 -print
$ find themes -type d -name "system" -prune -o -type f  -ctime -10 -print

CMSアップデート後の場合(ブラウザで確認)

SSHでサーバーに入るのが難しい場合は、「scan.php」の内容を変更してファイルを設置することで、ブラウザで確認することができます。

// 実行する find コマンド
$commands = [
    "find . -maxdepth 1 -type f -mtime -$daysAgo -print",
    "find archives  -type f  -mtime -$daysAgo -print",
    "find archives_rev  -type f  -mtime -$daysAgo -print",
    "find media  -type f  -mtime -$daysAgo -print",
    "find storage  -type f  -mtime -$daysAgo -print",
    "find cron  -type f  -mtime -$daysAgo -print",
    "find extension  -type f  -mtime -$daysAgo -print",
    "find private  -type f  -mtime -$daysAgo -print",
    "find themes -type d -name 'system' -prune -o -type f  -mtime -$daysAgo -print",

    "find . -maxdepth 1 -type f -ctime -$daysAgo -print",
    "find archives  -type f  -ctime -$daysAgo -print",
    "find archives_rev  -type f  -ctime -$daysAgo -print",
    "find media  -type f  -ctime -$daysAgo -print",
    "find storage  -type f  -ctime -$daysAgo -print",
    "find cron  -type f  -ctime -$daysAgo -print",
    "find extension  -type f  -ctime -$daysAgo -print",
    "find private  -type f  -ctime -$daysAgo -print",
    "find themes -type d -name 'system' -prune -o -type f  -ctime -$daysAgo -print"
];

調査後は必ず、scan.phpはサーバーから削除ください。

.htaccess で PHP の実行を制限

.htaccessで、index.php以外のphpの実行を制限します。以下コードを.htaccessの上部に設置ください。

<IfModule mod_version.c>
    <IfVersion < 2.4>
        <FilesMatch "\.php$">
            Order Allow,Deny
            Deny from all
        </FilesMatch>
        <Files "index.php">
            Order Allow,Deny
            Allow from all
        </Files>
    </IfVersion>
    <IfVersion >= 2.4>
        <FilesMatch "\.php$">
            Require all denied
        </FilesMatch>
        <Files "index.php">
            Require all granted
        </Files>
    </IfVersion>
</IfModule>

もし独自のphpを動作させたい場合は、以下のように修正ください。

<IfModule mod_version.c>
    <IfVersion < 2.4>
        <FilesMatch "\.php$">
            Order Allow,Deny
            Deny from all
        </FilesMatch>
        <Files "index.php">
            Order Allow,Deny
            Allow from all
        </Files>
        <Files "xxxx.php">
          Order Allow,Deny
          Allow from all
      </Files>
    </IfVersion>
    <IfVersion >= 2.4>
        <FilesMatch "\.php$">
            Require all denied
        </FilesMatch>
        <Files "index.php">
            Require all granted
        </Files>
        <Files "xxxx.php">
          Require all granted
      </Files>
    </IfVersion>
</IfModule>

「xxxx.php」に独自のphpファイル名を指定ください。

* 2025/04/04 追記.
上記の phpの実行制限だと、index.phpのみ実行できるように制限できますが、階層違いのindex.phpは実行できてしまいます。CMSのindex.phpのみ実行できるようにするには以下リダイレクトを設定します。

# ------------------------------------------------------------------
# 実行可能なスクリプト (PHP, CGI, Perl, Python, Shell, EXE) をブロック
# ------------------------------------------------------------------
RewriteCond %{REQUEST_URI} !^/index\.php$ [NC]
# RewriteCond %{REQUEST_URI} !^/_setup/.*\.php$ [NC]
# RewriteCond %{REQUEST_URI} !^/other2/index\.php$ [NC]
RewriteCond %{REQUEST_URI} \.(php|cgi|pl|py|sh|exe|bin|dll|bat|cmd|msi|jar)$ [NC]
RewriteRule ^.*$ - [F,L]
  • メンテナンスプログラムや、CMS外のプログラムも動作しなくなります。
  • 他のphpを動作させたい場合は、コメントアウトされている箇所を参考に該当パスを除外ください。

.htaccessで攻撃元のIPアドレスを制限

.htaccessで、攻撃元のIPアドレスを制限します。

攻撃元IPアドレスの確認方法

Ver. 3.1 系であれば監査ログで攻撃されたログが確認できます。以下のメッセージのものが攻撃されたアクセスの可能性が高いです。

  • 「takeover」が復元できません
  • POSTデータの「takeover」が復元できません

攻撃ログ

攻撃ログ

監査ログから接続元のIPアドレスを確認し、.htaccessでこのIPアドレスからの接続を拒否するように設定ください。

# 特定のIPアドレスをブロック
Order allow,deny
Deny from xxx.xxx.xxx.xxx
Deny from xxx.xxx.xxx.xxx
Allow from all

最後に

この度はご迷惑をおかけしてしまい大変申し訳ございません。
重大の問題になりますので、お早めにご対応をお願いいたします。

今後もご報告いただいた内容に対して真摯に受け止め修正と改善を行ってまいります。

本件に関するお問い合わせ先

本件についてご不明点などありましたら以下のお問い合わせよりご連絡ください。

有限会社アップルップル
メールアドレス:info@a-blogcms.jp
お問い合わせフォーム:https://www.a-blogcms.jp/contact/

モーダルでビデオ再生をする

YouTube や Vimeo の組み込みビデオを、ボタンなどを押した時にモーダルで再生するための組み込みJSです。

デモ

使い方

js/config.js に設定されている「modalVideoMark」に設定されているクラス(デフォルト: js-modal-video)をクリックして再生したい要素に振ります。 次に「data-video-id」データ属性にビデオのidを指定します。

<button class="js-modal-video" data-video-id="MwlwcmF0hwo">ビデオを再生</button>

デフォルト設定

この機能の設定は、/js/config.jsの以下の箇所にあります。設定を変更する場合は、適用しているテーマ内にJavaScriptファイルを別途作成してください。詳しくは「組み込みJSについて:設定を編集する」を参照してください。

modalVideoMark: '.js-modal-video', // ここで指定したセレクターをクリックするとビデオが再生されます
modalVideoConfig: {
  channel: 'youtube', // どのサービスを使うか指定します
  youtube: { // youtubeの設定です。オプションはyoutubeのapiドキュメントを参照してください。
    autoplay: 1,
    cc_load_policy: 1,
    color: null,
    controls: 1,
    disablekb: 0,
    enablejsapi: 0,
    end: null,
    fs: 1,
    h1: null,
    iv_load_policy: 1,
    list: null,
    listType: null,
    loop: 0,
    modestbranding: null,
    origin: null,
    playlist: null,
    playsinline: null,
    rel: 0,
    showinfo: 1,
    start: 0,
    wmode: 'transparent',
    theme: 'dark'
  },
  ratio: '16:9', // ビデオの比率を指定
  vimeo: { // vimeoの設定です。オプションはvimeoのapiドキュメントを参照してください。
    api: false,
    autopause: true,
    autoplay: true,
    byline: true,
    callback: null,
    color: null,
    height: null,
    loop: false,
    maxheight: null,
    maxwidth: null,
    player_id: null,
    portrait: true,
    title: true,
    width: null,
    xhtml: false
  },
  allowFullScreen: true, // フルスクリーンの許可設定
  animationSpeed: 300, // モーダルのトグルアニメーションスピード(ms)
    classNames: { // モーダルコンポーネントのクラス名
      modalVideo: 'modal-video',
      modalVideoClose: 'modal-video-close',
      modalVideoBody: 'modal-video-body',
      modalVideoInner: 'modal-video-inner',
      modalVideoIframeWrap: 'modal-video-movie-wrap',
      modalVideoCloseBtn: 'modal-video-close-btn'
  },
  aria: { // スクリーンリーダーメッセージ
    openMessage: 'ビデオを開きました。',
    dismissBtnMessage: 'ここをクリックするとビデオを閉じます。'
  }
}

a-blog cms と View Transitions API で作るページ遷移のアニメーションの実装について


View Transitions API の利用することで、一覧ページの Entry_Summary から詳細ページの Entry_Body にページを遷移する際に、画像が拡大するようなアニメーションをつけることができます。実際の動きは、以下の YouTube の動画をご覧ください。

OpenStreetMap

OpenStreetMapがVer.2.9から利用可能になりました。

使い方

js-open-street-map という class 属性を適用すれば、簡単に好きなページで利用できます。

さらに、data 属性を指定することで経度、緯度、zoom値などを指定できます。



属性 入力する値
data-lat 緯度 35.18531791793727
data-lng 経度 136.89938921481374
data-zoom zoom値 14
data-lazy 表示領域(viewport)に入るまで、組み込みJSの実行を遅延させるかどうか(true | false) true
data-multiple 複数のピンを表示するかどうか(true | false) true
data-markers ピンを表示させたい位置情報を | 区切りで指定できます。 35.170394,136.887383|35.176559,136.885409|35.172762,136.887447
data-messages 複数のピンを表示させる場合に、それぞれのピンに対して表示するメッセージを [[:split:]] 区切りで指定できます。 メッセージ1[[:split:]]メッセージ2[[:split:]]メッセージ3
data-msg ピンが1つの場合に、表示するメッセージを指定できます。 メッセージ
<div class="js-open-street-map" data-lat="35.18531791793727" data-lng="136.89938921481374" data-zoom="14" data-lazy="true" style="width: 100%; height: 300px;"></div>

また、data-multipleという属性にtrueを設定し、data-markers属性に対してピンを立てたい位置情報を|区切りで記述します。そうすることで下のように複数ピンを表示することが可能になります。

<div class="js-open-street-map"
  data-lazy="true"
  data-multiple="true"
  data-lat="35.172775"
  data-lng="136.887466"
  data-zoom="15"
  data-markers='35.170394,136.887383|35.176559,136.885409|35.172762,136.887447'
  style="width: 100%; height: 400px;"
></div>

さらに、data-messagesという属性を使えばpin一つ一つにコメントをつけることも可能です。メッセージを区切りたい場合は、[[:split:]]このような記号を使って分割します。

<div class="js-open-street-map"
  data-lazy="true"
  data-multiple="true"
  data-lat="35.172775"
  data-lng="136.887466"
  data-zoom="15"
  data-markers='35.170394,136.887383|35.176559,136.885409|35.172762,136.887447'
  data-messages='<table><tr><td><a href="/realestate/entry-17.html">物件情報3</a></td></tr></table>[[:split:]]<table><tr><td><a href="/realestate/entry-16.html">物件情報2</a></td></tr></table>[[:split:]]<table><tr><td><a href="/realestate/entry-15.html">物件情報1</a></td></tr></table>'
  style="width: 100%; height: 400px;"
></div>

表示領域(viewport)に入るまで、組み込みJSの実行を遅延させる


OpenStreetMap の地図が画面の下部に存在する場合、組み込みJSの実行を、表示領域(viewport)に入るまで遅延させることで、パフォーマンスを向上させることが可能です。

data-lazy 属性の値に true を指定することで、組み込みJSの実行を遅延させることができます。

<div 
  class="js-open-street-map"
  data-lat="35.18531791793727"
  data-lng="136.89938921481374"
  data-zoom="14"
  data-lazy="true"
  style="width: 100%; height: 300px;"
></div>

設定

この機能の設定は、/js/config.js で設定されています。設定を変更する場合は、適用しているテーマ内にJavaScriptファイルを別途作成してください。詳しくは「組み込みJSについて:設定を編集する」を参照してください。



設定項目 説明 デフォルト
openStreetMapMark OpenStreetMap を表示する要素をセレクター形式で設定します。 '.js-open-street-map'
openStreetMapTileLayer 表示する OpenStreetMap のタイルレイヤーをURLで設定できます。 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png'