外注に依頼していたWebサイトの初稿が届いたときに思い出したことをつらつら。
Basic認証のパスワードが16文字以上で案内が届いたとき。
普段はすごく短いパスワードを設定する人が、公共団体っぽいサイトを依頼していたからか、ご丁寧に社内Pマークの規定?的なルールがあることを知っているというアピール的な感じで、すごく長いパスワードが届いた。
案の定、最初の8文字だけの入力で突破できたので、、規定だけ知ることの怖さを思い知った。
htpasswdはデフォルトではcrypt()アルゴリズムを使用しているので、最初の8文字までしかハッシュ化に使用しないため、これでは最初の8文字だけの入力でBasic認証を突破できてしまう。
9文字以上のパスワードを設定する場合は、MD5アルゴリズムを使用する必要があり、これにはhtpasswdコマンドに-mオプションを利用すればいい。
htpasswd -nbm username password
Basic認証とは
そもそもBasic認証とは、HTTP認証のひとつである。
HTTP認証とは以下のようなものである。
- サーバーは1回目のクライアントからのリクエストに対して、
401
(Unauthorized) レスポンスを返却し、WWW-Authenticate
レスポンスヘッダーを含めて認証方式に関する情報を提供する。 - クライアントは
Authorization
リクエストヘッダーに資格情報を含めることで、サーバーに自身の認証を要求する。
WWW-Authenticateレスポンスヘッダーは
- リソースへのアクセスに使用する認証メソッド(Basic,…)を指定する。
- このヘッダーを参照し、クライアントは資格情報の提供方法を認識する。
WWW-Authenticate: <type> realm=<realm>
<type>
:認証方式名。Basic
などが指定される。realm
:保護領域を説明する。これは、「本番アプリへのアクセスである」などをメッセージに設定することで、ユーザーが、どの領域にアクセスしようとしているかを通知する。
引用元:https://qiita.com/KWS_0901/items/29963df6625af3e3fd07
Basic認証は以下のような特徴を持つ。
- Base64 でエンコードした資格情報(ユーザー名とパスワード)を
Authorization:Basic
リクエストヘッダーに付与する認証方法 - 可逆エンコードのため、HTTPでは平文で送信される
通信の流れは以下のようになる。
- クライアントは認証が必要なページをリクエストする。しかし、通常ここではユーザ名とパスワードを送っていない。なぜならばクライアントはそのページが認証を必要とするか否かを知らないためである。
- サーバは401レスポンスコードを返し、認証領域 (authentication realm) や認証方式 (Basic認証) に関する情報をクライアントに知らせる。
- それを受けたクライアントは、認証領域(通常は、アクセスしているコンピュータやシステムの簡単な説明)をユーザに提示して、ユーザ名とパスワードの入力を求める。ユーザはここでキャンセルすることもできる。
- ユーザによりユーザ名とパスワードが入力されると、クライアントはリクエストに認証ヘッダを追加して再度送信する。
- 認証に成功すると、サーバは認証の必要なページのリクエストを処理する。一方、ユーザ名やパスワードが間違っていた時には、サーバは再び401レスポンスコードを返す。それによりクライアントは再びユーザにユーザ名とパスワードの入力を求める。
引用:https://ja.wikipedia.org/wiki/Basic%E8%AA%8D%E8%A8%BC
Basic認証の突破方法
Basic認証は、Authorizationヘッダーで以下のように送ったり
Authorization: Basic <BASE64エンコードしたユーザー名:パスワード>
※ユーザー名、パスワードに@を含む場合にはURLエンコードが必要
URLに設定したりすることで認証を突破することができる。
https://<ユーザー名>:<パスワード>@www.example.com/login
参考:https://qiita.com/HeRo/items/22751e828791be173529
ちなみにBasic認証のパスワード以外の文字列はユーザー名あるいはIDと呼ばれることがある。
どちらが正しいかを簡単に調べたところ、はっきりとはわからなかった。
また時間があるときに調べようと思うが、Wiki(日本語)とMDNではユーザー名(username)と記載されている。
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Authorization
大昔になにかの記事でBasic認証はボットで突破されにくいと言うのを見た気がするが、ソースが見つからず定かではない。
理由はボットの処理が上述のようにAuthorizationヘッダーやURLエンコードなども挟む必要があって、処理が複雑化するからなのかもしれないが、だからといって簡単すぎるパスワードを設定するのは望ましくないといえる。
Basic認証は危険なのか
よくネットで危険と言われているが、その理由として上述のようにAuthorizationヘッダーに可逆変換可能なBase64エンコードが利用されているため、パスワードが平文で流れるという状態になるからという説明が多くある。
その結果、盗聴することができれば簡単に復元できるといった趣旨であると思われる。
AuthorizationヘッダーはHTTPリクエストのたびに送信されるので、何度も送信される状況になるのだが、ほかの認証方法においても大概そうだし、最近ではHTTPS通信が一般化しているため、その場合は暗号化されるため解読はできない。
そのため、簡易パスワード認証方法としていまでも現役で使われている。