🙆

セキュリティキャンプ2022 [B]Webセキュリティクラス 課題晒し

2022/06/13に公開

takumma です。
セキュリティキャンプ 2022 [B] Web セキュリティクラスに受かったので、先人に続いて僕も課題を晒しておこうと思います。

課題についてのコメントや受講理由とかも少し書くつもりですが、そんなのいいよという人は適当に飛ばして見てください。

応募に際して

応募へのモチベーション

僕は応募時に高専 5 年生でした。来年に就職を控えているため、学生のうちにやれることはやっておきたいという気持ちがありました。

セキュリティキャンプ全国大会は応募資格を学生に限定しています。[1] そのため、以前から軽く CTF を触ったり K-sec の諸々のイベントに少しお世話になったりしててセキュリティに少し興味があった僕としては、ラストチャンスだし行けるといいなというモチベーションがありました。

しかしそれと時を同じくして SecHack365 というセキュリティ系のイベントの募集があってそっちはもっといきたかったので、欲張りな僕は期間がそれなりに被っている二つの(重い)応募課題を解くことを決めました。

課題解答について

期間とモチベーション的に SecHack365 の方を優先してやってたこともあって、課題に使える時間は二週間程度しかありませんでした。

僕は怠慢な人間なので例によって最初の一週間くらいは1、2問くらいしかまともに解けてなくて、残りの一週間(というか土日)で頑張って必答と選択2問を解いて、最終締切日に落ちそうな予感がしてもう一問解いて提出しました。

よほどちゃんとした人でない限り僕と同じような締切駆動になる気がしますが、調べながら書くのと調べてある程度理解してから書くのではスピードが違ってくると思うので、課題前からちょっとインプットしてみるなり、書くモチベが湧かなくてもちょっと課題に関連することを調べてみるなりすると課題提出率が上がると思います。

課題に関してコメント

最終的な問題の解答状況は以下のような感じでした。

必答
Q1
Q2
Q3
選択(二問以上)
Q4
Q5
Q6
Q7
Q8

晒している課題を見てくれたらわかりますが、結構書いてる量は全体的に少ないと思います。選択も解いたのは三問だけです。

選択は多く解けばそれだけ受かりやすくなるというわけでもないと思う(現に僕も三問しか解いてない)のですが、セキュリティキャンプの課題はすごくいい課題ばかりで、回答者に繰り返し問いと学びを与えてくれるので、時間とやる気があればそのぶん解くのがいいと思います。

字数を数えてみたら、URL・ソースコード・問題文を含めても 19000 字程度(多分それらを除いたら 15000 字以下くらい)でした。文字数は全く参考にならないですが、文章量もそこまで書いてる訳ではないことがわかると思います。
解いた選択問題に関しては時間の許す限り調べて考えてをしていましたが、それほど深い思考が書けているかというとそうではない気もします。

僕は時間をかけて解いてますが、割とダラダラしながらやる人なので他の人ならサクッと解いちゃうかもしれません。これは個人の意見です。

基本的にまずは応募できることを目標に掲げて必答 -> 選択というふうに解いていき、選択は時間があったら全て解こうと思って解けそうなやつ(書くモチベが沸いたやつ)から進めていきました。僕は技術スタックがフロント寄りでサーバーやインフラ周辺の知識は正直全く自信がなかったので、(本当は解くべきなんだろうけど)結果的にはそこらへんに関連した課題は解くことができませんでした(時間的な理由が主)。

僕はなぜか受かりましたが、自信がない領域こそわからないなりにチャレンジすることは受かるためにも受かった後のためにも割と重要なんじゃないかと個人的には思います(運営側もそういうのを求めてるみたいだし)。


課題晒し

ということで本題の課題晒しです。

一部フォーマットのために修正が入ってますが、基本全てそのまま載せてます。

Q.1(応募のモチベーションについて)

「Web セキュリティクラス」の講義のうち、特に受講したいと思う講義(複数可)に関して、その講義で「どのようなことを・なぜ学びたいか」を教えてください。とりわけ「なぜ学びたいか」の部分に関連して、いま応募を考えているあなたが感じておられる課題意識や、あなたの関心領域が伝わってくるような解答を歓迎します。

