Your RSA-2048 keys break in 2030. Find every one of them before attackers do.
📦 npm
Not in CISA KEV

Qinglong has an incomplete fix for CVE-2026-3965: Improper AuthenticationGHSA-v667-gc2r-2xm7

Fix: whyour/qinglong#2941

GHSA-v667-gc2r-2xm7 is a Improper Authentication vulnerability in @whyour/qinglong. A fix is available for @whyour/qinglong — see the affected versions and patch details below.

Also known asCVE-2026-55445
Published
Updated
Affected
1 pkg
Patched
1 / 1
Exploits
None indexed
Exploitation data as of Oct 12, 2026 · OSV.dev, NVD, FIRST.org (EPSS)

Exploitation Status

Proof-of-concept exploit code exists

  • CISA’s SSVC triage found public proof-of-concept exploit code for this CVE, though no confirmed active exploitation.
  • CISA assesses this as automatable — exploitation doesn’t require manual, per-target effort, which raises the odds of mass scanning and opportunistic attacks.
  • A successful exploit gives an attacker total control of the affected component, not partial access.

Exploitation and automatability from CISA’s SSVC triage for GHSA-v667-gc2r-2xm7.

EPSS Exploitation Probability

via FIRST.org ↗
0.7%probability of exploitation in next 30 days
Lower Risk0.00%
Lower risk than most CVEs50th percentile — riskier than 50% of all scored CVEsHighest risk
0.16%0.50%0.83%1.16%0.7%0.7%Sep 26Oct 26

Probability of exploitation in the next 30 days, from FIRST.org EPSS.

Real-World Exposure

1 pkg affected

How broadly this vulnerability is actually deployed: weekly install volume shows current usage, and reverse-dependency count shows how many other packages break if it stays unpatched.

0other npm packages depend on this — each one inherits the vulnerability until it's patched upstream
@whyour/qinglongnpm
612downloads / week

Description

Summary

The init guard middleware in Qinglong only checks /api/user/init paths but not /open/user/init, which is whitelisted from JWT authentication and rewritten to /api/user/init after the guard has already passed, allowing unauthenticated admin credential reset on initialized instances.

Affected Package

  • Ecosystem: npm
  • Package: whyour/qinglong
  • Affected versions: < 6bec52dca158
  • Patched versions: >= 6bec52dca158

Severity

Medium

CWE

CWE-287 — Improper Authentication

Details

The Qinglong panel has an initialization endpoint (/api/user/init) that allows setting admin credentials. Once the system is initialized, an init guard middleware is supposed to block further calls. The middleware in back/loaders/express.ts only checks:

!['/api/user/init', '/api/user/notification/init'].includes(pathLower)

However, the application also has a URL rewrite rule: rewrite('/open/*', '/api/$1'). The /open/* paths are whitelisted from JWT authentication.

The middleware ordering creates the bypass: first, JWT auth sees /open/* paths match the whitelist regex and skips authentication. Second, the init guard only checks for /api/user/init -- /open/user/init passes through as "not an init path". Third, the URL rewrite transforms /open/user/init to /api/user/init after the guard has already passed.

This means an unauthenticated attacker can send PUT /open/user/init with new credentials to reset the admin account on any Qinglong panel instance, gaining full administrative access.

PoC

/**
 * CVE-2026-3965 - Qinglong Panel /open/user/init Auth Bypass
 *
 * The init guard middleware only checks /api/user/init paths.
 * But /open/user/init is whitelisted from JWT auth and rewritten
 * to /api/user/init via express-urlrewrite AFTER the guard.
 */

"use strict";

// Simulate the init guard middleware exactly as in the source
function initGuardMiddleware(reqPath, authInfo) {
  const pathLower = reqPath.toLowerCase();
  // Exact check from the vulnerable source
  if (!['/api/user/init', '/api/user/notification/init'].includes(pathLower)) {
    return { action: "next" }; // passes through
  }

  let isInitialized = true;
  if (
    Object.keys(authInfo).length === 2 &&
    authInfo.username === 'admin' &&
    authInfo.password === 'admin'
  ) {
    isInitialized = false;
  }

  if (isInitialized) {
    return { action: "block", code: 450, message: "Error" };
  } else {
    return { action: "next" };
  }
}

