signalapp

Stars and mentions

Last 30 days, Oct 4 – Nov 2

GitHub stars244
mentions17
05101520Oct 4Oct 18Nov 2
UTC days · repositories signalapp owns5 repositories

Package downloads

Cumulative recorded downloads · since 2025-10-19

npm74.5K
018.6K37.2K55.9K74.5KOct 4Oct 18Nov 2
Oct 17npm: 2/2 packages observed

Across 2 known packages in repositories signalapp owns. Cumulative totals include recorded downloads before the selected range. Missing observations leave gaps; totals may be incomplete.

Top repositories

signalapp’s repositories ranked by new stars, as on trending.

Loading

Contributes to

Repositories outside signalapp’s account where signalapp opened or reviewed pull requests in the past 365 days.

Who noticed signalapp

Everyone who starred or forked signalapp’s repositories since the archive began in 2011.

Notable accounts

Ordered by the stars their own repositories have received.

Biggest fans

Accounts that starred the most of these repositories.

Breakout weeks

Each repository’s best week of new stars, with the release published around it.

Mentions

14posts
Nov 30 posts
  1. 원문 Piefed: piefed.world Hacker News: news.ycombinator.com Molly 공식 자료 Molly GitHub: mollyim/mollyim-android Molly Releases: github.com/mollyim/mollyim-android/releases Molly Changelog: github.com/mollyim/mollyim-android/wiki/Changelog 취약점 CVE-2026-113380: advisories/GHSA-5c63-xm6f-r368 RingRTC 수정 커밋: github.com/signalapp/ringrtc/commit/4b1b6fa53c9f3… CSIRT Toscana: csirt.regione.toscana.it 관련 논의와 새로운 대응 Privacy Guides의 Molly 업데이트 지연 논쟁 (2026-09-22): discuss.privacyguides.net Parakeet 개발자의 보안 패치 적용 설명 (2026-10-24): discuss.grapheneos.org

    32 views
  2. Faille CVE-2026-113380 (NVD) : nvd.nist.gov Correctif RingRTC 2.72.0 : github.com/signalapp/ringrtc/commit/4b1b6fa53c9f3… Dernière version Molly (31/07) : github.com/mollyim/mollyim-android/releases/tag/v… Dernière version Signal (26/10) : github.com/signalapp/Signal-Android/releases/tag/… Ticket "Hot mic" sans réponse : mollyim-android#843 Sauvegardes Molly et Signal compatibles : mollyim/mollyim-android

    203 views
  3. You need to fix your shill propaganda. It's 4 months i.e. 120 days, not 4 weeks, before they delete your account github.com/signalapp/Signal-Server/blob/7f5097bd3…

  4. Or this case we encountered, where on iOS Signal apparently corrupts its sqlite DB, leading to loss of all messages. Signal-iOS#5813 Interestingly here, the sqlite DB would be trivially fixable, and messages restorable, with the `sqlite3` CLI. But there's no way to get at that sqlite DB file. Even if you change Signal's code to add a feature to export the DB, it apparently cannot see your DB, because iOS sandboxes that so that it is only visible to Signal builds signed with the Signal developers' keys. So that means your messages are all there, on your device, running open-source software, and yet you cannot get them. This cannot have been the intention of Signal being Free Software. Where is "change it to make it do what you wish (freedom 1)"? (I do not use iOS myself but have friends suffering this issue. Everybody involved is programmers and yet we seem to be able to do nothing about it.) So it seems that even though the messages are on the user's device, it really is the Signal developers who "own" that data, and have the exclusive and ultimate control over it. Makes me wonder: Does this mean users suffering this need to GDPR-request their data out from Signal?

  5. libsignalの復号処理の途中経過をターミナルに出力させてみた はじめに この記事は? この記事は、大学で行った実験のレポートを兼ねています。コードやソフトウェア開発にほとんど触れてこなかった人間が行った調査・実装なので、温かい目で読んでいただけると助かります。 今回扱ったSignal・libsignalについては、以下の親ページを参照してください。 zenn.dev 何をしていったか 私たちの班では、最初に「libsignalの処理を理解し、新しいテストを追加すること」を目標にしていました。 ここでいうテストは、プログラムに決めた入力を与え、結果が期待どおりになっているかを自動で確かめるプログラムです。例えば、暗号化と復号に関するテストなら、次のようなことを確認します。 正しいメッセージを暗号化して復号すると、元の文章に戻るか。 暗号化されたメッセージを途中で書き換えると、受信側が拒否できるか。 一度受け取ったものと同じ暗号文をもう一度渡したとき、重複として拒否できるか。 特に最後の二つでは、「エラーを返すこと」が期待する正しい動作です。 libsignalにも、こうした動作を確認するテストが様々用意されています。 班員で担当を分け、僕は主に復号処理周りを調べました。復号とは、暗号化されたデータを元の文章などに戻す工程です。今回は、通常の1対1メッセージの受信処理を対象にしています。 まずは復号処理がどのように行われているかを追う作業から始めたのですが、こ〜れがかなり難しい作業でした……。 そもそもコードがRustで書かれているのですが、C言語の初歩しか触ったことのない僕は、記法の段階から調べる必要がありました。加えて、暗号処理そのものも複雑なため、AIに関数や引数一つひとつの意味を説明してもらいながらでも、理解するのにかなり時間がかかりました。難しくて、一生AIに聞いていました。(今でも完璧に理解できているとは到底言えない ><) そこで今回は、新しいテストを作る方針から変更し、まず自分が処理の流れを理解しやすくするために、「テスト実行時の復号処理の途中経過をターミナルに表示する」ことを目標にしました。 テストとその表示 今回は、もともと用意されていたテストを使って動作を調べました。この記事で取り上げるのは、次の2つです。 テスト名 内容 scenario_replay_message 一度正常に受信した暗号文をもう一度渡すと、重複として拒否されるか scenario_corrupted_ciphertext メッセージに付いた改ざん確認用の値を書き換えると拒否され、その後、元の正常なメッセージは復号できるか 例えば、前者のテストを実行すると、最後には次のような結果が表示されます。 test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 61 filtered out; finished in 0.02s これは「テストが1件合格した」という意味です。ただ、この合否の表示だけでは、復号がどこまで進み、どの段階でメッセージが拒否されたかまでは読み取れません。 僕自身、複数の関数に分かれた処理を頭の中でつなげるのが難しく、理解の障壁になりました。後述しますが、復号処理はかなり階層化されています。 そこで、復号処理の主な段階について、成功・失敗をターミナルに表示するコードを追加しました。 --- 復号開始 --- セッション取得: 成功 鍵の準備: 成功 MAC・アドレスの検証: 成功 本文の復号: 成功 相手の信頼確認: 成功 状態の保存: 成功 受信結果: 成功 --- 復号開始 --- セッション取得: 成功 鍵の準備: 失敗 (message with old counter 1 / 0) 受信結果: 失敗 test session_management::legacy_interop_tests::scenario_replay_message ... ok 最初の受信では、すべての段階が成功しています。一方、同じ暗号文をもう一度渡した2回目の受信では、「鍵の準備」で失敗し、本文の復号には進んでいません。このように、テストで何が行われたのかがわかりやすくなりました。 ちなみに、同様の機能が元々備わっていないかどうかをAIに調べてもらったところ、エラーの理由などを記録するログ自体は、元のコードにもあることがわかりました。例えば、メッセージの重複や、MACという改ざん確認用の値の検証失敗などを記録する処理が入っています。 ただ、今回調べた復号の経路では、成功した段階も含めて、順に進み具合を表示する処理は見当たりませんでした。 すべてのエラーを網羅したものではありませんが、今回扱ったテストについては、処理の進み方を確認しやすくなりました。 ビルド方法とテストの動かし方 ここでは、Ubuntu上で必要なツールを準備し、libsignalをビルドして、今回使ったテストを動かすまでの手順をまとめます。 使用した環境 今回使用した環境は、次のとおりです。 項目 バージョン OS Ubuntu 24.04.3 LTS Rust 1.98.1 Cargo 1.98.1 必要なツールをインストールする まず、Ubuntuのターミナルで次のコマンドを実行します。 sudo apt update sudo apt install -y build-essential clang libclang-dev cmake protobuf-compiler libprotobuf-dev python3 git gdb これにより、ビルド・コンパイル・デバッグに必要なツールをインストールします。 Rustの開発環境をインストールする 次に、Rustの開発環境を導入します。 curl --proto '=https' --tlsv1.2 -sSf sh.rustup.rs | sh source ~/.cargo/env 1行目は、Rustのインストール用スクリプトを取得して実行するコマンドです。画面の案内に従ってインストールを進めます。 2行目の source ~/.cargo/env は、インストールしたものを、ターミナルから使えるようにするための設定を読み込むものです。 コードを取得する git clone signalapp/libsignal cd libsignal git checkout 4beb029d8a941f81e7d9c6d8af1ed25a677569a8 これでGithub上にあるlibsignalのコードを取得することができます。 今回使うコードの場所 今回関係するファイルは、おおむね次の場所にあります。 libsignal/ ├── Cargo.toml ├── rust-toolchain └── rust/ └── protocol/ ├── Cargo.toml └── src/ ├── lib.rs ├── session_management.rs ├── triple_ratchet.rs └── double_ratchet.rs 今回使う2つのテストは、rust/protocol/src/session_management.rs内にあります。 ビルドする 今回は、調べる対象を絞って次のように実行しました。 cargo build -p libsignal-protocol --lib テストを実行する 再送を拒否するscenario_replay_messageを実行する方法を紹介します。 cargo test -p libsignal-protocol --lib scenario_replay_message -- --nocapture cargo test でテストをビルドして実行します。 最後の -- --nocapture が重要で、テスト内で出力した文字を、実行中のターミナルに表示するためのコマンドです。(デフォルトでは途中出力は隠される) 1対1通信の復号処理 ここからは、今回調べた復号処理の中身を見ていきます。 復号処理では、鍵の準備や改ざんの検証、通信の記録の更新など、いくつもの処理が組み合わさっているので、「どんな役割の処理が、どの関数に分かれているのか」を整理することにしました。 復号処理の全体像 今回の2つのテストでは、テスト側の補助処理を通って、message_decrypt_signal という関数に受信処理が渡されます。 その先の構造を、処理の役割を中心にまとめると、次のようになります。 受信全体を管理する message_decrypt_signal │ ├─ 相手との通信の記録(セッション)を取り出す │ ├─ 記録の候補を使って復号を試す │ try_decrypt_from_record │ │ │ └─ 一つの候補で復号を試す │ try_decrypt_with_state │ │ │ └─ 鍵の準備・検証・本文の復号を行う │ TripleRatchet::decrypt │ │ │ ├─ ① このメッセージ用の鍵を準備する │ │ │ ├─ ② 改ざんされていないか検証する │ │ verify_mac_with_addresses │ │ └─ verify_mac → compute_mac │ │ │ └─ ③ 本文を元のデータに戻す │ aes_256_cbc_decrypt │ ├─ 相手の身元の鍵を受け入れてよいか確認する │ ├─ 更新した通信の記録を保存する │ └─ 復号したデータを返す ここから、それぞれが何をしているかを順に説明します。 相手との通信の記録を取り出す 最初の message_decrypt_signal は、受信全体を管理する関数です。 この関数には、主に次のようなものが渡されます。 引数 何のために使うか 受信した暗号化メッセージ 復号する対象 相手と自分のアドレス 誰から誰へのメッセージかを識別する セッションの保管庫 相手との通信の記録を取り出し、更新する 身元の鍵の保管庫 相手の身元の鍵を受け入れてよいか確認する まず、この中の「セッションの保管庫」から、相手との通信の記録を取り出します。 セッションとは、相手との暗号化通信を続けるための記録です。鍵を作るための材料や、受信がどこまで進んでいるかなどの情報が含まれています。 単に「相手から暗号文が届いた」という情報だけでは復号できず、受信側にも、これまでの通信に対応する記録が必要になるわけです。 記録の候補を使って復号を試す 通信の記録を取り出したら、try_decrypt_from_record が、その記録の中の候補を使って復号を試します。 同じ相手との記録には、現在のセッション状態に加えて、以前の状態が保存されている場合があります。この関数は、まず現在の状態を使い、必要に応じて以前の状態でも試します。 一つの候補で実際に復号を試すのが、try_decrypt_with_state です。この関数は、その状態から復号に使う TripleRatchet を組み立て、処理を任せます。 ここの流れが複雑で混乱しましたが、ざっくりとまとめると以下のような感じです。 関数 ざっくりした役割 message_decrypt_signal 受信全体を管理する try_decrypt_from_record 保存された状態の候補を試す try_decrypt_with_state 一つの候補で復号を試す TripleRatchet::decrypt 鍵の準備・検証・本文の復号を行う ① このメッセージ用の鍵を準備する ここからは、TripleRatchet::decrypt の内側です。 まず、このメッセージを処理するための鍵を準備します。鍵は、暗号化・復号や、改ざんの検証に使うデータです。 受信側では、保存してある鍵の材料や、届いたメッセージに付いている番号などを使って、その1通に対応する鍵を用意します。 今回の再送テストで重要なのが、この段階にある consume_message_key という処理です。 1回目の受信が成功すると、受信側の記録が次の番号へ進みます。同じ暗号文をもう一度渡しても、その暗号文に付いている番号は前と同じです。このテストでは、その番号に対応する未使用の鍵も残っていないため、重複したメッセージとして拒否されます。(この仕組みすげ〜って思いました) これが、出力の次の部分に対応します。 鍵の準備: 失敗 (message with old counter 1 / 0) ② 改ざんされていないか検証する 鍵を準備できたら、verify_mac_with_addresses でメッセージの検証を行います。 ここで使うのが、MAC(メッセージ認証コード)です。MACは、秘密の鍵とメッセージなどから計算する確認用の値です。(ネットワーク機器の「MACアドレス」とは別物です) 大まかな流れは、次のとおりです。 送信側が、メッセージにMACを付ける。 受信側でも、受信した内容からMACを計算する。 受信したMACと、自分で計算したMACが一致するか確認する。 この計算を行うのが compute_mac、照合するのが verify_mac です。 今回の scenario_corrupted_ciphertext では、付いているMACの一部を書き換えています。そのため、この検証で拒否され、本文の復号には進みません。 ③ 本文を元のデータに戻す 検証を通過すると、aes_256_cbc_decrypt で暗号化された本文を元のデータに戻します。 ここが、名前から想像する「復号」に最も近い部分です。暗号化された本文と、準備した鍵などを使って処理します。 今回は、AESという暗号方式の計算そのものまでは詳しく追っていません。 相手の信頼確認と、通信の記録の保存 本文を元に戻せた後も、外側の message_decrypt_signal には処理が残っています。 まず、セッションに記録されている相手の身元の鍵を、受け入れてよいか確認します。この確認が正常に終了した後、更新した通信の記録を保存し、復号したデータを呼び出し元へ返します。 「どの番号まで受信したか」などの記録を更新しておくことで、次のメッセージの処理や、重複したメッセージの検知につながります。 また、復号の試行が失敗した場合は、その試行で進めた状態をそのまま確定しない仕組みになっています。これが、MACを改ざんしたメッセージを拒否した後でも、元の正常なメッセージを受信できることにつながっています。 実装した内容 ここまでで復号処理の流れを整理できたので、次は、その途中経過が見えるようにコードを追加しました。 今回変更したのは、主に次の2つの関数です。 ファイル 関数 表示する内容 session_management.rs message_decrypt_signal セッションの取得、相手の信頼確認、状態の保存、受信全体の結果 triple_ratchet.rs TripleRatchet::decrypt 鍵の準備、MAC・アドレスの検証、本文の復号の結果 既存の処理の区切りに、結果を表示するコードを追加するという方針です。 処理が終わった場所に表示を追加する eprintln! を使い、ターミナルに文章を表示させていきました。 例えば、セッションを取得できた後に、次の1行を追加します。 eprintln!("セッション取得: 成功"); この行が実行されれば、「セッションを取得するところまでは進んだ」とわかります。 同じように、鍵の準備が完了した後には次の表示を追加しました。 let message_keys = message_key_gen.generate_keys(pqr_key); eprintln!("鍵の準備: 成功"); 1行目が元からある鍵を作る処理で、2行目が今回追加した表示です。 また、受信処理が複数回呼ばれても区切りがわかるよう、message_decrypt_signal の先頭には次の表示を追加しました。 eprintln!("--- 復号開始 ---"); エラーを返す前にも表示する 途中で失敗したときに何が起きたかを示すために、エラーを返す直前にも表示を追加しました。 ここで少し書き換えが必要だったのが、Rustの ? を使っている部分です。 ? は、ざっくりいうと次の処理をする記号です。 成功したら、結果の中身を取り出して処理を続ける。 エラーだったら、その関数からエラーを返す。 例えば、message_decrypt_signal には、元々次のコードがありました。 let ptext = try_decrypt_from_record( &mut session_record, remote_address, local_address, ciphertext, CiphertextMessageType::Whisper, csprng, )?; この書き方では、復号に失敗すると ? によってエラーが返されます。その直前に表示を挟みたかったので、次のように match を使う形にしました。 let ptext = match try_decrypt_from_record( &mut session_record, remote_address, local_address, ciphertext, CiphertextMessageType::Whisper, csprng, ) { Ok(ptext) => ptext, Err(error) => { eprintln!("受信結果: 失敗"); return Err(error); } }; match は、値の内容に応じて処理を分ける書き方です。ここでは、関数から返ってきた結果を、成功と失敗に分けています。 再送が拒否される場所に表示を追加する 今回の scenario_replay_message では、同じ暗号文をもう一度渡したとき、鍵の準備中にある consume_message_key が重複のエラーを返します。 この結果を受け取る部分も、同じ考え方で ? から match に書き換えました。 let message_key_gen = match self.ratchet.consume_message_key( their_ephemeral, chain_key, counter, original_message_type, &sender_address.to_string(), ) { Ok(message_key_gen) => message_key_gen, Err(error) => { eprintln!("鍵の準備: 失敗 ({error})"); return Err(error); } }; ここでは、失敗した段階に加えて、返ってきたエラーの内容も表示しています。 鍵の準備: 失敗 (message with old counter 1 / 0) {error} の部分に、受け取ったエラーの説明が入ります。 重複を検知する仕組みは元からあるものです。今回追加したのは、そのエラーを受け取った場所で「鍵の準備に失敗した」と表示する処理です。 改ざんの検証結果を表示する MACの検証については、元々あった分岐に表示を追加しました。 mac_valid には検証結果が入っており、if !mac_valid は「検証結果が正しくなかった場合」という意味です。 if !mac_valid { eprintln!("MAC・アドレスの検証: 失敗"); return Err(SignalProtocolError::InvalidMessage( original_message_type, "MAC verification failed".to_owned(), )); } eprintln!("MAC・アドレスの検証: 成功"); 検証に失敗すると、失敗表示の後でエラーが返されます。そのため、この後にある本文の復号には進みません。 scenario_corrupted_ciphertext の改ざんメッセージでは、ここに追加した失敗表示を確認できます。 残りの段階にも表示を追加する ほかの段階にも、同じように表示を追加しました。 表示する段階 表示を追加した場所 セッション取得の失敗 セッションが見つからず、エラーを作る処理の中 相手の信頼確認の失敗 相手の身元の鍵を受け入れられず、エラーを返す前 相手の信頼確認の成功 信頼確認を通過した後 本文の復号の失敗 元からある、本文の復号に失敗した場合の分岐の中 本文の復号の成功 本文の復号と、関連する状態の更新が終わった後 状態の保存・受信全体の成功 身元の鍵とセッションの保存が完了した後 既存のテストで動作を確かめる 変更後は、先ほど紹介した2つのテストを実行しました。それぞれの実行結果を見ながら、追加した表示で何がわかるようになったかを説明していきます。 1つ目のテスト:同じ暗号文をもう一度渡す まず、scenario_replay_message を実行します。 cargo test -p libsignal-protocol --lib scenario_replay_message -- --nocapture このテストでは、暗号文を1通作り、正常に受信した後、同じ暗号文をもう一度受信処理に渡します。 2回目が重複として拒否されることを確認します。 実行結果は次のようになりました。 running 1 test --- 復号開始 --- セッション取得: 成功 鍵の準備: 成功 MAC・アドレスの検証: 成功 本文の復号: 成功 相手の信頼確認: 成功 状態の保存: 成功 受信結果: 成功 --- 復号開始 --- セッション取得: 成功 鍵の準備: 失敗 (message with old counter 1 / 0) 受信結果: 失敗 test session_management::legacy_interop_tests::scenario_replay_message ... ok test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 61 filtered out; finished in 0.06s 最初の --- 復号開始 --- から始まる部分が、1回目の受信です。セッションの取得から状態の保存まで成功し、最後に 受信結果: 成功 と表示されています。 続く2回目の受信では、セッションの取得は成功していますが、その直後に次の表示が出ています。 鍵の準備: 失敗 (message with old counter 1 / 0) 受信結果: 失敗 1回目の受信で受信側の記録が次の番号へ進んだ一方、同じ暗号文には前と同じ番号が付いています。その番号に対応する未使用の鍵も残っていないため、重複として拒否されています。 2回目には、MACの検証や本文の復号の表示がありません。つまり、本文を復号する前の、鍵を準備する段階で拒否されたことがわかります。 そして、最後のテスト結果は ok です。このテストが期待していたのは、重複メッセージのエラーが返ることだったということです。 2つ目のテスト:MACを改ざんしたメッセージを渡す 次に、scenario_corrupted_ciphertext を実行します。 cargo test -p libsignal-protocol --lib scenario_corrupted_ciphertext -- --nocapture このテストでは、準備として正常なメッセージを往復させた後、別のメッセージに付いたMACの末尾1バイトを反転させます。 そして、次の2点を確認します。 MACを改ざんしたメッセージが拒否されること。 その後、改ざんしていない元のメッセージは正常に復号できること。 実行結果は次のようになりました。 running 1 test --- 復号開始 --- セッション取得: 成功 鍵の準備: 成功 MAC・アドレスの検証: 成功 本文の復号: 成功 相手の信頼確認: 成功 状態の保存: 成功 受信結果: 成功 --- 復号開始 --- セッション取得: 成功 鍵の準備: 成功 MAC・アドレスの検証: 成功 本文の復号: 成功 相手の信頼確認: 成功 状態の保存: 成功 受信結果: 成功 --- 復号開始 --- セッション取得: 成功 鍵の準備: 成功 MAC・アドレスの検証: 失敗 受信結果: 失敗 --- 復号開始 --- セッション取得: 成功 鍵の準備: 成功 MAC・アドレスの検証: 成功 本文の復号: 成功 相手の信頼確認: 成功 状態の保存: 成功 受信結果: 成功 test session_management::legacy_interop_tests::scenario_corrupted_ciphertext ... ok test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 61 filtered out; finished in 0.07s このテストでは、復号処理の表示が4回出ています。それぞれ、次の受信に対応します。 このテストでは、復号処理の表示が4回出ています。最初の2回は準備のための正常な通信、3回目はMACを改ざんしたメッセージ、4回目は改ざん前の正常なメッセージの受信です。以下に3回目の通信を抜粋します。 セッション取得: 成功 鍵の準備: 成功 MAC・アドレスの検証: 失敗 受信結果: 失敗 先ほどの再送テストとは異なり、こちらは鍵の準備までは成功しています。その後、MACの検証で失敗し、本文の復号には進んでいません。 続く4回目の受信では、元の正常なメッセージを渡すと、本文の復号や状態の保存まで成功しています。 つまり、改ざんされたメッセージを拒否できただけでなく、その後の正常な受信もできていることが確認できます。途中の試行が失敗したときに、その試行で進めた状態をそのまま確定しない仕組みが、ここにも表れています。 このテストも、期待したエラーと、その後の正常な復号を確認できたため、合格しています。 二つを比べると、同じ「受信失敗」でも、再送は鍵の準備で、MACの改ざんはMACの検証で拒否されています。今回追加した表示によって、こうした違いをコードの流れと対応付けて確認しやすくなりました。 今回の実装でできることと、限界 今回追加したのは、復号処理の主な段階を観察するための表示です。 すべての失敗に、今回の日本語の段階表示を追加したわけではありません。例えば、復号処理以外の過程でのエラー、保存処理そのものの失敗、復号処理内の一部のエラーなどには、専用の失敗表示がありません。どこでどのようなエラーが吐かれるか全て把握するのはさすがに厳しかったです。 また、グループのメッセージ本文を復号する処理は1対1とは異なる関数を使うため、そちらには今回の段階表示を追加していません。時間があればここも実装してみたかったですね。 細かな暗号の計算まで理解できたわけではありませんが、関数を追い、表示を追加し、テストで確認することで、自分の中で処理の流れをつなげやすくなりました。 新しいテストを考えるときにも、「この入力はどの検証まで進むのか」「期待した場所で拒否されているか」を調べる手掛かりにできるのではないかと思います。 おまけ 班の他のメンバーが通信全体の流れを可視化するツールを作っていました。 僕が実装したものも、このツールにそのまま移植できたら有用だな〜と思ったので、AIに頼んで実装をしてもらいました。 可視化ツール絡みの処理は全くわからなかったので、これに関しては完全にAI任せにしました。ということで、ここでは言及しないでおきます^^

  6. Signal, libsignalをいじってみた はじめに この記事は、東京大学工学部電子情報工学科・電気電子工学科の3年次後期実験の一つ、「大規模ソフトウェアを手探る」の実験レポートを兼ねています。 この実験では、公開されている大規模なOSS(オープンソースソフトウェア)を一つ選び、実際のコードを読みながら、その仕組みを調べます。プログラムを実行できる形にする「ビルド」や、途中で処理を止めながら動きを確認する「デバッガ」を使った探索を通じて、理解を深めていくことが目的の1つです。 私たちの班では、Signal, libsignal を調査対象に選びました。3人で担当を分けてコードを調べ、テストや、処理の様子を見えるようにする機能の追加に取り組みました。 あくまでも学生が授業の中で調査・実装した内容であり、理解の不足や誤りが含まれている可能性があります。温かい目で読んでいただけると幸いです。 Signal, libsignalとは Signalは、スマートフォンやパソコンで使えるメッセージアプリです。文章や画像の送信、グループチャット、音声・ビデオ通話などの機能があります。詳しくはSignalの公式サイトをご覧ください。 特徴の一つが、「エンドツーエンド暗号化」という仕組みです。送信する側の端末でメッセージを暗号化し、受信する側の端末で元のメッセージに戻します。このため、通信を取り次ぐサーバー上でも、メッセージの本文を読めないようになっています。 libsignalは、こうしたSignalの暗号化通信などを支える処理をまとめたライブラリです。Signalのアプリは、libsignalの機能を使って、メッセージの暗号化や復号などを行います。その内部の実装には、プログラミング言語のRustが使われています。libsignalの公式リポジトリ 各メンバーがやったこと 班員3人が各々担当箇所を分け、実装を行いました。実装内容は以下のとおりです。 暗号化通信の可視化 ? グループ通信におけるテストの追加 テストにおける復号処理過程をターミナルに表示 各実装の詳細については、以下のそれぞれの記事をご覧ください。 記事準備中...

  7. I Built IssueWise: Let AI Do the GitHub Issue Detective Work So You Can Focus on Contributing This is a submission for the Hacktoberfest Open-Source AI Challenge Week 3: Slow and Steady. Have you ever opened a GitHub issue that looked interesting, read through the description, and then realized you had absolutely no idea where to start? I have. One minute, you're excited about contributing to an open-source project. The next, you're jumping between the issue description, comments, documentation, and repository files, trying to understand what the problem actually is. Sometimes, the issue mentions a function you've never seen. Other times, it references a part of the codebase you know nothing about. And before you've written a single line of code, you've already spent a considerable amount of time investigating. I've contributed to open-source projects, including Signal Android and Lawnchair, and one thing I've learned is that finding an issue and understanding an issue are two very different things. GitHub makes it easy to discover issues. Understanding enough about an unfamiliar project to work on one is where things get difficult. That experience gave me an idea: What if I could paste a GitHub issue URL into a tool and get a clear explanation of the problem, what I need to understand, and where I should start investigating? Not something that writes the solution for me, but something that helps me understand the problem before I start writing code. That's how IssueWise came about. For this year's Hacktoberfest Slow and Steady challenge, I built IssueWise to handle some of the repetitive investigation involved in understanding GitHub issues, so developers can focus more on contributing. What I Built IssueWise is an AI-powered GitHub issue explorer that helps developers understand unfamiliar issues and figure out how to approach them. The idea is simple. You paste a public GitHub issue URL, IssueWise retrieves information about the issue and its repository, and Google's Gemma 4 model helps turn that information into a structured explanation. Instead of getting one long AI-generated response, you get four sections that guide you through the issue. 1. Understand — What exactly is the problem? Some GitHub issues are written with the assumption that whoever reads them already understands the project. But what if you don't? The Understand section breaks down the issue into simpler terms, helping you understand what's happening and why it matters. It's the first thing I would want to know before attempting any fix. 2. Explore — Where should I start looking? Understanding the problem is one thing. Knowing where to investigate is another. The Explore section helps you think through the issue in the context of the project. IssueWise also provides additional information through expandable sections such as Advanced Analysis, Discussion, and Repository Snapshot. I wanted this information to be available without overwhelming someone who just wants to understand the basics first. 3. Learn — What should I know before working on this? Sometimes, an issue introduces concepts you've never encountered. You might understand what needs to change but still need to learn how a particular framework, component, or programming concept works. The Learn section explains relevant concepts to help you build that understanding. This is especially useful for developers who are still learning or contributing to a particular project for the first time. 4. Contribute — How do I get started? This is where everything starts coming together. The Contribute section helps you approach the issue with a clearer idea of what to investigate and how to proceed. It doesn't replace reading the code, testing your changes, or following the project's contribution guidelines. It simply helps you get past that initial feeling of being lost. IssueWise doesn't write the contribution for you. It helps you understand what you're contributing to. And that was exactly what I wanted to build. Demo IssueWise is live, and you can try it yourself. 🚀 Try IssueWise Here's how it works: 1. Open the IssueWise website. 2. Paste a public GitHub issue URL. 3. Click Explore Issue to retrieve the issue details. 4. Click Explain This Issue to generate an explanation using Gemma 4. 5. Explore the Understand, Explore, Learn, and Contribute sections. That's all you need to get started. I tested IssueWise using real issues from open-source repositories, including Signal Android and Flask. Here's a look at the application. The homepage !IssueWise homepage showing the GitHub issue exploration interface Everything starts with a GitHub issue URL. No complicated setup or lengthy instructions. Exploring an issue !IssueWise displaying GitHub issue information and repository context IssueWise retrieves the issue details and presents them in a way that's easier to explore. Understanding the issue with AI !IssueWise AI-generated explanation with Understand, Explore, Learn, and Contribute sections This is my favorite part. Instead of reading an issue and wondering what to do next, you have a structured explanation to help you understand the problem and begin investigating. The application is hosted on Render's free services, so the first request may take a little longer if the server has been inactive. Code IssueWise is open source, and the complete source code is available on GitHub. 💻 View IssueWise on GitHub I organized the project as a monorepo, with the frontend and backend in separate applications. issuewise/ ├── apps/ │ ├── api/ # FastAPI backend │ └── web/ # Next.js frontend ├── docs/ # Documentation └── README.md The repository includes the application code, tests, and documentation. You can explore how it works, run it locally, or contribute improvements. Since IssueWise is designed to help people contribute to open source, I felt it was important to make the project open source too. How I Built It I wanted IssueWise to feel simple to use, even though there's quite a bit happening behind the scenes. I used Next.js for the frontend, FastAPI for the backend, PostgreSQL for storing application data, and Gemma 4 for the AI explanations. Here's the stack: | Technology | What I used it for | |---|---| | Next.js + TypeScript | Frontend application | | Tailwind CSS | Styling and responsive interface | | Python + FastAPI | Backend API | | PostgreSQL | Database | | Alembic | Database migrations | | Gemma 4 26B A4B IT | AI-powered issue explanations | | Google AI Studio | Hosted model inference | | GitHub API | Retrieving issue and repository information | | Render | Hosting the application | Why I chose Gemma 4 I wanted to build something where open-weight AI was an important part of the product, not just an extra feature. IssueWise uses Google's Gemma 4 26B A4B IT model to generate explanations from GitHub issue context. The GitHub API provides the issue information, but that information alone isn't always enough to help a newcomer understand what to do. Gemma helps turn it into something more useful: an explanation of the problem, relevant concepts, possible investigation directions, and guidance for getting started. Without that AI layer, IssueWise would mostly be another interface for reading GitHub issues. The explanation is what makes the experience different. How it works behind the scenes When someone submits a GitHub issue URL, the frontend sends the request to the FastAPI backend. The backend retrieves the issue and relevant repository context from GitHub. That context is then used by the AI explanation pipeline, which generates the information displayed in the four main sections. The process looks like this: GitHub Issue URL | v Fetch Issue Information | v FastAPI Backend | v Gemma 4 AI Model | v Structured Explanation | v Understand | Explore Learn | Contribute I also implemented caching. When an explanation has already been generated and stored, IssueWise can reuse it instead of making another unnecessary AI request. This helps avoid repeating work and makes previously analyzed issues quicker to revisit. I think that's a good fit for the Slow and Steady theme: if you've already done the work once, why do it all over again? Making the interface easy to use One thing I wanted to avoid was building an application that gives you another wall of technical information to read. That would defeat the purpose. So I organized the explanation into four sections and kept more detailed information inside expandable panels. You can start with the basics and explore further when you're ready. The goal was to make the experience useful without making it feel complicated. Testing and deployment I also spent time testing the frontend and backend to make sure the different parts worked together. Once the application was ready locally, I deployed it using Render. The frontend, backend, and PostgreSQL database are hosted as separate services. Getting everything working in production took some effort, especially configuring environment variables, connecting the database, running migrations, and making sure the frontend could communicate with the API. At one point, the backend wouldn't start because the production database didn't have the required tables. I had to run the Alembic migrations against the hosted database before the application could start successfully. It was a useful reminder that an application working locally doesn't automatically mean it's ready for production. Eventually, everything came together. Seeing IssueWise retrieve a real GitHub issue and generate an explanation from the live website made the work worthwhile. Why Does Open Innovation Matter? One of the reasons I enjoy open-source development is that it gives people the opportunity to learn from real projects. You can read the code, understand how something works, suggest improvements, and contribute to software that other people use. But there's a difference between having access to source code and understanding it. That's part of what inspired IssueWise. I wanted to build something that could make open-source projects a little more approachable, especially for developers who are still gaining experience. Using Gemma also fits into that idea. More freedom to experiment Gemma is an open-weight model family, which means developers have options beyond relying exclusively on a closed model API. With suitable hardware and infrastructure, open-weight models can be deployed and experimented with in different environments. For a project like IssueWise, that opens up interesting possibilities. Different programming languages, repositories, and technical problems may benefit from different models or specialized approaches. I like the idea of being able to experiment with the AI layer as the project grows. Being realistic about the current implementation The deployed version of IssueWise uses Google AI Studio for inference. So, while Gemma is an open-weight model, IssueWise currently relies on a hosted service to run it. It doesn't run entirely offline, and I'm not claiming that it does. However, using an open-weight model means there are other deployment possibilities worth exploring in the future, including self-hosted inference. For me, that's one of the practical benefits of open innovation: having more choices about how a project can evolve. Helping more developers participate I also believe that open source becomes more valuable when more people can participate. Not everyone has years of experience working with large codebases. Sometimes, all someone needs is a clearer explanation or a better starting point. If IssueWise helps even a few developers feel more confident exploring unfamiliar issues, then it's solving a problem I care about. Making code public is important. Helping people understand that code matters too. The Lazy Payoff The theme for this challenge is Slow and Steady, and I think IssueWise fits it quite well. Because sometimes being productive isn't about working harder. It's about finding ways to avoid unnecessary work. Before building IssueWise, understanding an unfamiliar GitHub issue could involve reading the description several times, checking the comments, exploring the repository, searching unfamiliar concepts, and trying to connect everything together. None of those activities is necessarily difficult on its own. But together, they can take a lot of time, especially when you're new to a project. With IssueWise, the process becomes: Paste the issue URL → Explore → Explain → Start investigating. The application brings the initial information-gathering and explanation process into one workflow. I've tested it with real GitHub issues and verified that the deployed application can retrieve issue information and generate explanations. I haven't conducted a formal study to measure exactly how much time it saves, so I won't make up a number. But the practical benefit is clear: instead of repeatedly collecting context and asking separate questions, you get a structured starting point in one place. And for me, that's the kind of laziness worth encouraging. Let the tool handle some of the repetitive investigation. Save your energy for understanding the code, testing your ideas, and making a useful contribution. What I Learned Building IssueWise taught me a few things. First, integrating an AI model is only one part of building a useful AI application. You also need to think about the information the model receives, how the output is organized, what happens when requests fail, and how people will actually use the result. Second, a good interface can make a big difference. Even a useful explanation becomes difficult to follow if everything is presented at once. Breaking the experience into smaller sections helped me keep the application focused on what the developer needs at each stage. And finally, I was reminded that it's better to solve one real problem properly than to build a long list of features that don't necessarily help anyone. There are plenty of things I'd like to improve in IssueWise over time. But for this challenge, I wanted to focus on one question: Can I make it easier for someone to go from finding an unfamiliar GitHub issue to understanding how to approach it? That's the problem IssueWise is built around. Prize Categories I'm submitting IssueWise for two partner categories. Best Use of Gemma IssueWise uses Gemma 4 26B A4B IT to generate structured explanations of GitHub issues. The model powers the main experience, helping developers understand problems, learn relevant concepts, and identify where to begin investigating. Best Use of Render I used Render to deploy the complete application, including the Next.js frontend, FastAPI backend, and PostgreSQL database. Render makes IssueWise publicly accessible so other developers can try it without setting up the project locally. Final Thoughts I don't think AI should do all the thinking for developers. And I don't think contributing to open source should mean asking an AI model to generate code you don't understand. But I do think AI can help remove some of the unnecessary friction that makes contributing feel difficult. Sometimes, the hardest part of fixing an issue isn't writing the code. It's understanding the problem well enough to know where to begin. That's what I'm trying to make easier with IssueWise. If you've ever opened a GitHub issue and wondered where to start, give it a try. 🚀 Try IssueWise 💻 Explore the source code on GitHub I'd love to hear what you think, especially if you've experienced the same challenges while contributing to open source. And if you find something that could be improved, the repository is open for contributions too. Happy Hacktoberfest! 🎃

  8. Maybe I will get the stuff fixed because I do have a verified vulnerability patch with them. This is fixed so I can share it github.com/signalapp/libsignal/commit/08b7ba6845e…

    1 like
  9. How Signal Made the Phone Number Optional, and What the Zero-Knowledge Proof Actually Protects Signal has long had a privacy contradiction at its core: the most secure mainstream messenger still required a phone number to sign up. That number became a de facto identity anchor, linkable to you even if you never shared it with contacts. Signal has now added an optional way around that, and zero-knowledge proofs (ZKPs) are part of it, though not in the way most coverage suggests. Phone-numberless registration landed in the Signal Android 8.28.0 beta on 16 September 2026. It is optional, Android only, and it costs a one-time in-app purchase: 3 USD in the United States, with per-country differences, checked 29 September 2026. The zero-knowledge proof is not what replaces the phone number. It is what stops Signal from linking that purchase to the account it creates. This post breaks down what Signal actually built, and what self-hosters can and cannot take from it. 💡 Why This Matters Phone numbers are lousy identifiers for a private messaging app. They are tied to real-world identity through carriers, they can be ported or spoofed, and they hand a centralized third party leverage over who can register. Signal has been aware of this tension for years, and their community forums have tracked the demand for phone-number-free registration since at least 2018. What shipped is narrower than proving eligibility with a zero-knowledge proof. A numberless account is identified by an Account ID and an Account Key, which Signal Android lead Greyson Parrelli describes as "a username and password." Nothing is proved about the person at all. The anti-spam control is the fee, and the zero-knowledge proof exists so that the payment cannot be tied back to the account. That is still a real change to the trust model, but it is worth being precise about which part the cryptography is doing. 🔍 What Zero-Knowledge Proofs Actually Do Here A zero-knowledge proof lets one party (the prover) convince another party (the verifier) that a statement is true, without revealing anything beyond the truth of that statement itself. In Signal's registration flow, the proof is not about you. It is about the payment. Signal's own description, from Parrelli's 16 September 2026 post on the Signal Community forum: "The payment uses the same zero-knowledge proofs our donation system uses so that there is no link between your payment and your account." The machinery being reused is the anonymous credential code behind Signal's donation badges, which lives in the zkgroup and zkcredential crates inside libsignal. Note what is not happening: nothing verifies a phone number, and nothing verifies a username either. Registration simply mints an Account ID and Account Key. The credential work is confined to the purchase, so that redeeming it proves a payment was made without identifying which payment. Concretely: you never give Signal a phone number in this flow, because no number is involved at any point. One caveat that the cryptography does not address. The purchase currently has to go through a Play Store in-app payment, so Google still sees a Signal purchase on your account even though Signal cannot link it to the Signal account. Signal says more payment methods are planned, and that a device without Play Services cannot buy an account today. 🏗️ The Architecture in Plain Terms Here is the rough flow, based on how ZKP-based credential systems like this typically work: - Credential issuance: A trusted issuer issues a blinded credential to the user. The issuer signs it without seeing the full content. Signal is not federated, so in Signal's case the issuer is Signal. - Proof generation: The client uses the credential to generate a zero-knowledge proof that says "I hold a valid credential issued by this authority" without revealing the credential itself. - Server-side verification: Signal's registration endpoint verifies the proof cryptographically. If it checks out, registration proceeds. No phone number is logged. - One-time use: The proof is typically bound to the session or includes a nullifier so the same credential cannot register multiple accounts. One-time redemption matters for abuse prevention in any scheme like this. Read the four bullets above as a description of the general pattern rather than of Signal's registration endpoint, because in Signal's case the abuse control is the price, not the cryptography. Parrelli's stated reason for charging anything at all: "Spammers, unfortunately. If it was free, spammers would acquire massive numbers of these accounts and ruin our network." Signal has also said it may raise the price if numberless accounts turn into a spam vector. 📋 Status as of 29 September 2026 What is actually shipping, from Signal's own release notes and forum posts rather than press coverage: - Platform: Android only, and still in beta. It arrived in the 8.28.0 beta on 16 September 2026, and the 8.29 beta notes on 23 September 2026 say Signal is "keeping phoneless registration in beta for another week to get more testing." Signal iOS release notes through 8.30.0 do not mention it, and Signal Desktop has no standalone registration at all. - Cost: a one-time in-app purchase, 3 USD in the United States, with prices differing by country. Play Store in-app payment is the only method at the moment, so a device without Play Services cannot buy an account. - Recovery: none. The Account ID and Account Key are the only credentials, and Signal states plainly that there is no other recovery mechanism if you lose them. These accounts have no PIN, because the Account Key replaces it. - Reachability: a username is optional, and without one the account is, in Signal's words, "completely unreachable" except in conversations you start yourself. - Existing accounts: you cannot remove the phone number from an account you already have. Signal says that may become possible later. - Two-factor: TOTP now, with passkeys and hardware keys promised. It is not yet available on phone number accounts. 🧰 What Self-Hosters Can Learn From This Pattern You do not need to be Signal to apply this pattern. The ZKP credential model is useful any time you want to gate access to a service without storing identifying data about your users. Here are a few real scenarios where this architecture applies: - Invite-only self-hosted apps: Issue blinded invite tokens. Users redeem them with a ZKP so you know the token is valid but cannot trace which token a specific account used. - Age or membership verification: Prove "user is over 18" or "user is a paid member" without storing birthdate or subscription ID server-side. - Rate limiting without tracking: Issue anonymous rate-limit tokens. Each token proves the holder is allowed N requests without tying requests back to an IP or user ID. Libraries worth looking at if you want to experiment with this pattern include zk-kit (JavaScript/TypeScript), bellman and arkworks (Rust), and snarkjs for browser-compatible proof generation. For the credential-issuance side, Signal's own zkgroup is open source and worth reading even if you do not use it directly. Check each project's documentation for current API stability before building on them. 🛡️ Security Considerations ZKPs are not magic. There are real failure modes to understand before you rely on this pattern. - Trusted setup: Some ZKP systems (like Groth16) require a trusted setup ceremony. If that ceremony is compromised, proofs can be forged. Systems using transparent setups (STARKs, or PLONK with a universal SRS) reduce this risk. - Credential theft: If an attacker steals a user's credential before it is blinded, the ZKP does not help. The issuance step still needs to be secured. - Implementation bugs: A ZKP circuit that does not correctly encode the constraint you think it does will verify invalid proofs. Formal audits of ZKP circuits are expensive and specialized. Do not roll your own for production without one. - Metadata leakage: Even with a valid ZKP, timing, IP addresses, and request patterns can still de-anonymize users. Layer your ZKP registration behind Tor or a VPN if anonymity is the goal. 🔧 Practical Next Steps If You Want to Explore This If you want to get hands-on with ZKP-based authentication, here is a reasonable starting path: Step 1: Read Signal's anonymous credential code. The standalone signalapp/zkgroup repository is archived and GitHub now points it at signalapp/libsignal, so start there. The rust/zkgroup and rust/zkcredential crates are where credential issuance and verification live. Checked 29 September 2026. Step 2: Run through the snarkjs tutorial to build a trivial ZKP circuit locally. It uses Circom for the circuit definition and outputs a Solidity or JavaScript verifier. The two tools do not install the same way: # snarkjs does ship on npm npm install -g snarkjs # circom does not. The "circom" package on npm is circom 1, # which upstream marks deprecated. circom 2 is a Rust # compiler you build from source: # https://github.com/iden3/circom Step 3: Design your constraint. Write out in plain English what your proof needs to show, for example "the prover knows a value x such that hash(x) equals a public commitment." Translating that into a Circom circuit is the hard part, and the circom documentation is the right reference. Use whichever documentation link the iden3/circom README currently gives, because docs.circom.io failed to resolve from two separate clients when this was checked on 29 September 2026. Step 4: Wire up your verifier to your registration or access endpoint. The verifier function takes a proof and public inputs and returns true or false. That boolean is your gate: // Pseudocode for a Node.js endpoint const { groth16 } = require("snarkjs"); app.post("/register", async (req, res) => { const { proof, publicSignals } = req.body; const vKey = require("./verification_key.json"); const valid = await groth16.verify(vKey, publicSignals, proof); if (!valid) return res.status(403).json({ error: "Invalid proof" }); // Proceed with account creation }); Step 5: Add nullifier tracking. Store the nullifier from each proof in a database table. On each registration attempt, check that the nullifier has not been used before. This prevents credential reuse without revealing who the credential belongs to: -- PostgreSQL example CREATE TABLE used_nullifiers ( nullifier TEXT PRIMARY KEY, used_at TIMESTAMPTZ DEFAULT now() ); ✅ Wrap Up Signal has not dropped the phone number requirement. It has added an optional, paid, Android-beta alternative to it, and free phone number registration remains the default path. What the feature does demonstrate is narrower and still useful: an anonymous credential can sit between a payment and an account so that the two cannot be correlated, even by the service that issued both. That is the principle worth borrowing, wherever you currently store an identifier only to prove that someone paid or was invited. The tooling is approachable enough that a small homelab project or self-hosted app can implement a basic ZKP gate without a cryptography PhD. Start with snarkjs, read the zkgroup source for inspiration, and design your constraints carefully. The hardest part is not the math, it is being precise about exactly what you need to prove. --- Related from the lab - The Design of Everyday Cryptography: A Homelab Primer - Reclaim Your Phone: Self-Hosting Android Alternatives for Real Ownership - You Should Self-Host Your Email (Yes, Even in 2026) --- Originally published at codewithromi.com.

  10. Signal RingRTC CVE-2026-113380: Queue Saturation Can Keep Audio and Possibly Video Active After Hang-Up 1. Basic Information - Article Title: CVE-2026-113380 (MITRE CNA Record) - Publisher: MITRE (CVE CNA) - Publication Date: 2026-10-20 - Original Source: CVE-2026-113380 (MITRE CNA Record) - Related Information Sources: NVD: CVE-2026-113380, RingRTC fix commit, SecurityWeek: Signal Vulnerability Lets Malicious Callers Block Hang-Ups, Researcher's Technical Analysis and Synthetic Queue Demo - Related Malware and Threat Groups: Unspecified - Related CVE: CVE-2026-113380 - Related Products: Signal RingRTC, Signal - Severity: High - Severity Basis: A CVSS 9.3 vulnerability that can be triggered remotely by a call partner, leading to a severe privacy breach (active exploitation has not been confirmed, and it has been fixed in RingRTC 2.72.0). 2. Executive Summary A vulnerability in Signal's calling library, RingRTC, can disrupt hang-up processing if a call peer saturates the finite-state machine (FSM) event queue. Audio and, under some conditions, video capture and transmission may then continue after the user attempts to hang up. Note that the published proof-of-concept (PoC) code is a synthetic queue simulation in an offline environment and does not demonstrate successful attacks against live Signal calls on a real network. 3. Attack Flow The attack path is based on the CVE record and fix commit (the PoC published by the researcher is a synthetic model that does not include network traffic or live calls, and must be clearly distinguished from the validation of exploit procedures in a real environment). Attack Path Indicated by CVE Description 1. An attacker establishes an active call with the target and sends a large volume of peer-derived events to the vulnerable RingRTC call event processing mechanism. 2. Saturating the FSM event queue prevents hang-up processing locally on the victim's device from successfully completing the release of the call session and media tracks. 3. Even after the user perceives the call as ended on the screen, the transmission of the audio track (and potentially the video track) continues (this is the technical impact of the published flaw, not an indication of actual damage in a real attack). The table summarizes the public information above. Defender signals are suggestions for investigation in your own environment (Inference). Undisclosed implementation details and follow-on behavior are left unspecified. | Attack Stage | Attacker Action / Technique | Tools / Communication Used | Defender Signals (Conditions / Artifacts) | | --- | --- | --- | --- | | 1. Call Establishment | Establishes a Signal call session with the target | Signal call (E2EE WebRTC communication) | Normal Signal call start logs and incoming call records | | 2. Queue Saturation | Continuously sends a large volume of peer-derived events to saturate the RingRTC FSM queue | Specific network message format undisclosed | Device-side event records when available (the published model is not a reproduction of a live call) | | 3. Hang-Up Disruption | The victim's local hang-up event stalls and processing is blocked within the queue | Interference with normal hang-up operations | Media sessions remain active even after the victim's disconnect action | | 4. Impact (Potential) | Audio and potentially video may continue even after hang-up | Potential continuation of media communication | OS displays and encrypted traffic flows alone do not confirm content transmission or delivery to the peer | 4. Attacker Position and Execution Location - A remote call peer who has established an active call with the victim. 5. Victim and Administrator Perspective Victims - Even though the call appears to have been disconnected by pressing the end call button on the UI, an in-call indicator (such as an active microphone or camera light) may remain in the OS status bar, and audio may continue to reach the other party. Administrators and SOCs - May be observed as active device privacy indicators, application log inconsistencies, lingering media sessions, or continued network traffic past the disconnection timestamp. 6. Success and Failure Conditions Success Conditions - A Signal client incorporating RingRTC prior to version 2.72.0 is running. - The attacker is able to establish a call with the victim and saturate the FSM queue. Failure Conditions and Mitigations - Immediately update the Signal app to the latest version containing the patched RingRTC. - Verify that the OS microphone and camera usage indicators (icons) turn off after ending a call, and if they do not disappear, completely force-close the application. 7. What Happens Upon Success - Unauthorized capture or eavesdropping on surrounding audio after the user attempts to hang up. - Unintended continuation of video track transmission under specific conditions. - Severe privacy breach and leakage of confidential information. 8. Observable Logs Inference: The following are candidates for internal investigation. Availability depends on the product, privileges, settings, and retention periods, and should be distinguished from observation records in source materials. Single events alone do not confirm attribution or successful compromise in this case. Email - This issue requires an established call, and email delivery vectors have not been publicized. Proxy / SWG / DNS - Internal call FSM events or hang-up processing cannot be directly read from proxy or DNS logs. Correlate available destination IPs and session durations with device records. Endpoint / EDR - Review available Signal app logs, OS microphone and camera access display histories, and correlate hang-up times with media session states (this issue involves a call processing flaw; OS shell execution or file generation are not inherent required indicators). Identity / IdP - Verification of accounts and linked devices is performed to isolate alternative factors, but administrative privileges or authentication compromise are not required for the issue itself to manifest. SaaS / Cloud - Check application versions and deployment histories collectible via MDM or management tools (Signal's E2EE communication contents and detailed FSM logs are not retained in cloud audit logs). Network - Correlate the duration of media communication traffic continuing past the hang-up operation time with device-side records (due to encrypted communications, packet contents alone cannot reconstruct audio or video contents). 9. Attack Success Determination Confirmed in Public Information The CVE record and RingRTC fix commit substantiate the existence of a flaw that impedes hang-up processing. The fix commit includes unit tests in a synthetic environment. The researcher's PoC is also an offline queue model and is distinct from confirmation of successful exploitation or actual damage in live calls. Internal Determination Criteria - User Operation Confirmed: The stage where call establishment and the user's hang-up operation are confirmed via device logs or similar means. Operation records alone cannot determine the success or failure of communication termination. - Information Theft or Session Compromise Confirmed: When factual evidence substantiates that audio or video continued to reach the peer as encrypted communication even after the hang-up operation (lingering OS displays or ongoing encrypted traffic flows alone do not confirm the transmission or delivery of audio/video contents). 10. Investigation Playbook - Trigger: Initiated by microphone indicators remaining lit after call termination, sessions with abnormally long durations, or suspicious ongoing traffic. - Initial Review: Check the Signal app version, included RingRTC version, call partner, hang-up operation time, and OS privacy indicator display state. - Endpoint / Server Investigation: Preserve Signal app logs, crash logs, OS media permission logs, and screen captures. - Identity / Cloud Investigation: Check the list of registered devices on the account and rule out suspicious linked devices or account takeover possibilities. - Subsequent Actions: Investigate call duration, outgoing data volume, and follow-up communications from the peer. - Containment: Force-close the application, update to the latest version, and temporarily disconnect the device from the network if necessary. - Judgment Classification: Clearly distinguish contact, execution, successful authentication, information retrieval, and subsequent compromise stages, and do not assume unverified success. 11. Defense and Detection Ideas - Single Events: Detect persistent lighting of media indicators after hang-up operations or abnormally long call sessions. - Temporal Correlation: Correlate the flow of a sudden surge in peer events -> hang-up operation -> remaining media sessions -> ongoing encrypted traffic. - Threat Hunting: Comprehensively search managed devices for Signal versions, abnormally long call records, and post-call traffic. - Log Limitations: Due to E2EE communication, network equipment cannot inspect payloads, and mobile OS telemetry regarding application internals is limited. - Priority Mitigations: Promptly update the Signal app, verify compliance with managed device versions, educate users on checking privacy indicators, and establish reporting procedures for anomalies. 12. Facts / Inference / Hypothesis Facts - CVE-2026-113380 affects RingRTC prior to version 2.72.0 and has a severity score of CVSS v4.0 9.3. - The CVE record indicates that saturation of the FSM event queue by a call partner prevents local hang-up processing from completing, potentially causing audio or, in some cases, video to continue. - The fix commit is dated September 4, 2026, and introduces processing to evaluate termination requests independently of the queue, continuing media resource release even upon notification failure, alongside unit tests. - The PoC published by the researcher is an offline synthetic queue simulation and does not demonstrate successful exploitation in actual Signal calls. Additionally, referenced materials show no observations of active exploitation. Inference - Because there is a divergence between operation completion on the device screen and the actual cessation of media tracks, safety cannot be judged based solely on UI displays. Hypothesis No additional hypotheses. Unverified items are listed in "Unknowns and Additional Investigation." 13. MITRE ATT&CK Mapping The following are candidates based on the potential impact in desktop environments, and do not imply uniform applicability to mobile environments or confirmation of active exploitation. | ID | Technique | Confidence | Basis | | --- | --- | --- | --- | | T1123 | Audio Capture | medium | Candidate based on the impact when the audio track continues to be transmitted even after the hang-up operation (recording operations by the attacker and active exploitation are unconfirmed). | | T1125 | Video Capture | low | Candidate based on the CVE description that video tracks may also continue (specific success conditions and successful recording are unconfirmed). | 14. Unknowns and Additional Investigation - The exact versions and dates when the patched RingRTC was incorporated into official releases of Signal clients for each OS (iOS, Android, Desktop). - Presence of active exploitation, stable detection signatures, and specific conditions for video continuation. 15. Impact on SOCs and Organizations Organizations utilizing Signal for business communications or sensitive calls should immediately verify app versions on managed devices, update them to the latest version, and investigate device and network logs if anomalies are reported where OS microphone or camera indicators persist after call termination. 16. Audience-Specific Summary - For SOCs: Monitor and correlate ongoing media sessions after call termination operations, suspiciously long WebRTC traffic, and persistent OS privacy indicator lighting. - For Administrators: Immediately update the Signal app to the latest version and verify that no outdated builds (RingRTC prior to 2.72.0) remain across managed devices. - For Users: Update the Signal app to the latest version, and if microphone or camera icons on the screen do not disappear after ending a call, force-close the application and notify your administrator.

    1 reaction
Trending awards, every completed day and week
Gold
21st place finishes
Silver
72nd place finishes
Bronze
53rd place finishes
Awarded repositories
2Owned by signalapp now

Repositories

Ordered by gold, then silver, then bronze.

  1. Signal-AndroidBest: 1st by stars, 679 stars273
  2. Signal-ServerBest: 3rd by stars, 542 stars002

A repository earns an award for finishing first, second or third in a completed trending day or week, ranked by new stars, new forks or pull request authors. Awards follow a repository through renames and transfers and count toward its current owner. Weeks run Monday to Sunday, UTC.