ModernUO/Projects/UOContent
Kamron Batman dce677b8c3 fix(accounts): gate the password repair on a per-account tag
The repair retried a failed verify against username + plainPassword, and
nothing in a stored hash distinguishes "this is H(username + password)
because SetPassword was buggy" from "this password merely begins with the
username". With repairMigratedPasswords on, that is a cheap targeted attack
against every account on the shard:

  Account 'bob', real password 'bob123', stored correctly as argon2("bob123").
  Someone submits '123'. The primary verify against "123" fails. The repair
  verifies "bob" + "123" == "bob123" and succeeds, forceRehash rewrites the
  credential to argon2("123"), and the real owner can never log in again --
  their password has been silently replaced by the attacker's guess.

Passwords that start with the username are common enough that this is worth
doing at scale, and it is silent: the victim only finds out later.

Add a second gate on top of the shard-wide switch. The account must also
carry a RepairMigratedPassword tag, which an operator sets from the admin
gump (Account Details -> Tags -> Add Tag) for someone who has actually
reported being locked out. That reduces exposure from every account on the
shard to one an operator deliberately marked, and in the real workflow the
collision cannot arise at all: a colliding account still logs in fine, so
nobody would ever mark it. The tag is removed on a successful repair, so the
window closes for that account immediately.

Also repair the other corruption shape. The old guard short-circuited on
UsesUsernamePhrase(_passwordAlgorithm), so SHA1/SHA2 accounts were never
repaired -- but SetPassword also runs from the Account(string, string)
constructor before _passwordAlgorithm is assigned, so an account created
while CurrentAlgorithm was SHA1 or SHA2 holds H(bare password) tagged
SHA1/SHA2, whose rule adds the username. Those accounts could never log in
at all and the repair declined to rescue them. RepairPhrase now tries
whichever rule the stored algorithm does not use, covering both directions.
That direction has no truncation collision -- exploiting it would need the
attacker to already know the real password -- but it stays behind both gates.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-07 17:30:45 -07:00
..
Accounting fix(accounts): gate the password repair on a per-account tag 2026-08-07 17:30:45 -07:00
Assistants chore: Use var everywhere (#2294) 2025-12-27 16:47:28 -08:00
Commands feat(network): allowlist false-positive IPs, escalate on behavior (#2556) 2026-07-30 23:12:17 -07:00
Compression feat: Implements new robust/pluggable backup/archive system. (#2388) 2026-03-22 19:51:20 -07:00
Configuration fix: Streamlines insurance. Insurance only executes when enabled. (#2550) 2026-07-26 09:47:49 -07:00
Console feat: Adds console commands (#1714) 2024-03-30 09:40:43 -07:00
Context Menus fix: Moves ContextMenu out of core, streamlines code, fixes bugs (#1873) 2024-07-20 21:33:23 -07:00
Engines fix(opl): refuse property list invalidation raised from inside GetProperties (#2555) 2026-07-28 21:29:03 -07:00
Gumps feat(network): allowlist false-positive IPs, escalate on behavior (#2556) 2026-07-30 23:12:17 -07:00
Holiday Stuff perf: Migrate Veteran Reward gumps to DynamicGump/StaticGump (#2415) 2026-04-25 20:09:27 -07:00
Items fix: Streamlines insurance. Insurance only executes when enabled. (#2550) 2026-07-26 09:47:49 -07:00
Migrations feat(throwing): add remaining SA throwing artifacts (add-only) (#2516) 2026-07-03 08:50:16 -07:00
Misc feat(network): allowlist false-positive IPs, escalate on behavior (#2556) 2026-07-30 23:12:17 -07:00
Mobiles fix: Streamlines insurance. Insurance only executes when enabled. (#2550) 2026-07-26 09:47:49 -07:00
Multis fix(housing): register doors, and stop crashing on client component sheets (#2557) 2026-08-04 20:05:28 -07:00
Network feat(network): allowlist false-positive IPs, escalate on behavior (#2556) 2026-07-30 23:12:17 -07:00
Regions fix: Fixes criminals having guards called on them (#2348) 2026-03-13 17:35:47 -07:00
Skills feat: Pre-Publish 14 Crafting (supersedes #2181, #2381) (#2476) 2026-06-07 20:27:22 -07:00
Special Systems feat: Add zero-alloc interpolation handler to ValueStringBuilder, replace all StringBuilder usage (#2387) 2026-03-22 14:23:44 -07:00
Spells fix(necromancy): correct Blood Oath duration, reflection, and expiry timing (#1690) (#2480) 2026-06-08 23:42:28 -07:00
Systems/JailSystem fix: Bumps deps. Updates copyrights (#2353) 2026-03-05 19:36:54 -08:00
Targets chore: Use var everywhere (#2294) 2025-12-27 16:47:28 -08:00
Text fix: Bumps deps. Updates copyrights (#2353) 2026-03-05 19:36:54 -08:00
Utilities fix: Harden Advanced Search: crash-safety, autosave, correct results & worker fixes (#2543) 2026-07-21 07:51:06 -07:00
World Saves perf(messages): mechanical interpolation cleanups (#2436) 2026-05-03 18:26:49 -07:00
Module.cs fix: Fixes sending packets and sidesteps a major issue with stackalloc and PGO in .NET 8 (#1607) 2023-11-21 12:18:20 -08:00
UOContent.csproj feat(accounts): default to Argon2id at 16 MiB, t=1 2026-08-07 16:44:31 -07:00