const authInfo = { username: "realAdmin", password: "str0ngP@ss!" };
console.log("System state: initialized (non-default credentials)");

// Test 1: Direct /api/user/init is blocked
const test1 = initGuardMiddleware("/api/user/init", authInfo);
console.log("\n[Test 1] PUT /api/user/init:");
console.log("  Guard result:", test1.action);
console.log("  Blocked:", test1.action === "block");

// Test 2: /open/user/init BYPASSES init guard
const test2 = initGuardMiddleware("/open/user/init", authInfo);
console.log("\n[Test 2] PUT /open/user/init:");
console.log("  Guard result:", test2.action);
console.log("  Bypassed guard:", test2.action === "next");

if (test2.action === "next") {
  const rewrittenPath = "/open/user/init".replace(/^\/open\//, "/api/");
  console.log("  After rewrite:", rewrittenPath);
  console.log("  Reaches init handler: true");
}

if (test1.action === "block" && test2.action === "next") {
  console.log("\nVULNERABILITY CONFIRMED: /open/user/init bypasses the init guard");
  console.log("An attacker can reset admin credentials on an initialized instance.");
  process.exit(0);
} else {
  console.log("\nVULNERABILITY NOT CONFIRMED");
  process.exit(1);
}

Steps to reproduce:

  1. git clone https://github.com/whyour/qinglong /tmp/qinglong_test
  2. cd /tmp/qinglong_test && git checkout 6bec52dc~1
  3. node poc.js

Expected output:

VULNERABILITY CONFIRMED
/open/user/init bypasses the init guard; the guard only checks /api/user/init but /open/ path is whitelisted and rewritten after.

Impact

An unauthenticated attacker can send PUT /open/user/init with new credentials to reset the admin account on any Qinglong panel instance. This provides full administrative access, enabling the attacker to execute arbitrary cron jobs and scripts on the server.

Suggested Remediation

Add /open/user/init and /open/user/notification/init to the init guard check list. Alternatively, move the URL rewrite middleware to run before the init guard. Consider implementing the init guard at the handler level rather than as path-based middleware.

References

Affected Packages

1 total 1 fixed
EcosystemPackageVulnerable rangeFix
📦npm@whyour/qinglongall versions2.20.1npm install @whyour/qinglong@2.20.1

Detection & mitigation playbook

Open-source dependency
  1. Detect

    Scan your dependency tree (package-lock.json, pnpm-lock.yaml, requirements.txt, go.sum, etc.) for @whyour/qinglong, including transitive dependencies — a direct dependency you never call can still pull in a vulnerable version.

  2. Fix

    Update @whyour/qinglong to 2.20.1 or later, then make sure no transitive (indirect) dependency still pins the vulnerable range — O3 confirms GHSA-v667-gc2r-2xm7 is resolved across your whole dependency graph.

  3. Workarounds

    Put an independent control in front of the weakness: restrict the affected endpoint or interface to trusted networks, require an additional authentication factor or proxy-level check, and invalidate existing sessions and credentials in case the flaw has already been used.

Frequently Asked Questions

### Summary The init guard middleware in Qinglong only checks `/api/user/init` paths but not `/open/user/init`, which is whitelisted from JWT authentication and rewritten to `/api/user/init` after the guard has already passed, allowing unauthenticated admin credential reset on initialized instances. ### Affected Package - **Ecosystem:** npm - **Package:** whyour/qinglong - **Affected versions:** < 6bec52dca158 - **Patched versions:** >= 6bec52dca158 ### Severity Medium ### CWE CWE-287 — Improper Authentication ### Details The Qinglong panel has an initialization endpoint (`/api/user/i
O3 Security · Impact-Aware SCA

Is GHSA-v667-gc2r-2xm7 in your dependencies?

Find it across npm, including transitive dependencies.

Qinglong has an incomplete fix for CVE-2026-3965:…