Aikido

Mailcow に複数のクロスサイトスクリプティング(XSS)の脆弱性が確認されました

執筆者
Jorian Woltjer

Mailcowは、メールボックスの管理に必要なすべての機能を備えた、広く利用されているセルフホスト型オープンソースのメールサーバーです。そのセキュリティを評価するため、私たちはローカル環境を構築し、AIペネトレーションテストエージェントを実行しました。その結果、3つのXSS脆弱性を発見しました。その中には、認証されていない攻撃者がUI上でログを確認している間に管理者アカウントを乗っ取ることができる脆弱性 重大な脆弱性 。

メールボックスへのアクセス権を奪われると、セキュリティ上、深刻な影響が生じる可能性があります。メール内に含まれる機密データが盗み出されるだけでなく、攻撃者はパスワード再設定機能を利用して、被害者の他の関連アカウントも乗っ取ることが可能になります。もし誰かがこれらの脆弱性を悪用していたら、まさにこのような事態が起きていたでしょう。

すべての脆弱性はMailcowに対して責任ある開示が行われ、バージョン2026-03b(2026年3月31日リリース)以降で修正されています。円滑な対応と迅速な修正を行ってくださったメンテナーのFreddleSpl0it氏に感謝申し上げます。

エスケープ処理されていないオートディスカバーのログ

GitHubでGHSA-f9xf-vc72-rcgmとして報告された脆弱性 、認証されていない攻撃者が悪意のあるメールアドレスを含むAutodiscoverリクエストを送信することが脆弱性 、そのリクエストはログに記録されていました。その後、管理者がこれらのログを確認する際、メールアドレスのフィールドがエスケープ処理されずに表示されるため、HTMLインジェクションやXSS攻撃が可能となります。

まずは基本から始めましょう。Mailcowでは、管理パネルのテーブルでAutodiscoverのログを表示できますが、これはdashboard.js内の DataTablesを使用してレンダリングされています。このライブラリには、デフォルトであらゆるデータ値をHTMLとして解釈してしまうという、よくある落とし穴があります。そのため、すべての値は事前に適切にエスケープしておく必要があります。

