セキュリティポリシー
Herkos は秘密鍵と暗号化されたメッセージを扱うため、セキュリティに関する報告を 真剣に受け止めています。問題は遅く知るより、早く知りたいと考えています。
脆弱性の報告
セキュリティ上の問題について、公開の issue を立てないでください。
メールで security@herkos.email まで非公開で報告してください。
含めていただくと役立つもの:問題の内容、再現方法、テストしたプラットフォームと バージョン、攻撃者が何を達成できるか。概念実証(PoC)があると大いに助かります。
報告に、ご自身の nsec、秘密鍵、bunker のシークレットを決して含めないでください。
報告には数日以内に受領の返事をすることを目標としています。Herkos は小さな プロジェクトなので、公開する前に修正のための妥当な時間をいただけるようお願いします。 ご希望がない限り、アドバイザリーにあなたのお名前を喜んで記載します。
対象範囲
Herkos アプリケーションそのもの:鍵の取り扱いと保存、メッセージの暗号化と
復号(local_packages/nostr_mail にある NIP-59 の送信者チェックと Bcc の分離を
含む)、アプリロック、リレーおよびブリッジとの通信、添付ファイルの扱い、
ビルドとリリースのパイプライン。Herkos Drive については、そのプロトコルパッケージ
(packages/herkos_drive_protocol)と、そのリンクを開くページ(herkos.app/f/)も
含みます。後述の専用の節を参照してください。
対象範囲外
- Nostr プロトコルとその NIP 自体——それらは上流に報告してください。
- 第三者が運営するリレー、ブリッジ、Blossom サーバー。 Herkos は既定値を 同梱していますが、それらを運営してはいません。問題はその運営者に報告してください。
- 上流プロジェクトである Nostr Mail Client。 ただし、問題が Herkos で加えた変更に固有のものである場合を除きます。
- 既知の制限として私たちがすでに文書化している、強化の不足(下記参照)。
既知の制限(率直に)
これらは設計上のトレードオフであり、脆弱性ではありません。誰かが痛い目に遭って 発見するより、ここに書いておきたいと考えています。
- 従来のアドレスとのメールはエンドツーエンドで暗号化されません。 Nostr 利用者どうしのメッセージは NIP-17 の gift wrap を使い、E2E で暗号化されます。 通常のメールアドレスに書く場合は、ブリッジがメッセージを変換し、内容を読めます。
- アプリロック(PIN と生体認証)は利便性のための障壁であり、保存時の暗号化では ありません。ロック解除された端末を手に取った人は止めますが、端末やその ストレージに完全にアクセスできる攻撃者からは守りません。
- Windows では、生体認証のみの認証を強制できません。 Windows Hello は 方式の選択を許さないため、システムの PIN が常に代替手段として残ります。
- 鍵を失うことは、アカウントを失うことです。 設計上、復旧の手段はありません。
- メタデータは完全には隠されません。 リレーは接続のパターンを観察でき、 メッセージの内容を読めなくても、すべてのリレーがあなたの IP アドレスを見ます。 Herkos が(2026年9月30日以降)明かさないのは、リレーが NIP-42 認証を求めたときの、 誰が誰に書いているか、です。
- 配送先の調査。 受信者のリレー一覧と Blossom 一覧は、あなたを一切識別しない
別の接続で問い合わせます。まず認証を求めないリレー(
purplepag.es、user.kindpag.es、nos.lol、offchain.pub)に問い合わせます。 - プロフィールと予約送信。 他の人について表示する名前と画像 (kind 0)、およびメールを予約または取り消すときの予約送信 DVM のリレー一覧も、 同じ方法で問い合わせます。まず匿名で、リレーがどうしても求める場合は 下で説明する一時的な鍵で問い合わせ、あなたの鍵は決して使いません (2026年10月1日以降。それ以前は、認証を求めるリレーにはあなたの鍵が渡り、 あなたが誰のプロフィールを見ているかが分かりました)。あなた自身の プロフィールだけは、今もあなたとして読み込みます。
- 配送。 gift wrap は受信者の DM リレーへ、同じ別の接続で送られます。 そのうちのどれかが認証を求めた場合、Herkos はその目的のために作られ、 メモリ内だけに保持される鍵で応答し、あなたの鍵は決して使いません。端末上の アカウントごとに別の鍵があります。リレーは、同じ端末(同じ IP、同じ一時的な鍵)が セッション中に複数の封筒を送ったことは引き続き見ることができます。
- 大きなメール。 32 KB を超えるメールの暗号化されたコピーは、受信者のものを 含む Blossom サーバーにアップロードされます。あなたの鍵で認可してアップロード するのは、あなた自身のサーバー(あなたの Blossom 一覧)だけです。それ以外の サーバーには匿名でアップロードし、認可をどうしても求める場合は、上と同じ 一時的な鍵で署名した認可を使います(2026年10月1日以降。それ以前は、すべての サーバーにあなたの鍵が渡っていました)。既知の鍵しか受け付けないサーバーは 拒否し、コピーは他のサーバーに残ります。
- あなた自身のデータ。 メールボックス、ラベル、設定、下書きの同期では、 リレーが求める場合、アカウントの切り替え中であっても、そのデータが属する アカウントとして認証します。あなた自身のリレーにとっては、新たに知ることは 何もありません。要求にはいずれにせよあなたの鍵が書かれているからです。あなた自身の リレー一覧と Blossom 一覧は公開されており、あなたを識別せずに問い合わせます。 メール内のリンクに書かれたリレーも同様です。
- 既読状態とフォルダーは(今のところ)公開メタデータです。 メールを既読、 スター付き、アーカイブ、移動にすると、あなたの公開鍵に結び付いた、暗号化されて いない NIP-32 ラベルイベントが公開され、独自フォルダーの名前も含まれます。 あなたに送ったメールの id を知っている送信者は、あなたがいつそれを操作したかが 分かります。これらのラベルの暗号化は予定していますが、それまではフォルダー名を 公開されるものと考えてください。
- プッシュ通知と予約送信は第三者のサービスを使います。
プッシュサーバー(選んだ場合のみ。既定ではなし。希望すれば
api.nmail.liとrelay.nmail.li)は、あなたの公開鍵、プッシュトークン、 メールを受け取った時刻を知ります。予約送信 DVM は、あなたの公開鍵と、公開すべき 暗号化済みのメッセージを知ります。どちらも任意で有効にするもので、PRIVACY.mdに 記載しています。プッシュ通知の文面はプッシュサーバーが決めるもので、Herkos は UnifiedPush が暗号化して(RFC 8291)届けた場合にのみそれを信頼します。 暗号化されていないペイロードは、アプリを起こしてメール自体を取得させるだけです。 - ウェブ版はあなたの鍵をブラウザーに保持します。そこは鍵にとって最も弱い 場所です。 インストール版のアプリは、秘密鍵を OS の安全な保存領域 (Android キーストア、Windows の DPAPI、libsecret、iOS/macOS の キーチェーン)に渡します。ブラウザーにはそのどれもありません。鍵はオリジンの ストレージに置かれ、署名のたびに JavaScript を通り、ページ内で動くあらゆる コード——すべてのサイトにアクセスできるブラウザー拡張機能、アプリや依存関係の XSS の欠陥、改ざんされた配信——や、ブラウザーのプロファイルをコピーする インフォスティーラーの手が届くところにあります。また、コードを一度だけ検証する 機会もありません。署名済みのバイナリはインストール時に確認されますが、ウェブ ページは訪問のたびに新しいコードを配信します。ウェブ版にはリモート署名 (NIP-46 の bunker、Amber)でサインインして鍵がブラウザーに届かないようにするか、 使い捨てのアイデンティティとして扱い、本当の鍵はインストール版のアプリに 置いてください。
- ブリッジ経由のメールの信頼性は、ブリッジの信頼性と同じです。 Herkos は、
ブリッジ経由と表示されたメッセージが、あなたが設定したブリッジ(または既定の
いずれか)によって本当に署名されたものかを検証します。ブリッジが中継する従来の
From:アドレスについては、何も検証できません。 - 添付ファイルは OS によって開かれます。 Herkos は実行ファイルや スクリプトの種類を決して起動せず、プレビューできないその他の添付ファイルを システムの既定アプリに渡す前には確認しますが、ファイルを開くアプリは私たちの 管理外です。
Herkos Local Relay:守るものと守らないもの
Herkos Local Relay は、あなたのアプリのイベントを、非公開のもの(下書き、 非公開の一覧、あなたが受け取る封筒)も含めて、あなたの端末に保存します。 ここでは、それを何が守り、限界がどこにあるかを、プラットフォームごとに 説明します。リレーのセキュリティ上の問題も、ほかの問題と同じ方法で報告して ください(上記参照)。
データベースは全体が暗号化されます。ジャーナルも含みます(SQLite3 Multiple Ciphers、AEGIS-256)。鍵は端末上で作られる 32 バイトのランダムな値で、 システムの安全な保存領域に保管されます。Android では Keystore、Windows では DPAPI、Linux ではキーリング(libsecret)です。リレーは自動で起動する必要が あるため、鍵にはあなたのパスワードを使いません。鍵がなければリレーは起動せず、 そのことを表示します。暗号化されていないデータベースを開いたり作ったりする ことは決してなく、開けないデータベースを削除することも決してありません。
| もし… | Android | Windows | Linux |
|---|---|---|---|
| 誰かがデータベースファイルをコピーした(バックアップ、同期フォルダー、ディスクイメージ) | 保護される | 保護される | 保護される |
| 電源が切れた状態で端末やディスクが盗まれた | 保護される:鍵は Keystore にある | 保護される。ただし Windows のサインインパスワードを知られている場合を除く:DPAPI はそのパスワードで鍵を保護する | 保護される。ただしキーリングのパスワード(ほぼ常にセッションのパスワード)を知られている場合を除く |
| 同じ端末の別のユーザーアカウント | 保護される | 保護される:DPAPI はユーザーごと | 保護される:キーリングはユーザーごと |
| あなたのユーザーとして動く別のアプリやプログラム | 保護される:Android は各アプリを分離し、Keystore は鍵をリレーにだけ渡す | 保護されない:DPAPI はアプリごとではなくユーザーごとに暗号化する。あなたとして動くプログラムは、リレーと同じように鍵を要求できる | 保護されない:セッションのキーリングはアプリどうしを分離しない |
| root 化されたスマートフォン、またはアプリとしてコードを実行するツール | 保護されない | — | — |
| ロック解除された端末を誰かが手にしている | リレーの PIN か指紋(設定している場合)だけ | 同じ | 同じ |
| 動作中のリレーのメモリーを誰かが読む | 保護されない | 保護されない | 保護されない |
デスクトップでは、DPAPI とキーリングの限界はどのプログラムとも同じです。 ほかのユーザーやディスクを持ち去る人からは守りますが、すでにあなたとして 動いている悪意のあるプログラムからは守りません。その場合が心配なら、守って くれるのはシステムディスクの暗号化(BitLocker、LUKS)と、信頼できない プログラムを実行しないことです。キーリングのない Linux(Secret Service が ない環境)では、リレーは起動せず、その理由を説明します。鍵を平文で保管する ことは決してありません。
端末そのものの上で、誰が入れるか。 リレーは 127.0.0.1 だけで待ち受けますが、
端末上のどのアプリも、ブラウザーで開いたウェブページも、そのアドレスに
届きます。そのため:
- アプリはペアリングが必要です。リレーの画面に表示され、あなたが承認します (PIN か指紋を設定していれば、それを使って)。どのアプリも自分に好きな名前を 付けられます。そのアプリから今まさに求めた場合にだけ承認してください。
- ウェブページは常にペアリングが必要で、ペアリングはそれを行った場所からしか 有効になりません。端末のアプリのペアリングは、同じ鍵で署名するウェブページで あっても、ウェブページには何も開きません。
- ペアリングしたアプリは、あなたが許可した種類のイベントだけを読み書きし、 書き込める種類のイベントだけを削除します。許可を取り消すと、すぐに切断されます。
- ペアリングしていないアプリは、あなたの公開イベント(もともと公開されている もの)を読むだけで、何も書き込みません。ただし、端末のペアリングしていない アプリを受け入れる設定をオンにした場合を除きます。
- 非公開のイベントは、それが属する鍵を持っていることを NIP-42 で証明した相手に だけ渡され、封筒はその受信者にだけ渡されます。
ここで守らないもの:
- 端末上の悪意のあるアプリは、リレーを遅くしたり、メモリーを使わせたり できます。ただし、それによって非公開のものを読むことはできません。
- リレーがスリープ中または停止中は、そのポートが空いています。 Android では 接続がないまま 10 分たつとスリープします。デスクトップでは、起動していない あいだポートは空いています。別のアプリがそこで待ち受け、リレーになりすます ことができます。Herkos のアプリは、非公開のものを送る前にリレーの鍵を確認する ようになる予定ですが、まだ確認しておらず、それまではこれは現実の限界です。
- デスクトップでは、そのコンピューターのほかのユーザーが、ペアリングして いないアプリとして接続できます。あなたの公開イベントを読み、ペアリングを 求めることができます。
ローカルネットワーク(オンにした場合。既定ではオフです):
wss://のみで、リレー自身の証明書を使います。端末の外で暗号化されていないws://を使うことは決してありません。- あなたの一覧にある鍵で認証(NIP-42)するまでは何もできません。30 秒以内に 認証しない接続は閉じられます。ローカルネットワークには専用の接続数があり、 端末のアプリの接続枠を使うことは決してありません。
- 一覧にある鍵は、あなたの公開イベントと自分の非公開イベントを読み、自分が 署名したイベントだけを書き込みます。一覧から外すと切断されます。
- 証明書は家庭内の名前(
localhost、.local、プライベートアドレス)にだけ 有効です。誰かがその鍵を盗んだとしても、証明書をインストールした端末で インターネットのドメインに署名するためには使えません。
ここで守らないもの:同じネットワークにいる人は、端末に開いたポートがあることと、 そこを通る通信量はわかりますが、その中身はわかりません。また、端末にパブリック アドレスがある場合(間にルーターがない場合)、そのポートはインターネットから 見えますが、それでもあなたの一覧にある鍵を求めます。
バックアップ。 暗号化されたバックアップにはパスワードがあります(scrypt と XChaCha20-Poly1305)。パスワードがなければ、私たちを含め誰も開けません。 JSONL の書き出しは暗号化されず、非公開のイベントが平文で含まれます。アプリは そのことを警告します。
ロック(PIN と、指紋または Windows Hello)は、アプリを開くとき、30 秒離れた あと、ペアリングを承認するときに求められます。これは Mail と同じく利便性のための 障壁で、何も暗号化しません。Android では、PIN を設定するとスクリーンショットが 撮れなくなり、最近使ったアプリにサムネイルも表示されません。また Android 12 以降は、使用中のリレーのウィンドウの上にほかのアプリのウィンドウが重なることは できません。
Herkos Drive:守るものと守らないもの
Herkos Drive は、あなたのファイルを Blossom サーバーに、ファイルとフォルダーの一覧を Nostr リレーに保存します。どちらも端末上で暗号化されます。
ここでは、それを何が守り、限界がどこにあるかを説明します。
詳細は packages/herkos_drive_protocol/ にある spec-drive.md と脅威モデル amenazas-drive.md にあります。各リレーとサーバーに何が見えるかはプライバシーポリシーにあります。
Drive のセキュリティ上の問題も、ほかの問題と同じ方法で報告してください(上記参照)。
リレーとサーバーにできないこと:
- ファイルやその名前を読むこと。 ファイルの各ブロックは、そのリビジョン固有の鍵のもとで AES-256-GCM により暗号化されます。名前、フォルダー、サイズ、日付、鍵は、それが入っているフォルダーの鍵のもとで XChaCha20-Poly1305 により封印されて送られます。 中身から導出されるものは何もありません。同じファイルを 2 回アップロードしても、異なるブロックになります。
- 気づかれずに何かを変更、すり替え、移動すること。 すべてのブロックは、そのファイルのエントリーに封印されたマニフェストと照合されます。すべてのエントリーはボリュームキーで署名され、自身の位置(ボリューム、識別子、フォルダー)に対して封印されています。リレーが、あるエントリーを別のエントリーとして、あるブロックを別のブロックとして通すことはできません。
- 古いバージョンを戻すこと。 アプリは、同じ識別子についてすでに持っているものより古いエントリーを決して受け付けません。
- ボリュームキーだけであなたとして書き込むこと。 あなたの端末が書き込むものには所有者の印、つまりどのリンクからも得られない鍵による HMAC が付いています。印のないエントリーや削除は受け付けられず、アプリが警告します。
守らないもの:
- Drive のパターン。 リレーはファイルとフォルダーの数を数え、ツリーの形と各エントリーがいつ変更されたかを見ることができます。サーバーには各ファイルのおおよその大きさが見えます(ブロックは 64 KiB に、エントリーは 2 のべき乗にパディングされます)。 どのリレーとサーバーにも、あなたの IP アドレスが見えます。それが重要なら、システムレベルで Tor または Orbot を使ってください。
- 誰かがすでにダウンロードしたもの。 リンクや人を外すと、その人が開けたものにはすぐに新しい鍵が付くので、あとから追加したものは開けません。しかし、すでに保存されたものを取り戻すことはできません。
- 漏れたリンク。 パスワードのないリンクは、それそのものが鍵です。ページがアドレスバーから取り除く前に、ブラウザーが履歴に保存することがあります。 機密性のあるものには、リンクにパスワードを付けて別の方法で伝えるか、その人のアカウントと共有してください。弱いパスワードは時間をかければ破られます。リンクを持つ人はオフラインで試せるからです。
- ページ
herkos.app/f/は、リンクを開いた人のブラウザーで動きます。厳格な Content-Security-Policy と Subresource Integrity を付けて、第三者のコードなしで配信されますが、ウェブホストを支配する者は別のページを配信できます。 これは、ブラウザーで復号するすべてのウェブページに共通する限界です。 - ボリュームキーを持っていた人(あなた自身、またはフォルダーへのリンクとともに渡された人)は、そのキーでアップロードされたブロックを、再アップロードされるまで削除できます。 ボリュームキーは変更できます(設定 → ボリュームキー)。ほかの端末は自動的に追従します。
- あなたの端末。 ファイルの一覧は暗号化してキャッシュされ、その鍵はシステムの安全な保存領域にあります。ダウンロードしたファイルや開いたファイルは、あなたが選んだ場所に平文で書き出されます。 Drive の PIN は、Mail と同じく利便性のための障壁です。
- 将来の量子コンピューター。 ブロックと封印は共通鍵暗号(AES-256、XChaCha20)ですが、ロケーターは secp256k1 上の NIP-44 で暗号化されています。今日それを保存しておき、明日 secp256k1 を破った者は、Drive 全体を開ける可能性があります。
どのように検証しているか。 脅威モデルに基づく 2 回の内部レビュー(2026年11月2日)とその修正、各イベントと各ブロックに何が表れるかのテスト、外部から来るものを読むすべての処理(イベント、封印、マニフェスト、リンク、バックアップ)のファジング。 外部監査はまだありません。公開ベータの前に 1 回予定しており、その報告書は全文を公開します。Drive はまだ開発中です。
サポート対象のバージョン
セキュリティ修正は、最新のリリース版に適用されます。プロジェクトの規模から、 古いバージョンは保守していません——報告の前に更新してください。