Slack ビデオ埋め込みを利用したエンドツーエンド暗号化の活用

クライアント側実行のベクターとしての Slack ビデオブロック

Slack のビデオブロック内の video_url フィールドは、実行時のコンテンツ検証が行われないため、任意のクライアント側コードを実行できる可能性があります。本来はビデオ埋め込み用ですが、プラットフォームは提供された URL がアクセス可能であり、2xx または 3xx の HTTP 応答コードを返すことだけを確認します。検証が通ると、コンテンツは単純な iframe としてレンダリングされ、開発者はカスタム Web アプリケーションを直接 Slack インターフェース内にロードできるようになります。

Slack におけるエンドツーエンド暗号化(E2EE)の実装

ビデオブロックの iframe 機能を利用することで、暗号鍵をクライアント側だけで扱い、サーバーが復号されたプライベートキーを見ることがないシステムを構築できます。実装はブラウザの Subtle Crypto API と openpgpjs ライブラリ(Proton がメンテナンス)を使用し、複雑な暗号操作を処理します。

E2EE ワークフロー

暗号化メッセージを送信するプロセスは以下の手順で行われます。

  1. 開始: ユーザーが /e2ee send コマンドを実行し、受信者を選択する Slack モーダルが開きます。
  2. スラッグ生成: サーバーは作者の暗号化されたプライベートキーと受信者の公開キーを含む一意のスラッグを生成し、KV データベースに保存します。
  3. クライアント読み込み: ユーザーがビデオブロックとやり取りすると、ローカルクライアントがスラッグに紐付いたデータをロードします。
  4. ローカル復号: 作者はパスフレーズを使用してローカルで自分のプライベートキーを復号します。
  5. ローカル暗号化: 作者はメッセージを書き、受信者向けに暗号化し、さらに自分のキーで署名します—すべて iframe 内でローカルに実行されます。
  6. 送信: 暗号化された暗号文だけがサーバーに送信されます。
  7. 配信: サーバーは暗号化メッセージを含む「エンベロープ」を受信者に配信します。

技術的制約と実装詳細

  • TypeScript: 本プロジェクトは迅速なイテレーションのため TypeScript で開発されました。
  • エフェメラルメッセージの制限: ビデオブロックはエフェメラルメッセージに含めることができません。この挙動は Slack の公式 Block Kit リファレンスには記載されていません。
  • データ保存: サーバー側のデータ保持を最小限に抑えるため、必要な暗号データをクライアント側 iframe に渡すスラッグベースのシステムを使用しています。
  • Node.js 統合: 本プロジェクトは最新の Node.js バージョンが提供するネイティブ .env ファイルサポートを利用して環境設定を行っています。

プロジェクトの公開とコンプライアンス

この実装のソースコードは github.com/v1ctorio/e2ee-slack で入手可能です。作者はこの手法を「ハック」と呼んでおり、ビデオブロックの設計制約に厳密に準拠していないことを指摘しています。これは Discord の「Activities」や Telegram の「Mini Apps」のように、より柔軟でフル機能のアプリ統合が必要であることを示す概念実証です。

Sources