var table = $('#autodiscover_log').DataTable({
  ...
  ajax: {
    type: "GET",
    url: "/api/v1/get/logs/autodiscover/100",
    dataSrc: function(data){
      return process_table_data(data, 'autodiscover_log');
    }
  },

会社情報 process_table_data() この関数は、各行のユーザー入力をエスケープしようとします。Autodiscoverログについては、  item.ua (User Agent) は、以下の方法で正しくエスケープされています escapeHtml (dashboard.js):

} else if (table == 'autodiscover_log') { 
   $.each(data, function (i, item) { 
     if (item.ua == null) { 
       item.ua = 'unknown'; 
     } else { 
       item.ua = escapeHtml(item.ua); 
     } 
     item.ua = '<span style="font-size:small">' + item.ua + '</span>';

ただし、item.name という1つのカラムはエスケープされていません。これは、Autodiscoverリクエストで送信されるメールアドレスです。

最も危険な点は何か?Autodiscoverリクエストは設計上 認証が行われないため 、このケースではメールアドレスが検証されません。その結果、その情報はログに記録され、管理者がログを確認すると、これらの脆弱性のある関数を通過して、任意のHTMLとしてレンダリングされてしまいます。

以下は、以下を挿入するリクエストの例です <img src=x onerror=alert(origin)> 表に:

POST /Autodiscover/Autodiscover.xml HTTP/2
Host: 127.0.0.1
Content-Type: text/xml
Content-Length: 384

<?xml version='1.0' encoding='utf-8'?>
<Autodiscover xmlns='http://schemas.microsoft.com/exchange/autodiscover/outlook/requestschema/2006'>
  <Request>
    <EMailAddress>&lt;img src=x onerror=alert(origin)&gt;</EMailAddress>
    <AcceptableResponseSchema>http://schemas.microsoft.com/exchange/autodiscover/outlook/responseschema/2006a</AcceptableResponseSchema>
  </Request>
</Autodiscover>

管理者が「ダッシュボード」→「ログ」→「Autodiscover」にあるAutodiscoverログを表示すると、JavaScriptが実行され、アラートポップアップが表示される。これにより、MailcowのオリジンにXSSの脆弱性が存在することが確認できる。

localhost上のmailcowのコピーでは、「localhost says https://localhost」というポップアップが表示されます

この問題は管理者のみに影響するため、攻撃者は任意のユーザーのメールボックスにアクセスし、インスタンスの設定を変更することが可能です。このため、脆弱性 評価されました。

今回の号 修正されました ~を追加することで escapeHtml() 行の処理中に item.user を順に呼び出す。

検疫対象ファイル名の挿入

GHSA-2xjc-rg88-jvppとして報告された脆弱性 、管理者がフラグが立てられた添付ファイルを調査できるMailcowの「検疫」機能に脆弱性 。これらの添付ファイルのファイル名がHTMLエスケープされずに表示されていたため、それらを閲覧した管理者に対してXSS攻撃の攻撃経路が生じていました。この脆弱性を悪用するには、攻撃者側の認証は不要でしたが、標的となるインスタンスで「検疫」機能が有効になっている必要がありました。

今回はシンクは空です。quarantine.js の中には、動的なデータと HTML を結合するコードが少しあります:

$.each(data.attachments, function(index, value) { 
   qAtts.append( 
     '<p><a href="/inc/ajax/qitem_details.php?id=' + qitem + '&att=' + index + '" target="_blank">' + value[0] + '</a> (' + value[1] + ')' + 
     ' - <small><a href="' + value[3] + '" target="_blank">' + lang.check_hash + '</a></small></p>' 
   ); 
 });

これらのいずれかがユーザーによって制御可能な場合、再びHTMLインジェクションが発生する可能性があります。これらの値はそれぞれファイル名MIMEタイプファイルサイズ 、およびVirusTotalのSHA256ハッシュですこのうち、ファイル名にはユーザー入力が含まれる可能性が最も高いと考えられます。なぜなら、攻撃者はHTMLタグで構成された特殊なファイル名を持つ添付ファイルをメールで送信できるからです。 

When testing, it turns out that, as expected, no strict validation takes place on this filename. It can contain <> characters, which is all that's needed to inject an XSS payload. The remaining challenge is getting the email into the quarantine queue in the first place, so an admin will open and inspect it. The attacker solves this by attaching an EICAR antivirus test file, which is a standardized string that every antivirus engine is guaranteed to flag. This reliably routes the email to quarantine without requiring the attacker to send actual malware.

以下のコードは、内容をEICAR文字列とし、ファイル名をXSSペイロードとした添付ファイルを生成します(完全なスクリプトについてはアドバイザリを参照してください):

# Malicious filename attachment with EICAR to trigger quarantine
att = MIMEApplication(b'X5O!P%@AP[4\\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*', _subtype='octet-stream')
att.add_header('Content-Disposition', 'attachment', filename='<img src=x onerror=alert(origin)>.exe')
msg.attach(att)

Mailcowにメールを送信して隔離された後、管理者は「隔離」ページを開いてそのメールを確認できます。管理者が「アイテムを表示」をクリックすると、ファイル名が表示され、XSSがトリガーされます:

なお、エクスプロイト、Mailcow での認証は不要である点に留意してください。必要なのは、悪意を持って作成されたメールを Mailcow ドメインに送信し、管理者がそれを調査することだけです。そこから、JavaScript を使用してインスタンス全体を乗っ取り、メールボックスを再度読み取り、インスタンスの設定を変更することが可能になります。

この問題は、添付ファイルの値の前後に escapeHtml() を呼び出すことで修正されました

ログイン履歴に記載されたIPアドレスにおけるセルフXSSの悪用

GHSA-jprq-w83q-q62hとして報告された脆弱性、エクスプロイト観点から技術的に興味深いものでした。このXSSペイロードは攻撃者自身のアカウント下に保存されるため、通常であれば攻撃者自身だけがこれをトリガーすることになります(実質的な影響のない「セルフXSS」です)。 この攻撃は、ログインCSRFと組み合わせることで危険なものとなります。ログインCSRFは、被害者のブラウザを強制的に攻撃者のアカウントにログインさせ、保存されたペイロードを本来アクセスすべきでない人物の目の前に表示させてしまうからです。

この脆弱性 、user.js にある別の単純な HTML 連結シンクから脆弱性 :

var real_rip = item.real_rip.startsWith("Web") ? item.real_rip : '<a href="https://bgp.tools/prefix/' + item.real_rip + '" target="_blank">' + item.real_rip + "</a>";

会社情報 real_rip (実際のリモートIP)は、エスケープ処理されずに最近のログイン履歴の表に表示されます。通常、これは問題にはなりません。IPアドレスは非常に厳格な形式に従っており、XSSペイロードを埋め込む余地がないからです。

ただし、IPアドレスはMailcowによって検証されるものではなく、直接 X-Real-IP: デフォルトではヘッダーが設定されます。一部のプロキシはこのヘッダーをユーザーのリモートIPに設定しますが、そのようなプロキシが存在しない場合、指定された値はすべて信頼されます。したがって、設定しながらログインすることができます X-Real-IP: "><img src onerror=alert(origin)> これにより、その値が最近のログイン履歴に保存されます。これを(経由で)表示すると /ユーザー)、XSSペイロードによってアラートが表示され、実行されます。

POST / HTTP/1.1
Content-Type: application/x-www-form-urlencoded
X-Real-Ip: "><img src onerror=alert(origin)>

login_user=attacker&pass_user=attacker

しかし、話はこれで終わりではありません。なぜなら、被害者がこの偽のIPヘッダーを使ってログインしたり、突然攻撃者のアカウントにログインしたりすることはないからです。現時点では、これはセルフXSSです。

脆弱性 、権限昇格を可能脆弱性 2つの要因脆弱性 。第一に、ペイロードが攻撃者のアカウント下に永続的に保存される脆弱性 。第二に、ログインリクエストにCSRF対策が施されていないため、クロスサイトでのトリガーが可能であることです。攻撃者は自身のドメイン上に、攻撃者の認証情報を自動的に送信するフォームを設置することができ、被害者がページにアクセスするだけで、何の操作もせずにログインさせてしまうことが可能です。

攻撃者は、自身の悪意のあるドメイン上に次のようなフォームを公開することができます:

<form action="http://mailcow.local/" method="POST">
    <input type="text" name="login_user" value="attacker">
    <input type="text" name="pass_user" value="attacker">
</form>
<script>
    document.forms[0].submit();
</script>

被害者が悪意のあるウェブサイト上のこのホストされたフォームを開くと、自動的に攻撃者のアカウントにログインされてしまいます。その後、被害者を /ユーザー 以前に保存しておいたXSSをトリガーするためです。しかし、ちょっと待ってください。被害者は今、攻撃者のアカウントにログインしているのですから、攻撃者はどうやって 被害者の データ?

ここで、攻撃者は巧妙な手口を使うことができます。つまり、ログイン時のCSRFおよびXSS攻撃が完了するまで被害者のメールボックスを開いたままにし、その後、同一オリジンアクセスを利用してその内容を読み取るのです。

新しいフローは次のようになります:

  1. 被害者が当社の悪意のあるページにアクセスする(タブ1)
  2. タブ1は、ログイン用のCSRFフォームを含む2つ目の悪意のあるページ(タブ2)を開きますが、実行されるまでにわずかな遅延が生じます
  3. タブ1は被害者のメールボックスにリダイレクトされ、攻撃者が盗み出そうとしているデータを読み込みます
  4. タブ2がログイン用のCSRFフォームを送信すると、新しいタブ3が開き、被害者が攻撃者のアカウントにログインさせられる
  5. タブ 2 は自動的に /ユーザー、そこで保存型XSSが引き起こされる
  6. タブ2のXSSは、への参照を使用しています オープニング 読み取りおよび持ち出し document.body.innerHTML タブ1で、被害者のメールボックスがまだ開いている状態

図には、ブラウザのタブを表す3つのボックスが描かれています。1. メールボックス 2. XSS 3. CSRF。後者の2つは攻撃者に属しています。

これにより、被害者がアカウントにログインしたままメールが取得されたため、そのアカウントからメールを読み取ることが可能になります!

エクスプロイト 実際にどのように機能するかについては、アドバイザリの詳細をご覧ください。流れを精密に制御した複数のHTMLファイルを用いることで、攻撃者はわずか2回のクリック(2つの追加タブを開くために必要な操作)でメールを盗み出すことができます。

この問題は、IPの表示処理の前後にescapeHtml()を呼び出すことで修正されました

対策

Mailcowを、2026年3月31日にリリースされたバージョン2026-03b以降に更新してください。このリリースでは、3つのXSS脆弱性すべてが修正されています。もし Aikidoをご利用の場合、脆弱性のあるMailcowインスタンスは、サーフェスモニタリングフィード上で自動的に「重大な問題」としてフラグが立てられます。

Aikido スコア95を示すダッシュボード:Mailcowにとって重大な問題です。また、要約(TL;DR)と修正手順も記載されています。

オフ Aikido まだ登録していませんか?無料アカウントを作成して始めましょう — クレジットカードは不要です。

まとめ

こうした情報漏洩事例から浮かび上がる傾向として、HTML文字列の連結は依然として避けるべき手法であることが挙げられます。最新のHTMLテンプレートエンジンは多くのアプリケーションにおいて大幅な改善をもたらしましたが、安全なフレームワークを採用していない旧式のアプリケーションには、そのような余裕がありません。こうしたアプリケーションでは、JavaScriptで文字列を連結する手法に戻ってしまうことがあり、ここで見られるように、ユーザー入力のエスケープを忘れる事態がすぐに起こりかねません。

メールボックスアプリケーションには極めて機密性の高い情報が含まれているため、細心の注意を払って扱う必要があります。こうしたアプリケーションは厳格に監査を行うべきです。なぜなら、1つのアプリケーションが侵害されると、パスワードリセット機能が悪用され、その結果、関連する他の多くのアカウントが侵害される恐れがあるからです。

Aikido (AIペネトレーションテスト)は、アプリケーション内のこうした脆弱性を完全に自動化されたプロセスで検出します。この結果をご覧になり、ご自身のアプリケーションにXSS脆弱性がないかご心配な方は、ぜひご登録いただくかお問い合わせください!

共有:

https://www.aikido.dev/blog/xss-vulnerabilities-in-mailcow

本日より無料で開始いただけます。

無料で始める
CC不要

脅威ニュースをサブスクライブ

4.7/5
誤検知にうんざりしていませんか?
10万人以上のユーザーと同様に Aikido をお試しください。
今すぐ始める
パーソナライズされたウォークスルーを受ける

10万以上のチームに信頼されています

今すぐ予約
アプリをスキャンして IDORs と実際の攻撃パスを検出します

10万以上のチームに信頼されています

スキャンを開始
AI がどのようにアプリをペンテストするかをご覧ください

10万以上のチームに信頼されています

テストを開始

今すぐ、安全な環境へ。

コード、クラウド、ランタイムを1つの中央システムでセキュアに。
脆弱性を迅速に発見し、自動的に修正。

クレジットカードは不要です。 | スキャン結果は32秒で表示されます。