過去のリンクが危険なサイトに乗っ取られているのを検知するシステムの作成方法
ウェブサイトの寿命は案外短いもので、記事に挿入したリンク先のサイトが全然別のサイトになっていたり、リンクが切れていたりするという連絡を読者の方からよく頂きます。リンク先が無害なサイトであれば良いのですが、フィッシングサイトやマルウェアサイトになってしまっていると大変危険だということで、URLから危険なサイトを判定してくれるGoogleのAPI「Web Risk」を利用して定期的にサイト全体のリンクをチェックする仕組みを作成しました。
Web Risk | Google Cloud
https://cloud.google.com/web-risk
Web Riskには記事作成時点で「Lookup API」と「Update API」の2つのAPIが存在しています。Lookup APIの方はURLを流し込めば直接安全か危険かを判定してくれるというわかりやすいAPIな一方、Update APIの方はハッシュの先頭数バイトが詰まったデータベースをダウンロード後、調べたいURLの先頭ハッシュが一致したら完全なハッシュを再度取得し、一致判定するという複雑な仕組みになっており、できれば片っ端からLookup APIを叩いて解決したいところ。
料金表を確認すると、Lookup APIは10万回を超えた分について1000回あたり0.5ドル(約55円)の費用が発生するとのこと。GIGAZINEの記事をチェックしてみると、全部で約100万件ものリンクが存在しており、全てをLookup APIで処理した場合の一回の調査費用は約5万円です。一方Update APIの方は最初のハッシュデータベースのダウンロードは無料で、その後完全なハッシュの取得回数1000回ごとに50ドル(約5500円)という料金体系。料金の検討をするには、まずハッシュの先頭がどの程度の頻度で一致するのかを調べる必要があります。
APIを利用するために、GCPのコンソールからサービスアカウントを作成し、認証情報をダウンロードします。
ダウンロードした認証情報を「GOOGLE_APPLICATION_CREDENTIALS」環境変数に設定して準備完了。
Update APIのガイドに記載されているサンプルによると、ハッシュデータベースは下記の形式で取得できるとのこと。
{ "recommendedNextDiff": "2020-01-08T19:41:45.436722194Z", "responseType": "RESET", "additions": { "rawHashes": [ { "prefixSize": 4, "rawHashes": "AArQMQAMoUgAPn8lAE..." } ] }, "newVersionToken": "ChAIARAGGAEiAzAwMSiAEDABEPDyBhoCGAlTcIVL", "checksum": { "sha256": "wy6jh0+MAg/V/+VdErFhZIpOW+L8ulrVwhlV61XkROI=" } }
全ての先頭ハッシュが結合されてbase64形式で渡されるので、手元で「prefixSize」に指定されているバイト数ごとに切り分けて利用します。今後の利用を考えて、下記のように切り分けた状態でjsonファイルに保存しました。このハッシュは随時更新されるため、本番でチェックを走らせる場合には毎回新たなハッシュを入手する必要があります。
このデータベースには4バイトの先頭ハッシュが合計4997件含まれていたため、安全なURLのハッシュが間違って判定されてしまう可能性は2の32乗分の4997で約20万分の1と計算できます。ここから100万件のリンクを調査する費用は約25円となり、Lookup APIと比較すると圧倒的に安価なためUpdate APIを採用することに。
Update APIを利用する場合、まずURLからハッシュを作成する必要があります。ガイドに詳細な手順が記載されているため、ガイド通りに変換していくだけでOK。それぞれテストケースが記載されているので実装の際にはかなり助かります。URLの正規化のテストケースにある「http://\x01\x80.com/」→「http://%01%80.com/」だけはどういう変換なのか分からずじまいでしたが、GIGAZINE内にこのようなURLのリンクは設定されていないので無視しました。もし詳しい方が居れば、こちらのフォームからご連絡いただけるとありがたいです。
一つのURLから複数のハッシュが生成されるので、それぞれデータベースに一致するハッシュがないかチェックし、すべてのハッシュについて一致がなければそのURLは安全なURLと判定できます。どれか一件でも一致があった場合はその先頭ハッシュを元にUpdate APIのsearchを利用して完全なハッシュリストを入手し、さらに一致するか検証します。マルウェア判定のテストを下図のように作成し、実装を進めました。
こうしてサイトに含まれているリンクを毎日チェック可能な仕組みが完成しました。古いサイトがいつの間にか放棄されて悪質なサイトに変わっていた場合でも、すぐに気付いてリンクを修正できるようになりました。幸いなことに、記事作成時点ではまだテストケース以外でマルウェア判定されたURLは存在していません。
なお、GIGAZINEは現在求人中で、こうした内容に興味がある人を募集しています。応募お待ちしています。
GIGAZINE採用情報. – GIGAZINEだからできることが、ある。
https://gigazine.co.jp/
・関連記事
機械学習でGIGAZINEの関連記事を自動生成するサーバーを作ってみました - GIGAZINE
電力源を2つにして停電などの障害に強いシステムを構築できる「ATS」を導入してみた - GIGAZINE
合計18万台近いHDDの故障率レポート2021年Q2版をBackblazeが公開、HDDとSSDの故障率比較も - GIGAZINE
PCの電源を入れたままストレージを交換できるホットスワップに対応したリムーバブルケース「ICY DOCK MB326SP-B」を使ってみた - GIGAZINE
無料でIFTTTやZapierっぽく全自動連携できる「n8n」を自サーバー上に構築してみた - GIGAZINE
・関連コンテンツ