署名検証だけではrollback・freeze attackを防げない
package managerがartifactのchecksumやsignatureを正しく検証していても、それだけでは「最新で安全なversionを取得している」とは限らない。過去に正当に公開・署名されたartifactやmetadataを攻撃者が再提示できるからである。
checksum・signature・provenanceは別の保証をする で分けたintegrity/authenticityとは別に、freshness を検証する必要がある。
The Update Framework (TUF)はsoftware update systemへの攻撃としてrollback attackとindefinite freeze attackを明示している。
rollback attackでは、clientが以前知っていたversionより古いartifact/metadataを攻撃者が提示する。古いversion自体のsignatureが正しければ、単純なsignature verificationには成功し得る。しかしそのversionに既知脆弱性が残っていれば、userを意図的に脆弱な状態へ戻せる。
freeze attackでは、攻撃者がclientに以前見た正しいmetadataを繰り返し提示し、新しいreleaseの存在を隠し続ける。ここでも提示されるmetadata自体は正当に署名されている可能性がある。
TUFはこのため、単一の「release signature」だけではなく、Root / Targets / Snapshot / Timestampという役割を分けてmetadataを管理する。
- Targetsはtarget artifactのhashとsizeを示す。
- Snapshotはtargets metadata群のversion/hashをまとめ、異なる時点のmetadataを混ぜるmix-and-matchを防ぐ。
- Timestampはsnapshotの最新version/hashを短いexpirationで示し、clientが古い状態へ固定されることを検出する。
- metadataにはversionとexpirationがあり、clientは既にtrustedなversionより古いmetadataを受け入れず、expired metadataも拒否する。
この設計から分かるのは、software distributionの検証には少なくとも三つの軸があることである。
- integrity — bytesが期待したhashか
- authenticity — trusted signerが認証したか
- freshness / consistency — 古い正規artifactへのrollbackや、repository viewの組み替えを受けていないか
binary cacheの公開鍵を追加することはbuilderを信頼することに近い のようなcache署名方式でも、signing keyが正しいことだけでは更新freshness問題を自動的には解決しない。cache/operator/registryがどのversionを「現在有効」と主張するか、そのmetadataをclientがどうpin・expire・updateするかという別のprotocolが必要になる。
これはversion pinningとの関係でも注意が必要である。user自身がlockfileで古いversionを意図的にpinすることと、attackerが「新しいversionは存在しない」と偽ってclientを古い状態に固定することは別である。前者はreproducibility policy、後者はupdate securityの問題になる。
package managerを評価するとき、「download URLがHTTPS」「SHA-256を検証」「signatureあり」まで確認しても、update metadataのversioning・expiration・rollback protectionがなければfreshnessは別途検討すべきである。