Live · auth, hardening, and a test suite
Prime Accounts Inc authentication & hardening
Full-stack developer
Most real engineering happens on top of something that already runs. This was a live FrontAccounting/PHP site: table-based markup, vendored webmail and calendar apps, no bundler, and no chance of a rewrite. Sign-in did not work at all. The submission guard had been copy-pasted into two dozen handlers with drifting variable names, so no two behaved the same and none of them was tested. I replaced the authentication system, centralised the guard, and wrote the suite that proves both still work.
- PHP
- PDO
- Security hardening
- Session management
- Regression testing
- Microsoft Graph API
- Auth
- PDO · split-token links
- Guard
- 5 gates · 24 handlers
- Tests
- 8 suites · HTTP-driven
- IFTA refactor
- Two copies · one library
Authentication / split-token links
The database never holds a secret that would work.
An invite or reset link carries a 128-bit selector and a 256-bit verifier. The selector finds the row; only a SHA-256 of the verifier is stored, and it is compared with hash_equals so the check cannot be walked one character at a time.
Links are single-purpose, single-use, and expire. A reset bumps the account's session epoch, which ends every other session it had open.
A leaked tokens table contains nothing an attacker can present.
The problem
A production legacy system with real users depending on its routes, forms, and email flows. Login was broken outright, the same honeypot-to-CSRF gauntlet existed in twenty-four slightly different copies, and identifiers as sensitive as social insurance numbers were moving through it. I could not add a bundler, drop in a framework, or rewrite the data layer. Everything had to be fixed in place, without changing a single field name or POST target.
What I owned
The authentication system end to end: PDO-backed accounts, split-token invite and reset links, two-axis throttling, session epochs, and Luhn-checked identifiers stored masked. One shared library for the five-gate submission guard, replacing the copy-pasted version in every handler. An invoice generator with a server-authoritative tax engine and a from-scratch PDF writer. And an eight-suite regression harness that drives the real pages over HTTP against a throwaway database.
The hard parts
Authenticating people on a site with no working login, and no framework to lean on.
Split-token links carry a 128-bit selector to find the row and a 256-bit verifier compared with hash_equals, so the database never stores a secret that would work if it leaked. Throttled at eight failures per address and thirty per IP in a fifteen-minute window.
Holding identifiers nobody wants to be holding.
Social insurance numbers are Luhn-checked before they are accepted and masked everywhere they are shown. The identifier's prefix distinguishes a person from a corporation, so the filing pages never ask a company for its marital status.
Proving any of it, on a stack with no test culture at all.
Eight suites on stock PHP with no dependencies. The auth suite drives the real pages over HTTP against a throwaway SQLite database, and a preloaded mail stub means nothing can reach Microsoft Graph.
The result
Twenty-four handlers now refuse an unauthenticated POST and send nothing, each gate still bites on its own, and a wrong password is indistinguishable from an unknown address. All of it is guarded by a suite that runs in ninety seconds on stock PHP, and every check in it exists because something actually broke.



