lobsters/lobsters

Check passwords against Have I Been Pwned

Open

#1,478 建立於 2025年3月2日

在 GitHub 查看
 (18 留言) (0 反應) (0 負責人)Ruby (961 fork)user submission
featurereqgood first issue

倉庫指標

Star
 (4,680 star)
PR 合併指標
 (平均合併 7天 4小時) (30 天內合併 20 個 PR)

描述

We recently got some garbage-tier spam (keyword-building for a captcha-breaking service). Oddly, the account mohanpierce99 was four years old with some light, realistic (if self-promo-y) usage.

When I looked at the logs, the same IP had first logged into srijancse, poked around, and logged out a couple minutes before. That account was also inactive, but there's a plausible github account with the same username. It had invited 3 accounts - 2 were unused with throwaway emails, 1 was already banned for trying to redeem an invite it sent (voting ring/sockpuppet setup, person goofed by opening the invite link in the logged-in browser they sent it from). Based on the prior abuse, inactivity, and shared login I banned it as an alt.

Also in the logs, the same IP had logged out and into a third account, also unused. I left that one alone so I could watch the logs to gather more info if the spammer returned.

I've been reviewing logs and chatting with the other mods about it because this all didn't quite match a familiar pattern, especially the fact that the accounts are years old. (Usually garbage-tier spammers are not patient.) Irene recognized it was probably account takeover and... yep! I searched the emails of the used accounts on Have I Been Pwned and all of them list a breach named Stealer Logs, Jan 2025 (and many others, it's ugly out there).

I no longer think the accounts I banned were alts of a spammer setting up a voting ring, I think they were all compromised in a breach and a spammer with a credential-stuffing script hit us. It's even possible the entire process was automated.

To prevent future abuse, we should use the HIBP Pwned Passwords list (announcement) to prevent this:

  • create a background job to download the hibp password database (what's the cadence for hibp: weekly, monthly updates?)
  • decide on a threshold of how many times a password has been seen to be refused
  • User: add validation that new password is not in list
  • LoginController#login block breached passwords, explain situation, render pre-filled reset password form

(Yes, prod has much more than enough available disk for the full download.)

I would especially appreciate kibitzing from any Lobsters users who have implemented similar security controls professionally, it seems very likely we have experts in the community.

EDIT: This plan has received exactly the kind of experienced advice I hoped for, so I plan to follow that lead:

  • Method to check a local password hash list like the roycewilliams list of the 20k most common password from HIBP, just import the file into our repo (Is there a more recent version than Nov 2021? By their nature commonly chosen passwords don't change too often, but it'd be nice.)
  • If that check passes, check the HIBP API with a 1500 ms timeout (to match pwnd-passwords-django, though this is 3x higher than I guessed)
  • Check on login - force failures into reset flow
  • Check on setting a new password in the reset flow
  • Check on setting a new password in /settings

貢獻者指南