ソフトウェアサプライチェーンセキュリティのこれから

僕はこの講義で、ソフトウェアサプライチェーン攻撃の現状とその対策を学びたいです。

僕はソフトウェアサプライチェーン攻撃について、LT で取り上げたことがあります。LT では実際の事例を挙げて、普段何気なく使っているパッケージを利用して攻撃されるリスクがあることを話しました。しかし重要なその対策に関しては、しっかりと具体的なものを話すことができませんでした。それは自分がソフトウェアサプライチェーン攻撃とその対策までしっかりと理解しきれていなかったためです。

なので今回の講義では、現状をもう一度学んだ上で、どのように対策していけばいいのかを学び、自分でも改めて考えて自分のソフトウェア開発に応用できるようにしていきたいと考えています。

Policy as Code 入門

僕はこの講義で、Policy as Code について入門したいです。

僕は、インターンで aws-cdk を用いて動画の変換処理を行う Cloud Formation を記述したことがあります。僕はそれまでインフラの分野に興味はあったものの難しそう...と思って深く触れたことがなかったのですが、入っているチームの中で aws-cdk などに詳しい人がいなかったため、僕が手を挙げて勉強をしながら取り組みました。TypeScript で補完を効かせながら記述できて、バージョン管理もでき、インフラ構成をコードで書くことのメリットを肌で感じることができました。それと同時に、難しいと思っていたインフラの分野を、自分のスキル(TypeScript など)を使って手を動かしながら学習できてとても楽しかったです。

Policy as Code について、初めはよくわからなかったのですが、記事をいくつか読んでみたり、AWS CloudFormation でどのように活用できるかを調べたりして、自分の持つ知識を使って学んでいくことができそうだなと思い、講義を受けたいと思いました。この講義で Policy as Code について入門し、さらに自分の知識を広げながらインフラについて勉強していきたいです。

Q.2(これまでの経験について)

以下の経験について、差し支えのない範囲でできるだけ具体的に教えてください:
(1) Web アプリケーションの設計・開発経験(※ どんな些細なものでも構いません)
(2) 一般のプログラミングの経験(※ 使ったことのある言語や、その用途などを教えてください。レイヤは問いません)
(3) コンテナ技術の利用経験
(4) CI/CD 環境のセットアップ・利用経験
なお、この問は「この応募課題を提出する時点での経験」を問うものです。
この応募課題を見た時点での経験はなくても構いませんし、この応募課題の記入にあわせての学習を歓迎します。

Q.3(あなたの感心・興味について)

Web に関連するサービス・プロダクトを作って提供することに関連する技術で、
いまあなたが興味を持っているものがあれば、それについて自由に説明してください。
少しでも Web との関連性がある技術であれば、それがハードウェア領域に近いものでも、
ソフトウェア領域に近いものでも構いません。

Notion

Notion は、タスク管理や Wiki などのさまざまな機能を提供するメモアプリケーション(サービス)です。チームでドキュメントを管理したい時や、社内ドキュメントとして活用したりなど様々な場面で活用できます。また、学生は個人のワークスペースを無制限で利用することができるので、僕は個人の様々なドキュメントやカレンダー、レポートなどたくさんのことを Notion 内にまとめています。(この課題も Notion で書いています。)

とても便利で使っていて楽しく、Notion を使っている自分が好きになるようなサービスの体験を提供してくれます。

そんな中で、特に僕は Notion が開発者向けに公開している API や sdk に特に興味を持っています。Notion は Notion API や JavaScript (TypeScript) 向けの sdk を公式が提供しており、それらを利用して Notion のドキュメントを読み込んだり、追加・変更したりすることができます。これによって Notion を活用した様々なものを作ることができるようになります。例えば、

  • Notion をデータベースとしてアプリケーションを作る
  • Notion を CMS のようにして、Notion で書いたブログ記事を Web アプリケーションで公開
  • ワークフローと組み合わせて、Notion に定期的にタスクを追加

などをすることができます。

実際に、僕自身も GitHub で管理しているブログ記事を Notion にまとめ、アドベントカレンダーとして活用できるワークフローを作成したことがあります。

https://github.com/marketplace/actions/notion-advent-calendar-action

