Date: April 9, 2026 Target: https://reggiebeer.com/ReggieLogin.php Method: Unauthenticated black-box review via page source inspection
| # | Issue | Severity |
|---|---|---|
| 1 | User PII (names, locations) embedded in unauthenticated HTML | π΄ Critical |
| 2 | Client-side hex encoding of passwords (security theater) | π High |
| 3 | SendPassword() suggests plaintext password storage/email |
π High |
| 4 | No CSRF tokens on login form | π High |
| 5 | Password length capped at 20 characters | π‘ Medium |
| 6 | Missing autocomplete attribute on password field |
π‘ Medium |
| 7 | Admin email exposed in page HTML | π‘ Medium |
| 8 | 16 JavaScript console errors | π΅ Low |
| 9 | PHP extension reveals server technology | π΅ Low |
| 10 | Security headers unverified | π΅ Informational |
The LastNameListNew dropdown is populated server-side and embedded directly in the page HTML. The DOM contains entries of the form:
<span>Forrest, Barry (Dallas, TX, US)</span>Raw text in browser tolls
George, Alex (Rockingham, VA, US)|||George, Brendon (Everett, WA, US)|||George, Bryan (Amarillo, TX, US)|||George, Charles (New Bern, NC, US)|||George, David (EUGENE, OR, US)|||George, Jessica (Everett, WA, US)|||George, Kevin (Bradford, MA, US)|||George, Luke (Charlotte, NC, US)|||George, Neal (Navarre, FL, US)|||George, Shackil (Denver, CO, US)|||George, Tim (Livonia, MI, US)|||George, William (Crest Hill, IL, US)|||Georgia, Joel (Englewood, CO, US)
Any unauthenticated visitor can open View Source or DevTools and enumerate all registered user accounts, along with their full names, cities, states, and countries. This is a significant privacy violation and a direct breach of user data confidentiality.
Recommendation: Never embed user lists in unauthenticated page responses. Autocomplete lookups should be performed server-side via authenticated AJAX calls, returning results only after identity is established.
The form contains a hidden field:
<input type="password" name="Bin2HexPswd" id="Bin2HexPswd" style="display:none">The visible password input (id="LoginPassword") has no name attribute, meaning it is not submitted directly. Instead, the LoginSubmit() JavaScript function converts the typed password to a hex representation before placing it in Bin2HexPswd and submitting the form.
This is not encryption β it is trivially reversible encoding. Anyone who reads the JavaScript (fully visible in DevTools > Sources) can decode it immediately. If the server stores or compares against this hex value, it provides zero security benefit over plaintext storage.
Recommendation: Remove client-side password transformation entirely. Use proper server-side password hashing (bcrypt, Argon2). TLS (HTTPS) already protects passwords in transit β client-side encoding adds no real value and creates a false sense of security.
The forgot-password button calls SendPassword() β not SendPasswordResetLink() or similar. Combined with the UI label reading "Forgot your passwords?" (plural), this strongly suggests the application stores passwords in recoverable form and emails them to users in plaintext.
Passwords should never be recoverable, and they should never be emailed directly.
Recommendation: Implement a one-time reset token sent via email that expires quickly (e.g., 15β60 minutes). Never store or transmit recoverable passwords. Use a one-way hashing algorithm (bcrypt, Argon2) for all stored credentials.
There are no CSRF tokens visible anywhere in LoginForm. While login CSRF is a lower-severity variant compared to authenticated CSRF, it can be used to force a victim into an attacker-controlled session (session fixation via CSRF), which can then be used to harvest credentials or monitor actions.
Recommendation: Add a per-session, cryptographically unpredictable CSRF token to all forms and validate it server-side on every submission.
<input type="password" id="LoginPassword" size="5" maxlength="20">The maxlength="20" attribute artificially limits users to 20-character passwords. This prevents the use of strong passphrases and reduces the overall entropy ceiling of all accounts. It also hints β consistent with Finding #3 β that passwords may be stored in a form where length matters to the storage mechanism (e.g., a fixed-width column), which is another indicator of non-hashed storage.
Recommendation: Remove the maxlength restriction on password fields. Modern password hashing algorithms (bcrypt, Argon2) are not sensitive to input length.
The password input does not specify an autocomplete attribute. This can cause inconsistent browser behavior and may prevent password managers from correctly identifying or auto-filling the field.
Recommendation: Add autocomplete="current-password" to the password field.
The page embeds a mailto:Nelson@ReggieBeer.com link in the unauthenticated HTML. While not severe in isolation, admin and contact email addresses embedded in public pages are prime targets for phishing campaigns and account takeover attempts.
Recommendation: Obscure or omit admin email addresses from public-facing pages, or replace them with a contact form.
The DevTools console shows 16 errors and 2 warnings on page load. While not directly exploitable, a high error count indicates unmaintained or poorly tested code, which may harbour deeper logic or security bugs.
The .php extension reveals the server-side technology stack, which narrows the attack surface for a motivated attacker targeting known PHP vulnerabilities.
Recommendation: Consider URL rewriting to remove file extensions from public URLs.
The following HTTP response headers could not be confirmed as present without direct access to raw HTTP responses. These should be verified and added if missing:
Strict-Transport-Security(HSTS) β enforces HTTPSContent-Security-Policyβ mitigates XSSX-Frame-Options(orframe-ancestorsin CSP) β prevents clickjackingX-Content-Type-Options: nosniffβ prevents MIME sniffingReferrer-Policyβ controls referrer leakage
Additionally, session cookies should be verified to carry the HttpOnly, Secure, and SameSite=Strict flags.
- Immediately remove user data from unauthenticated page HTML (Finding #1). This is a live data leak affecting all registered users.
- Audit password storage to confirm whether passwords are stored as recoverable hex values or properly hashed (Finding #2 and #3). If recoverable, migrate to bcrypt/Argon2 immediately and invalidate all existing credentials.
- Rename or replace
SendPassword()with a proper token-based reset flow (Finding #3). - Add CSRF tokens to all forms (Finding #4).
- Remove the
maxlengthcap on the password field (Finding #5). - Audit and add HTTP security headers (Finding #10).