◆ ログイン情報を Google にも送って流出チェックしてくれてる
◆ これまで開発用の適当な情報でも出たことなかった
◆ 何故か出たので理由調べようと 簡易環境作ったら出なくなった

Chrome ではなにかのサービスにログインするときにログイン情報を Google にも送って その情報が流出してたら警告してくれる機能があります
知ってはいたのですが 実際に自分のアカウントで出たことはなく 開発時の適当なログイン情報でも出ていませんでした
なので完全に忘れていたような機能だったのですが テスト用の適当なアカウントでログインしたときにその警告が出てきました

chrome-password-warning

画像の通り localhost:8000 へのログインです
localhost への POST であっても照合されてるようです

ログイン先の情報と一緒にチェックするなら localhost は無視しそうなものです
そうなると id と password の組み合わせだけで判断してそうです
しかし id と password だけでも どういうパラメータ名で送られるのかはサービスによって違います
id が username や userid かもしれませんし 同じ username でも userName や user_name みたいになってるかもしれません
そのパラメータ名まで固定してしまうと 有用性が落ちてしまいそうですし 気になるところです

そのへんを色々試してみようと思ったのですが この警告が出たのは hapi で作ったサーバで 少し複雑めです
最小限のログインの仕組みを作ろうと PHP で作ってみたのですが……なぜか出ません

同じアラートが連続して出ても邪魔だし しばらく出ない仕組みなのかと思いましたが もう一度 hapi の方で試すと何度でも表示されます
もしかしてオリジンが影響するのかと思って同じ localhost:8000 にして POST 先の path まで一緒にしましたが再現しません

POST した中身やレスポンスの set-cookie などでログインかどうかを判断してそうなので hapi の場合に返ってきた レスポンスの header を全部コピーしてそのまま PHP で返すようにしました
しかし それでも出ません

試した結果余計に Chrome がどういう条件で判断しているのかが謎になりました……

気が向いたときにもう少し試してみます

追記

PHP でも出るようにできました
cookie などを設定する必要すらなくて これだけでもチェックしてくれました

<?php
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
echo 'a';
} else {
?>
<form method="POST">
<input name="id" />
<input name="pw" type="password" />
<button>POST</button>
</form>
<?php
}

これに user1/user1 を入れて送信すると警告が出ます

分岐しやすく POST にしていますが POST である必要もありません
GET でも警告が出ます

また input の name は id と pw である必要なく name をランダムな文字列 "fjao23nb1nzhoa" みたいなものにしても警告が出ました
ただし type="password" の input が必須で さらにその一つ前に input が必要のようです
type="password" の input とその前の input が user1/user1 だと 3 つ以上の input でも警告が出ました
しかし type="password" を最初に持ってくると 2 つや 3 つの input を用意してすべて user1 を入力しても出ませんでした

加えて フォームの送信後のページが送信前と同じページとみなされるとチェックされないようです
同じだと入力したパスワードが間違っていてログインフォームが表示されてるという扱いなのでしょう
この「同じとみなされる」というのは 単純に HTML が一致したというものではありません
多少 HTML に違いがあっても許容されます
エラーメッセージの表示だったり トークンや時刻情報などの変化で HTML が完全に一致しないことが多いからだと思います
試してみた感じでは文字をあちこちに追加してもチェックされませんでした
見ている部分はおそらくフォームです
フォームの input の name を変えると警告が出ました
同じ input のフォームがあるならログイン画面のまま というのはまぁ正しそうですけど そこまで Chrome が見てるんですね……

追記2

どこにリクエストを送ってチェックしてるのか気になったので調べてみました
パスワードチェック対象の POST をするとき次の 2 箇所にリクエストを送っていました

https://www.googleapis.com/oauth2/v4/token
https://passwordsleakcheck-pa.googleapis.com/v1/leaks:lookupSingle

1 つ目の URL へのリクエストでベアラートークンを取得して それを 2 つ目の URL へのリクエストのヘッダーで送信していました
トークンの取得は毎回する必要がないので連続で POST すると 2 つ目の URL へのリクエストのみになります

2 つ目の URL へのリクエストのボディ部分はハッシュ化されているようです
POST するデータの文字数を変えても 42bytes のバイナリデータで固定でした
Chrome のソースでもみないとどういうハッシュ化がされているかまではわからないです

どうハッシュ化して送ればいいかはわからないので 直接この URL へアクセスするような使い方は難しそうですが そもそも Chrome で password 付きフォームを POST すれば自動でチェックしてくれているのでそういう使い方をする必要もないでしょう