概要
src/webhook.ts の verifyGitHubSignature(L59)は expected === signature で署名照合している。文字列 === は最初の不一致で早期終了するため、HMAC 署名検証としては理論上タイミング攻撃に晒される。GitHub 公式ドキュメントは定数時間比較を推奨している。
severity
低。ネットワークのジッタが支配的で実攻撃は非現実的。ただしセキュリティ境界のベストプラクティス違反(subtraction-safeguard 域=明示性が load-bearing)。
対応方針
定数時間比較へ置換(Web Crypto で HMAC 再計算して crypto.subtle ベースで比較、または node crypto.timingSafeEqual。後者は等長バッファ必須なので署名長を先に検証)。挙動は不変(正しい署名→true / 不正→false)なので、webhook.test.ts の既存テストはそのまま通る想定。
検出経緯
#165 のテスト脚整備中に発見。src/webhook.test.ts で現挙動(=== 比較の正常系/異常系)を pin 済み。タイミング性質は unit では検証不能なため、本 issue で別途追跡する。
概要
src/webhook.tsのverifyGitHubSignature(L59)はexpected === signatureで署名照合している。文字列===は最初の不一致で早期終了するため、HMAC 署名検証としては理論上タイミング攻撃に晒される。GitHub 公式ドキュメントは定数時間比較を推奨している。severity
低。ネットワークのジッタが支配的で実攻撃は非現実的。ただしセキュリティ境界のベストプラクティス違反(subtraction-safeguard 域=明示性が load-bearing)。
対応方針
定数時間比較へ置換(Web Crypto で HMAC 再計算して
crypto.subtleベースで比較、または nodecrypto.timingSafeEqual。後者は等長バッファ必須なので署名長を先に検証)。挙動は不変(正しい署名→true / 不正→false)なので、webhook.test.tsの既存テストはそのまま通る想定。検出経緯
#165 のテスト脚整備中に発見。
src/webhook.test.tsで現挙動(=== 比較の正常系/異常系)を pin 済み。タイミング性質は unit では検証不能なため、本 issue で別途追跡する。