DEV Community

Cover image for BroncoCTF : Super Secure Server
Yogeshwar Peela
Yogeshwar Peela

Posted on Edited on Originally published at exploitnotes.hashnode.dev

BroncoCTF : Super Secure Server

Executive Summary

Super Secure Server presents a login form that appears to check a username and password, but does nothing of the sort. The page's own JavaScript fetches the "secret" credentials from an unauthenticated /api/config endpoint, then compares them against the user's input entirely in the browser. If the comparison passes, the client just POSTs {"authenticated": true} to /login — a flag the server trusts unconditionally, with no actual credential check on its side. Sending that payload directly, without ever supplying real credentials, was enough to authenticate and read the flag.

Root cause: authentication state is decided client-side and asserted to the server via a trusted boolean, rather than being verified server-side against real credentials.

Flag: bronco{d0nt_3xp0se_p@ssw0rd5!}


Recon

Pulled the login page to see how the client-side flow actually works:

curl https://broncoctf-super-secure-server.chals.io/
Enter fullscreen mode Exit fullscreen mode
<form id="loginForm">...</form>
<script>
  let leakedUser = "";
  let leakedPass = "";
  fetch('/api/config')
    .then(res => res.json())
    .then(data => {
      leakedUser = data.username;
      leakedPass = data.password;
    });
  document.getElementById('loginForm').addEventListener('submit', function(e) {
    e.preventDefault();
    const u = document.getElementById('username').value;
    const p = document.getElementById('password').value;
    // client-side password comparison
    if (u === leakedUser && p === leakedPass) {
      fetch('/login', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ authenticated: true })
      }).then(res => res.json())
        .