要約
- RFC 3112はpassword由来値を、大文字小文字を区別するscheme、scheme情報、authentication valueの三つに分けた。matching ruleは
TRUE、FALSE、Undefinedを返せたが、それは比較の結果であり、LDAP associationの認証結果ではなかった。 - 文書は認証にBindを必須とした。attributeは複数値を持てたため、書き込み権限を奪った者は、利用者の既存passwordを無効にせず、もう一つの有効な秘密を追加できた。
真だったのは別のstate machineだった
clientがLDAPのmatching ruleへpasswordを渡す。serverは保存値を見つけ、schemeとsaltを読み、期待値を計算し、真を返す。秘密は一致した。しかしclientはdirectoryに対してまだ認証されていない。
この境界がRFC 3112の歴史的な中心である。2001年5月にInformationalとして公開された「LDAP Authentication Password Schema」は、当時のuserPassword利用が想定していた実際のpasswordではなく、そこから導出した情報をdirectoryへ置く方法を記述した。syntax、二つのmatching rule、root DSEのcapability attribute、auxiliary object classを定義する。そして便利な照合方法を作った直後、その意味を広げないよう警告した。CompareまたはSearchによるauthPasswordMatch成功だけではdirectory accessに足りず、認証にはBindを使わなければならない。
比較とBindは違う問いに答えていた。比較は、入力文字列が宣言されたschemeの下で保存値のどれかと一致するかを答える。Bindは、serverがこのLDAP associationにauthentication identityを受け入れたかを答える。その後、authorization policyが、得られたauthorization identityに許す操作を決める。directoryを使うapplicationは、さらに自分のbusiness actionを決める。
これらを一つの「login成功」に畳むと、証拠は壊れる。matchはBindなしでも起こる。Bind成功後も書き込みは拒否され得る。directory readが許されても、applicationの変更や取引が完了したとは限らない。
保存値は計算方法を名乗った
authPasswordSyntaxはドル記号で区切られたscheme、authInfo、authValueを持ち、各componentはcase-sensitiveだった。schemeがmechanismを名付け、authInfoはしばしばbase64のsaltを、authValueはしばしばpassword由来値を運んだ。
このself-describingな形式により、一つのdirectoryに複数mechanismを置き、serverが理解する名前を公表できた。RFC 3112はMD5とSHA1を定義し、privateなschemeにはX- prefixまたはOIDを求めた。root DSEにだけ現れるsupportedAuthPasswordSchemesは、serverがsupportすると主張するschemeを列挙した。
ただしsupportは実行証拠ではない。広告は、あるBindで何が選ばれたか、どのentryにどの値があったか、saltが一意だったか、誰が書いたか、channelが保護されたか、認証が成功したかを示さない。capabilityとexecution traceは別物である。
時代も明示しなければならない。RFC 3112のMD5/SHA-1 schemeは、passwordとsaltを連結してdigestを作った。saltは64 bit以上で、implementationは128 bitまでsupportする必要があった。これは2001年の定義であり、現代のpassword storage推奨ではない。後のRFC 8018はsaltとiteration countを明示したpassword-based cryptographyを整理し、RFC 9106はmemory-hardなArgon2を規定してpassword hashingとkey derivationにArgon2idを優先した。後代の文書は古い記録を書き換えないが、「安全にhashした」という曖昧な表現ではschemeとcostを証明できないことを示す。
encoded equality、password test、Bind
authPasswordExactMatchは、すでに構造化されたcomponentを比較した。同じscheme、authInfo、authValueを持つ保存値があればtrue、なければfalse、それ以外はundefinedになる。これは表現同士のequalityだった。
authPasswordMatchはextensible-match filterでpasswordを受け取り、保存値ごとのschemeで試した。一つ以上が合えばtrue、すべて合わなければfalse、処理できなければUndefinedだった。
どの答えも、keyboardの前にいる人を同定しない。trueはchannelの支配者や、比較を行う権限を証明しない。falseは正しいentryを選んだことや外部credential storeが存在しないことを証明しない。Undefinedはwrong passwordではない。結論を出せなかったという独立した事実を残している。
Bind必須という規則が、比較結果の越権を防いだ。後のRFC 4511は改訂LDAP protocolでBind resultを記述し、RFC 4513はauthentication identityとauthorization identityを分けた。後者は前者から導出される場合も、適切なmechanismの下で別に主張される場合もあるが、serverは代理する権限を確認しなければならない。
だからBind成功さえ万能の許可ではない。authenticationはassociation上で誰を受け入れたかを決める。authorizationはそのidentityが対象objectにそのoperationを行えるかを決める。applicationは最後のbusiness outcomeを所有する。
複数値は複数の入口になった
authPasswordはsingle-valuedではなかった。選択されたschemeについてserverは関連値を調べ、どれか一つが合えばpasswordを有効とみなせた。scheme移行や計画的なoverlapには便利だが、write authorityが新しい入口を作るauthorityにもなる。
RFC 3112は危険を明記した。attributeへのwrite accessを得た攻撃者は、利用者の本来のpasswordを止めずに追加値を保存できる。利用者は普段通りsign inできるので、resetやlockoutという目立つ兆候がない。第二のdoorだけが残る。
最終snapshotでは履歴を復元できない。二つの値が存在しても、誰が追加し、どのpolicyが許可し、何を置換する予定だったかは分からない。add、replace、delete、writer identity、authorization result、fingerprint、scheme、parameter、replication、retirementをそれぞれ保存する必要がある。
RFC 3062はすでにLDAP Password Modify extended operationを定義していた。serverは管理規則の下で対象を決め、passwordを受け取るか生成し、保存mechanismを選べた。RFC 3112はこれと組み合わせられたが、attribute一つがaccount lifecycle全体を表すわけではない。
serverはauthPasswordをuserPasswordやexternal storeと併用することもできた。一つのattributeを観測しても、authentication decision surface全体は見えない。一値を消しても、別経路までrevokeしたとは限らない。
由来値もsecretだった
RFC 3112は「one-wayだから公開できる」とは言わなかった。algorithm flaw、implementation error、offline attackにより漏えいがaccessへ変わるため、由来値もclear-text password同様に保護するよう勧告した。confidentialityを保証できないtransportでの転送は強く非推奨だった。
authPasswordMatchのassertionも同じである。candidate passwordそのものをserverへ送る。保護されないchannelは秘密を漏らし、自由すぎるmatching interfaceはonline guessing oracleになる。
計算costはavailabilityにも作用する。重いschemeはguessの費用を上げる一方、clientがserver CPUを消費する手段にもなる。rate limit、concurrency budget、timeout、compare権限まで含めて実際のpolicyである。強いscheme名だけでは安全運用を証明できない。
文脈は変わっても分離は残った
RFC 3112はRFC 2251、RFC 2252、RFC 2256という1997年のLDAP文脈からuserPasswordを論じた。これを永遠の仕様と読んではならない。後のRFC 4519は、userPassword値がclear textである必要もBindに使える必要もないと明確にした。implementationは独自のtagged formも使った。
Informational statusも重要である。RFC EditorとIETF Datatrackerの記録が証明するのはpublicationとdocument historyであり、広いdeploymentではない。RFC 2829とRFC 4513はsecurity modelを示し、RFC 4511、RFC 4517、RFC 4519はprotocol、matching、schemaの後継を示す。どれも特定directoryがauthPasswordをenableした証拠ではない。
残る教訓は、表現、比較、認証、認可、結果を分離することだ。「userがloginした」と主張するなら、entryとmutation history、scheme・salt・parameter、Compare/Searchを許したaccess control、channel、requestと三値結果、実際に試した値、Bind requestとresponse、authentication/authorization identity、後続operation、application outcomeを別々に保存しなければならない。
passwordは確かに一致し得た。RFC 3112は、その真実がBindの代わりに話してはいけないことを知っていた。
情報源
- https://www.rfc-editor.org/rfc/rfc3112.html
- https://www.rfc-editor.org/info/rfc3112
- https://datatracker.ietf.org/doc/rfc3112/
- https://www.rfc-editor.org/rfc/rfc2251.html
- https://www.rfc-editor.org/rfc/rfc2252.html
- https://www.rfc-editor.org/rfc/rfc2256.html
- https://www.rfc-editor.org/rfc/rfc2829.html
- https://www.rfc-editor.org/rfc/rfc3062.html
- https://www.rfc-editor.org/rfc/rfc4511.html
- https://www.rfc-editor.org/rfc/rfc4513.html
- https://www.rfc-editor.org/rfc/rfc4517.html
- https://www.rfc-editor.org/rfc/rfc4519.html
- https://www.rfc-editor.org/rfc/rfc8018.html
- https://www.rfc-editor.org/rfc/rfc9106.html
会員向け解説
プロフィールの詳細
適切な会員レベルでログインすると、解説全文と出典メモをご覧いただけます。
Strategic Circle 限定
Strategic Circle
すべての読者に公開されています。参加してログインすると プロフィール解説 を閲覧できます。
Strategic Circle に参加Leadership Alliance 会員限定
Leadership Alliance
対象となる IP 資産の所有者・管理者向けです。ログインすると Leadership Alliance の解説を閲覧できます。
Leadership Alliance に参加
