Login security and authentication hardening
What makes a login trustworthy, what the application review found, and what I learned about securing identity from sign-up through session termination.
Scope and assurance
This review was completed August 3, 2026 against the local source trees, packaged application evidence, safe runtime configuration checks, public response headers, and current OWASP and NIST guidance. It covered OpenTrail, OpenLinks, WeaveNote, Cinderstrike, BiasLens, Shadowbroker administrative access, Krawl dashboard access, and the public Technology Wiki.
No real credentials were submitted, no secrets were read or published, and no destructive brute-force or account-lockout testing was performed. A code and configuration review can find control gaps, but it is not a penetration-test certificate and cannot guarantee that a login is secure.
The secure-login security model
A login form is only the visible beginning of an identity system. A secure design protects the entire lifecycle.
HTTPS is required, but TLS alone does not prevent weak passwords, stolen browser tokens, session fixation, authorization mistakes, insecure recovery, or a database outage that causes the application to trust stale privileges.
Passwords, passphrases, and storage
Password policy
- For password-only login, require at least 15 characters; where the password is part of MFA, require at least eight.
- Allow long passphrases, spaces, Unicode, paste, and password managers; do not silently trim or truncate.
- Do not force uppercase/lowercase/number/symbol composition rules. Length and breached-password blocking provide better value.
- Block common, expected, context-specific, and known-compromised passwords.
- Do not require scheduled password changes without evidence of compromise.
Password storage
- Never encrypt or store a login password in reversible or plain form.
- Prefer Argon2id with reviewed memory, iteration, and parallelism settings.
- When bcrypt is retained, use a cost of at least 10 and explicitly handle its 72-byte input limit.
- Use the library's random per-password salt and constant-time verification.
- Support work-factor upgrades during a successful login.
Unknown accounts should still perform a realistic password-hash verification so response time does not become a username-discovery signal. Error text should remain consistent for unknown user, wrong password, and disabled account until identity has been safely proven.
Sessions, JWTs, and browser storage
After login, the session token is temporarily as powerful as the authenticator. Token handling therefore matters as much as password hashing.
Do not store session IDs, JWTs, refresh tokens, administrator keys, or other bearer credentials in localStorage or sessionStorage. Any script running in that origin can read them.
Automated attacks, enumeration, and monitoring
- Rate-limit login by account and by trusted client/network signal; a single IP-only counter is not enough.
- Use progressive delay or carefully designed lockout without giving an attacker an easy denial-of-service switch.
- Do not trust forwarded client-IP headers unless requests can only arrive through a controlled proxy that overwrites them.
- Keep responses and timing similar for valid and invalid accounts.
- Log success, failure, throttling, recovery, MFA changes, role changes, and session revocation without recording passwords or raw tokens.
- Alert on credential stuffing, distributed guessing, unusual administrator access, impossible travel where relevant, and repeated recovery activity.
- Use CAPTCHA or adaptive challenges only as defense in depth; they do not replace rate limits or MFA.
Rate-limit state must survive ordinary process restarts and work across replicas when the application scales. Security logs need retention, access restrictions, useful timestamps, and a response playbook.
MFA, passkeys, and privileged accounts
Passwords are replayable and phishable. Administrative accounts, applications holding private notes or customer contact data, and systems capable of updating software or changing infrastructure should add a second factor.
- Prefer WebAuthn/passkeys or hardware-backed FIDO authenticators for phishing resistance.
- TOTP can improve password-only login, but codes entered into a phishing site are not phishing-resistant.
- Require step-up authentication for role changes, password/MFA changes, destructive actions, secret viewing, software updates, exports, and recovery.
- Provide more than one authenticator and protected one-time recovery codes.
- Treat MFA reset as a high-risk recovery event with notification and session review.
- Keep database, middleware, service, and infrastructure accounts out of public user login interfaces.
Password recovery and identity changes
Recovery is another login path and cannot be weaker than normal authentication.
Reset request
- Return the same message and similar timing whether the account exists or not.
- Rate-limit by account and network and prevent email/SMS flooding.
- Generate a random, single-use, short-lived token; store it securely and bind it to one account and purpose.
- Construct reset links from an approved origin, not an untrusted Host header.
Reset completion
- Apply the normal password-strength and breached-password rules.
- Notify the verified contact channel of the change without sending the password.
- Do not automatically sign the user in after reset.
- Invalidate existing sessions automatically or give a clear secure option.
- Require reauthentication and notification for email, role, and MFA changes.
Application authentication review
| Application | Verified strengths | Material gaps | Assessment |
|---|---|---|---|
| OpenTrail | Argon2id at the OWASP baseline; dummy-hash login; generic failure; random opaque sessions; token hashes at rest; rotation, logout, ban revocation; server authorization. | The running public stack does not currently enable the Secure cookie setting even though the production overlay does. Password minimum is 10 rather than the current 15-character password-only guidance. No confirmed MFA, breached-password block, verified-email, or recovery path. | Strong design foundation with a high-priority production configuration correction. |
| OpenLinks | Auth.js; bcrypt cost 12; generic credential errors; public Auth.js cookies verified HttpOnly, Secure, SameSite=Lax, and no-store; OAuth account linking protection; current database role/ban checks on privileged operations. | Eight-character password minimum, long JWT lifetime, no confirmed login throttling, MFA/passkeys, credential-email verification, or password recovery. Dummy-hash behavior should be timing-tested. | Good baseline; requires lifecycle and abuse-resistance hardening. |
| WeaveNote | Bcrypt cost 12; JWT secret rejects missing/default runtime configuration; login and registration have an in-memory IP limiter. | JWT is stored in localStorage; seven-day bearer tokens have no demonstrated revocation; protected administrator APIs trust the role inside the token; one verification path fails open when the database is unavailable; an administrator-created user can receive a known default password; password policy is short/composition-based; some server errors are returned to clients. | Critical redesign required before calling the login hardened. |
| Cinderstrike | Production secrets required; constant-time credential comparison; eight-hour signed session in HttpOnly, Secure, SameSite=Strict cookie; loopback-bound application; protected server actions restrict approved origins. | No confirmed login throttling, MFA, recovery, session revocation, or step-up authentication. Password input is trimmed. Public login response lacked several defense-in-depth headers during review. | Good session-cookie basics; privileged login needs brute-force and MFA hardening. |
| BiasLens | Google/Firebase sign-in avoids application-managed passwords. | Current Firestore rules allow every read and write, the admin interface accepts any authenticated Google user, and the feed-processing operation lacks a confirmed server-side administrator check. The login does not create authorization. | Critical authorization failure; keep stopped until rules and server checks are redesigned. |
| Shadowbroker | Sensitive endpoints use an administrator key when configured; the running container has the setting present; endpoint rate limiting exists; current services bind to loopback. | The static bearer key is stored in browser localStorage, sent in a custom header, compared directly, and the backend intentionally fails open if configuration is missing. There is no user/session lifecycle, MFA, or immediate per-session revocation. | Replace the administrator-key pattern before broader exposure. |
| Krawl lab | Fake login pages are intentional deception and submitted values are sanitized before storage. | The real dashboard relies on a secret URL rather than authentication, the configured path is weak, and the service is host-published. Dashboard data includes hostile traffic and submitted credential material. | Dashboard must be network-restricted and protected by real authentication; obscurity is not login security. |
| Technology Wiki | Public, read-only content requires no account, reducing identity attack surface. | A future protected runbook or editor would require a separate threat model and authentication design before implementation. | Keep the public wiki login-free until a real private capability needs identity. |
These findings describe reviewed source and current observable configuration. They must be rechecked after remediation and on every authentication-related release.
Prioritized remediation roadmap
Authentication preflight checklist
Identity and threat model
- List user types, administrators, service identities, assets, trust boundaries, abuse cases, and assurance level.
- Choose framework-managed identity/session components before writing custom token code.
- Define registration, verification, recovery, role change, disablement, deletion, and last-administrator behavior.
- Draft the project wiki update with planned authentication and authorization changes.
Passwords, MFA, and recovery
- Use current length, blocklist, character, maximum-size, hashing, and work-factor rules.
- Offer password-manager-friendly fields and phishing-resistant MFA for privileged users.
- Design recovery tokens, expiry, single use, notifications, rate limits, and session invalidation.
- Remove default credentials and fail startup when required secrets are missing.
Sessions and authorization
- Choose HttpOnly/Secure/SameSite cookie scope, idle/absolute expiry, rotation, revocation, and no-store behavior.
- Validate JWT algorithm, signature, issuer, audience, expiry, subject, and current account state.
- Define server-side permission and ownership checks for every protected action.
- Fail closed when identity, role, session, or policy state cannot be verified.
Abuse and operations
- Rate-limit by account and trusted network signal with durable shared state.
- Use generic failure messages and timing-resistant unknown-user handling.
- Record safe audit events, alerts, proxy trust, HTTPS, headers, backup, response, and rollback requirements.
- Write negative tests before deployment, including stale role, banned user, cross-user access, and database outage.
Authentication postflight checklist
Browser and transport
- Verify forced HTTPS, hostname/certificate, cookie flags and scope, no-store, security headers, and absence of bearer tokens in browser storage or URLs.
- Confirm forwarded client identity is accepted only from the controlled proxy.
- Inspect production assets and logs for secrets, tokens, password values, and internal errors.
Positive journeys
- Test registration/verification where applicable, login, MFA, refresh, reauthentication, password change, recovery, logout, and session revocation.
- Confirm the intended role can complete only the intended object-level actions.
- Verify health checks exercise critical authentication dependencies rather than only configuration presence.
Negative journeys
- Test unknown user, wrong password, breached password, throttling, banned/suspended/deleted user, expired/reset token, stale role, direct API access, and cross-user records.
- Stop the identity database or provider and confirm protected operations fail closed.
- Test restart and horizontal instances so rate limits and revocation remain effective.
Close and learn
- Review audit events and alerts without exposing credentials or sensitive personal data.
- Update the project wiki with verified controls, unresolved risk, evidence, lessons, and next remediation priority.
- Keep rollback and incident actions available until the authentication release is stable.
What I learned
- A login page can work perfectly while the application behind it remains publicly writable. Authentication without server-side authorization is only appearance.
- Password hashing protects a stolen database; it does not stop phishing, browser-token theft, credential stuffing, insecure recovery, or stale administrator roles.
- HttpOnly, Secure cookies reduce browser credential exposure. localStorage is appropriate for preferences, not bearer authentication secrets.
- JWT signatures prove that a claim was issued; they do not prove that the user is still active or still an administrator.
- Fail-open behavior turns an ordinary dependency outage into a security bypass. Identity and privilege checks must fail closed.
- A secret URL or static administrator key is not a complete login system because it lacks user identity, lifecycle, MFA, auditability, rotation, and per-session revocation.
- MFA—preferably passkeys/WebAuthn for administrators—changes the outcome of a stolen-password attack.
- Recovery, role changes, bans, password changes, and logout are part of login security, not separate future features.
- Deployment can invalidate good code: a missing Secure cookie flag or an unintentionally public management service changes the real risk.
- Security is evidence-based and continuous. Each project preflight plans identity impact; each postflight re-tests it and updates the wiki.