CVE-2025-13877
Description
A vulnerability was detected in nocobase up to 1.9.4/2.0.0-alpha.37. The affected element is an unknown function of the file nocobase\packages\core\auth\src\base\jwt-service.ts of the component JWT Service. The manipulation of the argument API_KEY results in use of hard-coded cryptographic key . The attack can be launched remotely. A high complexity level is associated with this attack. The exploitability is described as difficult. The exploit is now public and may be used. The vendor was contacted early about this disclosure but did not respond in any way.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
@nocobase/authnpm | >= 1.9.0, < 1.9.23 | 1.9.23 |
@nocobase/authnpm | < 1.9.0-beta.18 | 1.9.0-beta.18 |
@nocobase/authnpm | >= 2.0.0-alpha.1, < 2.0.0-alpha.52 | 2.0.0-alpha.52 |
Affected products
1Patches
1de4292ea7847fix(auth): CVE-2025-13877 (#8128)
5 files changed · +41 −23
packages/core/auth/src/auth-manager.ts+29 −1 modified@@ -13,6 +13,10 @@ import { Auth, AuthExtend } from './auth'; import { JwtOptions, JwtService } from './base/jwt-service'; import { ITokenBlacklistService } from './base/token-blacklist-service'; import { ITokenControlService } from './base/token-control-service'; +import path from 'path'; +import fs from 'fs'; +import crypto from 'crypto'; + export interface Authenticator { authType: string; options: Record<string, any>; @@ -49,7 +53,11 @@ export class AuthManager { constructor(options: AuthManagerOptions) { this.options = options; - this.jwt = new JwtService(options.jwt); + const jwtOptions = options.jwt || ({} as JwtOptions); + if (!jwtOptions.secret) { + jwtOptions.secret = this.getDefaultAPIKey(); + } + this.jwt = new JwtService(jwtOptions); } setStorer(storer: Storer) { @@ -142,4 +150,24 @@ export class AuthManager { await next(); }; } + + private getDefaultAPIKey(): Buffer | string { + const apiKeyPath = path.resolve(process.cwd(), 'storage', 'apps', 'main', 'api_key.dat'); + const appKeyExists = fs.existsSync(apiKeyPath); + if (appKeyExists) { + const key = fs.readFileSync(apiKeyPath); + if (key.length !== 32) { + throw new Error('Invalid api key length in file'); + } + return key; + } + const envKey = process.env.APP_KEY; + if (envKey && envKey !== 'your-secret-key' && envKey !== 'test-key') { + return envKey; + } + const key = crypto.randomBytes(32); + fs.mkdirSync(path.dirname(apiKeyPath), { recursive: true }); + fs.writeFileSync(apiKeyPath, key, { mode: 0o600 }); + return key; + } }
packages/core/auth/src/base/jwt-service.ts+4 −7 modified@@ -9,22 +9,19 @@ import jwt, { JwtPayload, SignOptions } from 'jsonwebtoken'; import { ITokenBlacklistService } from './token-blacklist-service'; + export interface JwtOptions { - secret: string; + secret: Buffer | string; expiresIn?: string; } export type SignPayload = Parameters<typeof jwt.sign>[0]; export class JwtService { - constructor( - protected options: JwtOptions = { - secret: process.env.APP_KEY, - }, - ) { + constructor(protected options: JwtOptions) { const { secret, expiresIn } = options; this.options = { - secret: secret || process.env.APP_KEY, + secret, expiresIn: expiresIn || process.env.JWT_EXPIRES_IN || '7d', }; }
packages/core/test/src/server/mock-server.ts+2 −2 modified@@ -124,7 +124,7 @@ export class MockServer extends Application { agent(callback?): ExtendedAgent { const agent = supertest.agent(callback || this.callback()); const prefix = this.resourcer.options.prefix; - const authManager = this.authManager; + const authManager = this.authManager as any; const proxy = new Proxy(agent, { get(target, method: string, receiver) { if (['login', 'loginUsingId'].includes(method)) { @@ -142,7 +142,7 @@ export class MockServer extends Application { roleName, signInTime: Date.now(), }, - process.env.APP_KEY, + authManager.jwt.secret(), { jwtid: tokenInfo.jti, expiresIn,
packages/plugins/@nocobase/plugin-acl/src/server/__tests__/role-user.test.ts+2 −3 modified@@ -10,7 +10,6 @@ import Database, { BelongsToManyRepository } from '@nocobase/database'; import UsersPlugin from '@nocobase/plugin-users'; import { createMockServer, MockServer } from '@nocobase/test'; -import jwt from 'jsonwebtoken'; import { SystemRoleMode } from '../enum'; import { UNION_ROLE_KEY } from '../constants'; @@ -146,7 +145,7 @@ describe('role', () => { await userRolesRepo.add('test1'); await userRolesRepo.add('test2'); - const userToken = jwt.sign({ userId: user.get('id') }, 'test-key'); + const userToken = api.authManager.jwt.sign({ userId: user.get('id') }); const response = await api .agent() .post('/users:setDefaultRole') @@ -188,7 +187,7 @@ describe('role', () => { roleMode: SystemRoleMode.allowUseUnion, }, }); - const userToken = jwt.sign({ userId: user.get('id') }, 'test-key'); + const userToken = api.authManager.jwt.sign({ userId: user.get('id') }); const response = await api .agent() .post('/users:setDefaultRole')
packages/plugins/@nocobase/plugin-workflow-request/src/server/__tests__/instruction.test.ts+4 −10 modified@@ -625,16 +625,10 @@ describe('workflow > instructions > request', () => { it('request db resource', async () => { const user = await db.getRepository('users').create({}); - const token = jwt.sign( - { - userId: user.id, - signInTime: Date.now(), - }, - process.env.APP_KEY, - { - expiresIn: '1d', - }, - ); + const token = app.authManager.jwt.sign({ + userId: user.id, + signInTime: Date.now(), + }); const server = app.listen(0, () => {});
Vulnerability mechanics
Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
14- github.com/advisories/GHSA-mv7p-34fv-4874ghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2025-13877ghsaADVISORY
- docs.nocobase.com/welcome/getting-started/installation/docker-composeghsaWEB
- gist.github.com/H2u8s/f3ede60d7ecfe598ae452aa5a8fbb90dnvdWEB
- github.com/nocobase/nocobase/blob/main/docker/app-mariadb/docker-compose.ymlghsaWEB
- github.com/nocobase/nocobase/blob/main/docker/app-mysql/docker-compose.ymlghsaWEB
- github.com/nocobase/nocobase/blob/main/docker/app-postgres/docker-compose.ymlghsaWEB
- github.com/nocobase/nocobase/blob/main/docker/app-sqlite/docker-compose.ymlghsaWEB
- github.com/nocobase/nocobase/commit/de4292ea7847dd26c6306445091769f8b9ee96d5ghsaWEB
- github.com/nocobase/nocobase/security/advisories/GHSA-mv7p-34fv-4874ghsaWEB
- v2.docs.nocobase.com/get-started/installation/dockerghsaWEB
- vuldb.comnvdWEB
- vuldb.comnvdWEB
- vuldb.comnvdWEB
News mentions
0No linked articles in our index yet.