picoCTF · picoGym Web Exploitation Easy 50 pts

Transparent JS — Credentials in Public JavaScript

OWASP A07 — Identification and Authentication Failures

Vulnerability Overview

The application's entire authentication logic — including hardcoded admin credentials — was implemented in a publicly accessible JavaScript file named secure.js. Client-side authentication provides no security because the user controls the execution environment.

Discovery

Viewing the login page source revealed it loaded secure.js and contained a hidden admin form. Opening secure.js directly in the browser exposed the complete authentication function:

function checkPassword(username, password) {
  if (username === 'admin' && password === 'strongPassword098765') {
    return true;
  }
  return false;
}

The credentials were in plain text. Logging in with admin / strongPassword098765 returned the flag.

Root Cause

Authentication was performed entirely in the browser. Any validation that runs on the client can be read, modified, or bypassed by the user — the check can be overridden by simply setting the return value to true in the console, regardless of input. Storing credentials in public JavaScript compounded the issue.

ControlImplementation
Server-side authentication onlyCredentials must be verified on the server — never in browser JavaScript
No hardcoded credentialsCredentials belong in a secure secrets manager, never in source code
Password hashingEven server-side, passwords must be stored as Argon2 or bcrypt hashes, never plain text
Key Insight: A JavaScript file named secure.js that contains plaintext credentials and client-side authentication is a contradiction in terms. Authentication is only meaningful when it happens on a system the user cannot inspect or modify — which is always the server, never the browser.
Flag See challenge on picoCTF picoGym