Q1: 漏えいしたDigest verifierをどう分類すべきか?
単一選択 · L3serviceは各userについてH(username:realm:password)を保存しています。attackerがそのdatabaseを取得しましたが、userのcleartext passwordは復元していません。
Digestをchallenge-response protocolとして扱い、credential proof、replay policy、message coverage、proxy boundary、channel protectionを分けて判断する問題です。節番号はRFC 7616を指します。
serviceは各userについてH(username:realm:password)を保存しています。attackerがそのdatabaseを取得しましたが、userのcleartext passwordは復元していません。
clientがPOST /transferをauthenticateします。intermediaryはentity bodyを、あるvalidなJSON instructionから別のものへ変更しますが、method、request target、Authorization headerは変えません。
auth-intのA2をMethod、request-uri、H(entity-body)で構成します。bodyを置き換えると、期待されるresponse digestが変わります。authのA2に入るのはMethodとrequest-uriだけです。
Aはbody integrityを誤ったqopへ割り当てています。BはDigestの保護範囲を過大評価しています。Section 5.3によれば、auth-intでも計算に入る部分だけが保護され、多くのheader fieldは改変可能なままです。Section 3.4.5はentity-body hashを、transfer encodingの適用前と除去後に計算すると定めます。同じusername、server nonce、client nonceについて、nonce countを追跡するserverはnc=00000003をすでに受理しています。同じcountで正しく計算されたAuthorization valueを再度受信しました。
ncを、clientが同じnonceで送ったrequest数と定義します。serverが自身のcountを保持し、同じ値を2回見た場合はreplayとして検出できます。qopを使う場合、countとcnonceはresponse計算にも入ります。
Bはcredential proofとfreshness policyを混同しています。Cは問題で指定されたreplay-tracking stateを無視しています。nonce lifetimeとnonce-count uniquenessは別のcheckです。ncをwireへ含めるだけで、RFC 7616がreplay protectionをstatelessにするわけではありません。serverは、nonceが有効でなくなったため、ほかはvalidなDigest responseをrejectしました。stale=trueと新しいnonceを含むchallengeを返します。
stale=trueを、nonceがstaleだったためrejectしたことを示すflagと定義します。clientは必ずしもusernameとpasswordを再入力させず、新しいchallengeでretryできます。
Aは、このflagが区別するためのcredential failureを誤って割り当てています。Cは仕組みを逆にしています。旧nonceが延長されるのではなく、新しいchallengeでresponseを再計算します。serverは受信したnonceがinvalidだった場合だけ、このflagをtrueにすべきです。responseは、SHA-256、次にMD5という順序で別々のDigest challengeを提示します。clientは両方を実装していますが、local policyはMD5を禁止しています。
proxy rewrite後にoriginへ届いたrequest targetは/admin/deleteですが、Digest Authorizationのuriは/statusです。response digestはheader valueについて数学的には正しく計算されています。
uriとRequest-Lineのresourceが同じであることを確認するよう求め、不一致では400 Bad Requestを返すべきとしています。このinput-side comparisonにより、あるtargetのproofが別のtargetをauthorizeすることを防ぎます。
BはA2に入る値とserverのrequired resource checkを無視しています。Cはuser secretでresponseを再計算せず、authenticated inputを変更しています。serverはtrust boundaryで意味を比較する必要があり、不一致をcanonicalizeして受理してはいけません。intermediaryはrequestをforwardする前にclientをauthenticateしたいと考えています。originはすでにWWW-AuthenticateとAuthorizationを使っています。
Proxy-Authenticateを含む407 responseを返し、clientはProxy-Authorizationを送ります。
Aは別hopのexchangeを追加せず、origin authenticationを壊します。Cは異なるprotection space、challenge、credentialを混同しています。proxyは独自のDigest parameterを使います。clientは原理上proxyとoriginの両方へauthenticateできますが、同じresponseから同時に要求されることはありません。automated agentがqop=authでstate-changing POSTを送ります。serverはnonceを1時間受理し、nonce countを追跡しません。network intermediaryは取得したAuthorization fieldを別bodyとともにreplayできます。TLSは使っていません。
auth-intはentity bodyをbindします。Section 5.1はHTTPSなどのsecure channel上でDigestを使うことを推奨し、Section 5.3はDigestだけでは一般的なconfidentialityやintegrityを提供しないと説明します。
Aはauthにbody protectionとreplay stateを与え、存在しないconfidentialityも追加しています。Bはどちらのattackにも対処しません。Section 5.1はalgorithm agilityだけではlow-entropy password利用を安全にできないと述べます。auth-intを使っても多くのheaderはDigest protectionの外にあるため、完全なmessage securityとして扱ってはいけません。