Skip to content
Vidabug
Sign inStart a project
CASE STUDY · CLIENT NAME REMOVED

A training lesson of a web app

If the UI hides it, the server must still refuse it — and a link needs a route

These defects show features wired in the interface but never finished in the code, plus authorization and secrets left in the client. Fix the API first, then the UI.

What went wrong, and how to avoid it

  1. A whole feature (client tax mapping) and a Findings list/dismiss API have no route or handler anywhere in the delivered code Why: The routers and pages were never written into this build, or live somewhere that was not shipped, so the feature cannot be run, reviewed or tested.Avoid it: Treat every user-visible link, tab and API path as a checklist item with a matching route test that fails when the route is absent. Make the route-existence check part of CI so an unreachable page fails the build.
  2. Admin tabs hidden only by a client-side role check, with no server guard on the admin APIs Why: The UI hides views but the backend trusts this display-only check, so anyone can call the admin endpoints directly.Avoid it: Enforce role checks on every admin endpoint server-side and keep the UI hiding as convenience only. Add a test that calls each admin API as a non-admin user and expects a 403.
  3. Working demo passwords printed in clear text on the public sign-in page Why: The credentials were hard-coded into a public page component rather than provisioned from server config, so anyone gets access wherever this bundle ships.Avoid it: Remove demo credentials from the login page; if a demo is required, set it up only in non-production with rotating, unprivileged accounts. Block console logging and add a secret-scanning check to the build so credentials are caught before shipping.
  4. Error handler logs the whole error object, which can echo the request body, and returns two different 4xx response shapes on the same route family Why: The raw error is passed straight to console.error instead of a whitelisted summary, and the version-conflict helper bypasses the shared response envelope.Avoid it: Log a fixed summary (correlation id, method, url, code, message) and never the raw error or body. Send every 4xx through one envelope builder, including helper-generated conflicts, and test the response shape per route.

Read the full report on the home page →