Notion はこのように API などと組み合わせることで無限のアイデアを実現するポテンシャルがあり、とても面白いです。まだまだ機能も増えていっているので、今後さらに様々な活用法が発明されていったりすることを僕もとても楽しみに注目しています。

Q.4(Web に関する脆弱性・攻撃技術の検証 1)

Cross-Site Request Forgery (CSRF) とは何か、現代の Web ブラウザ・Web アプリケーションフレームワークが備える仕組みを深く考慮しながら、自分の言葉で説明してください。
なお、関連する仕様や実際の実装例の挙動を論拠にする場合は、ぜひその出典を明記してください。

CSRF とは

CSRF は、Web アプリケーションに認証しているユーザに対して、悪意のあるリクエストを送信させる攻撃です。

メールや投稿サイトなどからユーザを誘導して不正なリンクを踏ませたり、悪意あるサイトに誘導して img タグを読み込ませるなどソーシャルエンジニアリングを用いて攻撃を行います。それによってユーザに意図せず投稿させたりデータの変更・削除をさせたり、権限の取得やデータの漏洩などの被害を与えます。

CSRF は、ユーザにリクエストを送信させることでユーザの認証情報を用いて攻撃を行うため、サイト側はユーザが正当に送ったリクエストと攻撃者がユーザに送信させたリクエストの区別をつけることができません。

攻撃例

例えば、GET リクエストで何か重要な変更を行っているような脆弱な Web アプリケーションでは、以下のようなリンクを認証しているユーザに踏ませるだけで攻撃が成功してしまいます。

<a href="http://bank.com/transfer.do?acct=MARIA&amount=100000"
  >View my Pictures!</a
>

また、img タグの src 属性に URL を指定すれば、ページをロードするだけで攻撃することができてしまいます。

<img
  src="http://bank.com/transfer.do?acct=MARIA&amount=100000"
  width="0"
  height="0"
  border="0"
/>

また POST リクエストの場合は、hidden パラメータに値を設定してユーザにクリックを促すことで攻撃が可能になります。hidden パラメータで指定しているため、ユーザからはボタンしか見えないため、意図せずボタンをクリックしてしまって攻撃が実行されてしまいます。

<form action="http://bank.com/transfer.do" method="POST">
  <input type="hidden" name="acct" value="MARIA" />
  <input type="hidden" name="amount" value="100000" />
  <input type="submit" value="View my pictures" />
</form>

また、onload パラメータを付与することでユーザにクリックを促すことなく form からリクエストを実行することができてしまいます。

<body onload="document.forms[0].submit()">
  <form ...
</body>

ユーザに URL やボタンを踏ませるのはメールで送信するなどソーシャルエンジニアリングの方法を用いたりします。

コード引用元:https://owasp.org/www-community/attacks/csrf

CORS

CORS とは、Cross Origin Resource Sharing(オリジン間リソース共有)の略で、追加の  HTTP ヘッダーを使用して、あるオリジンで動作しているウェブアプリケーションに、異なるオリジンにある選択されたリソースへのアクセス権を与えるようブラウザーに指示するための仕組みです。

CORS を設定していれば、許可したオリジンのみからしかリクエストができないので大丈夫だと思いがちですが、実は CORS を適切に設定しているだけでは CSRF を防ぐことはできません。それは、CORS がどこでどのように利用されるのかが関係しています。

CORS が利用される流れは、以下の通りです。

  1. ブラウザからサーバーに対して、リクエストが送信される。
  2. サーバはリクエストに対して処理を実行したのち、HTTP ヘッダに CORS の設定が書かれたレスポンスをブラウザに返す。
  3. ブラウザは、レスポンスの HTTP ヘッダを確認し、CORS で許可されていれば処理を実行(JavaScript に対してリソースのアクセスを許可)する。

この時、CSRF ではサーバにリクエストが送られて処理が実行されさえすれば攻撃が成功してしまいます。そのため、CORS を設定していても CSRF を防ぐことはできません。代わりに、プリフライトリクエストを用いる方法があります。プリフライトリクエストについては後述します。

https://developer.mozilla.org/ja/docs/Web/HTTP/CORS

CSRF の対策

  • form タグで hidden パラメータに CSRF 対策用のトークンを追加する方法
  • プリフライトリクエストによる対策
  • その他の対策

form タグで、hidden パラメータに CSRF 対策用のトークンを追加する

form タグによってリクエストを送信する場合は、hidden パラメータに CORS 対策用のトークンを追加することで攻撃を防ぐことができます。具体的には、

  1. form タグが含まれた情報を入力するページをリクエスト
  2. ページを返すと同時にトークンを生成し、サーバに保存。
  3. トークンは form 内の hidden パラメータに含める。
  4. リクエストを送信したら、送られてきたトークンを保存していたものと比較して検証
  5. トークンが正しければ処理を実行する。

という流れで処理を行うことで、悪意あるサイトなどからの不正なリクエストを防ぐことができます。このような機能はいくつかのフレームワークなどでも提供されています。その例の一つが、Spring Boot の Spring Security です。

https://docs.spring.io/spring-security/reference/6.0.0-M3/features/exploits/csrf.html#csrf-protection-stp

また Laravel では、開発者の利便性のために Cookie に XSRF-TOKEN というトークンを設定する機能を提供するなどしています。

https://readouble.com/laravel/8.x/ja/csrf.html

注意点として、hidden パラメータに設定するトークンにセッション ID を指定してはいけません。なぜなら、HTML のソースはソーシャルエンジニアリングやプロキシサーバーによるキャッシュ、クリッピングなどの拡張機能などさまざまなケースで漏洩してしまう可能性があります。そのため、HTML のソースにセッションハイジャックができてしまうような情報を含めることはとても危険だからです。

プリフライトリクエストによる対策

プリフライトリクエストでは、リクエストがユーザーのデータなどに影響を与える可能性があるような場合に、送りたいリクエストを送る前に OPTIONS リクエストを送信し、送りたいリクエストを送信しても大丈夫かどうかを検証します。

プリフライトリクエストは、単純リクエストではない場合に送信されます。単純リクエストとは、以下を全て満たすようなものです。

送りたいリクエストが送信される前に送信されるため、プリフライトリクエストが発生するように固有の HTTP ヘッダを加え、それをサーバで検証することで異なるオリジンからの不正なリクエストも防ぐことができます。

また、固有の HTTP ヘッダを加えると form タグでの単純なリクエストの送信はできなくなりますが、その代わりに form タグを用いた攻撃を防ぐことができます。

https://developer.mozilla.org/ja/docs/Web/HTTP/CORS#preflighted_requests

その他の対策

そのほかの対策として、根本的な解決策ではありませんが、パスワードの変更などの重要な操作を行った場合に、登録されているメールアドレスへ通知するという方法があります。

メールで通知することによって不正に変更されたことをユーザが気づくことができ、CSRF への対策だけでなく、不正ログインへの対策にもなります。メールで通知する方法はさまざまなサービスで利用されていて、例えば Google では Google アカウントにログインすると Gmail にセキュリティ通知としてログインしたことが通知されます。

参考文献など

https://www.ipa.go.jp/security/vuln/websecurity-HTML-1_6.html
https://gist.github.com/mala/9086206
https://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html
https://owasp.org/www-community/attacks/csrf
https://github.com/pillarjs/understanding-csrf

Q.5(Web に関連する脆弱性・攻撃技術の検証 2)

「Top 10 web hacking techniques of 2021」
(https://portswigger.net/research/top-10-web-hacking-techniques-of-2021)
は、Web に関するセキュリティリサーチャーの投票により作成された、
2021 年に報告された興味深い Web に関する攻撃テクニック 10 選です。
この Top 10 中の事例の中で、興味を持てたもの 1 つに関して、以下を説明してください。
(1) 事例の概要
(2) 攻撃手法の詳細
(3) その他その事例に関して感じたこと・気がついたこと
なお、本設問では、関連する仕様や攻撃の適用可能な条件についての詳細な理解が垣間見えるような記述や、
理解を深めるために行ったこと(例: ローカルで行った再現実験等)に関する記述を歓迎します。

(1) 事例の概要

4 - Exploiting Client-Side Prototype Pollution in the wild

Described by filedescriptor as "arguably an underdog bug class as it's only occasionally exploited", Prototype Pollution was strictly a technique for enthusiasts until A tale of making internet pollution free - Exploiting Client-Side Prototype Pollution in the wild landed.
This phenomenal research defines a clear, insightful methodology for practical identification and exploitation. It's also notable for the all-star cast, headed by s1r1us - in Soroush's words "It feels like watching Avengers!"

https://blog.s1r1us.ninja/research/PP

プロトタイプ汚染攻撃はそれまで、たまにしか悪用されることがなかったためマイナーなほうの攻撃手法とされてきました。しかし、プロトタイプ汚染はそれを介して任意コード実行や XSS などの重大な脆弱性を生み出す危険性があります。そこで s1r1us らの研究チームは、プロトタイプ汚染攻撃の脆弱性をチェックするボットとブラウザの拡張機能を開発し、脆弱なアプリケーションを検出しました。そしてそこからアプリケーションに含まれる脆弱なライブラリと問題の箇所を特定し、報告を行いました。

挙げられている記事では、以下の3つの実際に研究チームがツールを用いて発見したプロトタイプ汚染の脆弱性の事例が挙げられています。

  • CodeQL
  • Jira Service Management(4.16.0)
  • apple.com おける XSS

(2) 攻撃手法の詳細

プロトタイプとは?

プロトタイプとは、JavaScript に継承の機能を提供する仕組みです。JavaScript のオブジェクトは、prototype オブジェクトを持つことができ、prototype はそのオブジェクトがもつメソッドやパラメータ、そしてそのオブジェクトの親のプロトタイプオブジェクトである __proto__ プロパティを持ちます。プロトタイプオブジェクトがさらにその親のプロトタイプオブジェクトを持つことはプロトタイプチェーンと呼ばれます。(最も下の  root は Object のプロトタイプを持ちます。)

JavaScript では、オブジェクトの継承という概念をこのプロトタイプを用いて表現しています。このことは、以下のサイトなどで class を babel で変換して見るとよくわかります。

https://bvaughn.github.io/babel-repl/

例えば以下のようなクラスを定義します。

class Animal {
  constructor(name) {
    this.name = name;
  }

  speak() {
    console.log(`${this.name} makes a noise.`);
  }
}

class Dog extends Animal {
  constructor(name) {
    super(name); // call the super class constructor and pass in the name parameter
  }

  speak() {
    console.log(`${this.name} barks.`);
  }
}

これを babel で変換して、AnimalDog の変換結果の定義を見ると以下のようになっています。

// 略...

var Animal = function () {
  function Animal(name) {
    _classCallCheck(this, Animal);

    this.name = name;
  }

  _createClass(Animal, [{
    key: "speak",
    value: function speak() {
      console.log(this.name + " makes a noise.");
    }
  }]);

  return Animal;
}();

var Dog = function (_Animal) {
  _inherits(Dog, _Animal);

  function Dog(name) {
    _classCallCheck(this, Dog);

    return _possibleConstructorReturn(this, (Dog.__proto__ || Object.getPrototypeOf(Dog)).call(this, name)); // call the super class constructor and pass in the name parameter
  }

  _createClass(Dog, [{
    key: "speak",
    value: function speak() {
      console.log(this.name + " barks.");
    }
  }]);

この他にも、_inherits 関数などをみるとプロトタイプオブジェクトを利用していることがわかります。このように、JavaScript ではクラスを関数とプロトタイプオブジェクトで表現しているのです。

コード引用元:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes#sub_classing_with_extends

プロトタイプ汚染攻撃とは?

プロトタイプ汚染攻撃とは、この JavaScript のプロトタイプオブジェクトの書き換えを狙った攻撃です。

プロトタイプオブジェクトは、普通のオブジェクトと同様にメソッドやパラメータを自由に追加したり変更したりすることができます。さらに、プロトタイプオブジェクトの変更は、同一オブジェクトの全てのインスタンスに対して適用されます。これは自分が定義したクラスやオブジェクトだけでなく、既存のメソッド(toString など)でも同様です。そのため以下のような挙動が実現されます。

({}.__proto__.toString = () => {
  alert("Prototype Pollution");
});
({}.toString()); // open the alert dialog.

これを利用して攻撃者は Web アプリケーション内のオブジェクトに対してプロトタイプオブジェクトの書き換えを行います。これがプロトタイプ汚染攻撃です。攻撃者はプロトタイプ汚染の脆弱性をきっかけとして、任意コード実行などの攻撃を行います。

典型的な攻撃例:JSON などから、ネストされたパラメータをパースするところを狙う

典型的なプロトタイプ汚染の脆弱性のパターンとして、JSON などから、ネストされたパラメータをパースする場合があります。

コード例:https://blog.s1r1us.ninja/research/PP#h.x0r92sn55t7w

例えば外部から JSON ファイルを読み込み、それを JavaScript のオブジェクトに変換しているような実装をしているアプリケーションがあるとします。以下はその中のコードの一部です。

const obj1 = {};
const obj2 = JSON.parse(v); // v はユーザからの入力

そして以下のような JSON を入力します。

{
	"__proto__": {
		"admin": 1.
		"user": "takumma",
	}
}

すると、以下のような結果が得られます。

console.log(obj1.admin); // 1
console.log(obj1.user); // "takumma"

このように、プロトタイプが変更されたことで何も操作をしていない obj1 のプロパティにまで影響を及ぼしてしまいます。このように JSON などの入力からプロトタイプを書き換えることで、攻撃者はプロトタイプ汚染攻撃を行います。

また、s1rius らの研究チームは「ネストされたパラメーターパーサーの 80%がプロトタイプの汚染に対して脆弱である」とも述べており、非常にプロトタイプ汚染の脆弱性が入り込みやすい部分であるといえると思います。

(3) その他その事例に関して感じたこと・気がついたこと

事例では主にクライアントサイドにフォーカスされていたが、近年では NestJS をはじめとしたサーバーサイドの JS フレームワークも普及し、サーバーサイドでも JavaScript が利用されることが増えたため、クライアントサイドだけでなくサーバーサイドでもプロトタイプ汚染攻撃を受ける可能性があるのではないかと思った。また JSON をパースするという処理は API でのサーバとクライアントとのやりとりではよく行われるため、そのようなサーバとクライアントとのやりといを介した攻撃を行うこともできるのではないかと思った。

参考文献など

https://developer.mozilla.org/ja/docs/Learn/JavaScript/Objects/Object_prototypes
https://knqyf263.hatenablog.com/entry/2020/08/09/234544
https://qiita.com/shellyln/items/af200a1953991de1698d
https://qiita.com/howdy39/items/35729490b024ca295d6c
https://jovi0608.hatenablog.com/entry/2018/10/19/083725
https://research.securitum.com/prototype-pollution-and-bypassing-client-side-html-sanitizers/

Q.8(新しい領域に関する調査)

Sigstore プロジェクト (https://sigstore.dev) について、
それがどのような課題を、概ねどのような方法で解決することを目指しているのかを簡潔に説明してください。
可能であればそれに加えて、以下のような調査・吟味を行い、その結果について論じてください。
詳細な解答を歓迎します。
(1) どのような技術的な仕組み・理論に裏付けられているのか
(2) 実社会で実際に運用可能そうなものなのか

sigstore は Docker イメージやファイルなどにデジタル署名し、それを検証するため方法を提供して、ソフトウェアサプライチェーン攻撃などのソフトウェアの依存関係に関する課題を解決するためにのツールです。


世の中にある多くのソフトウェアは、単体ではなく他のソフトウェアを利用(依存)して作られています。そのため、依存しているソフトウェアに脆弱性があればそれに依存しているソフトウェアにも脆弱性が含まれる可能性があります。このことを利用して依存しているソフトウェアに脆弱性を注入させる攻撃をソフトウェアサプライチェーン攻撃といいます。

ソフトウェアサプライチェーン攻撃は、依存しているソフトウェアがどこで誰が開発したものか分からず、全ての依存しているソフトウェアに対して脆弱性が含まれていることをすぐに見つけ出すのも難しいため、対策が難しいです。

その対策として、ファイルなどにディジタル署名をする方法があります。ディジタル署名を行うことで、誰がどこでビルドしたものなのかを保証することができます。これまでも、PGP 鍵を用いてファイルなどを署名する方法はありました。しかし、鍵の管理が難しく紛失した時の影響も大きいため、敬遠されつつありました。

そのような課題を解決するために、sigstore は Docker イメージやファイルなどに自動でディジタル署名を行い、検証する方法を提供しています。また sigstore では鍵の生成時にパスワードを設定するため鍵をそのまま GItHub などに上げて管理することができたり、OpenID Connect による Keyless Signing を提供したりと鍵の管理を簡単にする方法を提供しています。

(1) どのような技術的な仕組み・理論に裏付けられているのか

sigstore はいくつかの OSS のツールがまとまったもので、主なものは Cosign・Fulcio・Rekor の三つです。それぞれ

  • Cosign:署名を行うツール
  • Rekor:Transparency Log(署名を行った履歴がわかるログ)を提供するツール
  • Fulcio:証明書を発行するルート認証局

であるそうです。

各ツールの詳細

Cosign

Cosign は署名の作成、検証、保存を行うツールです。鍵の生成にはパスワードを使用した方法と Keyless Sigining を提供しています。署名を作成する手順は、

  1. メモリ内に一時的なパブリック/プライベートキーペアを生成
  2. Fulcio から要求された短期間の証明書に公開鍵をバインド
  3. 証明書がまだ有効である間に、一時的な秘密鍵を使用してアーティファクトに署名
  4. 証明書が有効な間に署名されたことを証明するものとして、署名と証明書を Rekor に保存

というような感じです。

Rekor

Rekor は Transparency Log(署名を行った履歴がわかるログ)を提供するツールです。ログは追加のみで変更はできないようになっています。Rekor のタイムスタンプとツリーヘッドは、署名付きツリーヘッド(STH)で署名されています。署名付きツリーヘッドでは、ログがツリーに新しいエントリを追加するたびに、対応するツリーのハッシュとツリー情報に署名します。

Fulcio

Fulcio は、証明書を発行するルート認証局です。Fulcio は有効な期間が 20 分未満の証明書にのみ署名します。有効な期間を短くすることで、失効を避けるようにしています。署名の記録は Rekor に記録されます。しかし、短い有効期間だと Rekor のオペレータがタイムスタンプを偽造することは簡単になります。そのために、STH で署名を行っています。

(2) 実社会で実際に運用可能そうなものなのか

この課題を書いている現在(2022/05/13)、sigstore 事態はまだベータ版で、Fulcio などの一部ツールもまだベータ版の状態です。Stable 版のリリースは 2022 年春にと公式では書かれています。実際に、GitHub などに上がっている元のファイルなどが改ざんされていないことはcosign verify で検証できるが、手元にあるイメージやファイルが改ざんされていないことを検証するためには改めて digest を比較して検証しないといけなかったり、ログの監視は提供されていないため自分で監視をしなければ Rekor や Fulcio から不正行為を検出することができなかったりと、使う上で不便なところはまだまだあると思います。Rekor に関しては、パブリックインスタンスで記録されているログが今後削除される可能性もあります。

しかし、現在も活発に開発されていて、Kubernetes も sigstore の採用を示しているなどし、今後さらに機能も増え、多くのプロジェクトに採用されていくのではと考えられます。よって、現時点で課題はあるものの、実際に運用することも可能なものだと考えられると思います。

参考文献など

https://www.sigstore.dev/
https://github.com/sigstore
https://knqyf263.hatenablog.com/entry/2022/02/06/213003
https://blog.sigstore.dev/kubernetes-signals-massive-adoption-of-sigstore-for-protecting-open-source-ecosystem-73a6757da73
https://github.com/rubygems/rfcs/pull/37
https://www.oracle.com/jp/cloud/cloud-native/container-registry/
https://shibumi.dev/posts/keyless-signatures-with-github-actions/
https://qiita.com/umi/items/2074aac509a6e78c4ef4
http://bluearth.cocolog-nifty.com/blog/2020/03/post-966b22.html
https://blog.flatt.tech/entry/sigstore_keyless_signing
https://docs.sigstore.dev/security
https://tex2e.github.io/rfc-translater/html/rfc6962.html
https://github.com/sigstore/rekor#public-instance


脚注
  1. 正確にはセキュリティキャンプ全国大会は学部生までで、ミニキャンプとかネクストキャンプはまた違ったと記憶してます。正確な情報は公式を追ってください。 ↩︎

Discussion