CVE-2023-30363
Description
vConsole v3.15.0's setOptions function allows prototype pollution via crafted key strings, enabling attackers to modify object prototypes.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
vConsole v3.15.0's setOptions function allows prototype pollution via crafted key strings, enabling attackers to modify object prototypes.
Vulnerability
Details
The vulnerability resides in vConsole's setOptions function within core.ts. The function parses a key string (e.g., "a.b") by splitting on periods and recursively assigns values to nested properties. However, it fails to validate special keys like __proto__ or constructor.prototype. This allows an attacker to set properties on the object prototype, a classic prototype pollution weakness [1]. The vulnerable code is shown in the GitHub issue [4].
Exploitation
An attacker can exploit this by controlling the keyOrObj parameter passed to setOptions. For example, if user input is supplied as a string like "__proto__.polluted" with a malicious value, the function will assign that value to Object.prototype.polluted. This requires no authentication if the function is exposed to untrusted input, such as through a query parameter or stored data that later triggers setOptions. The attack surface is present whenever vConsole is used in an environment where user-controlled data can reach this method.
Impact
Successful prototype pollution can lead to property injection across all objects in the application. Depending on how the polluted property is used, consequences may include denial of service, privilege escalation, or remote code execution. For instance, setting __proto__.isAdmin to true could bypass authorization checks if the application checks for that property. The impact is amplified because vConsole is a front-end debugging tool often included in production builds, potentially exposing many applications.
Mitigation
The vulnerability was reported and patched in a subsequent version [4]. Users should update vConsole to the latest version (≥3.15.1). Additionally, developers should avoid passing untrusted input to setOptions and sanitize any user-controlled keys. As a best practice, vConsole should not be enabled in production environments.
AI Insight generated on May 20, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
vconsolenpm | < 3.15.1 | 3.15.1 |
Affected products
2- vConsole/vConsoledescription
Patches
1b91591703490Fix(core): Fix prototype pollution in `vConsole.setOption()`. (issue #616 #621)
2 files changed · +18 −2
dev/common.html+5 −0 modified@@ -93,6 +93,11 @@ vConsole.setOption('log.maxLogNumber', 20); vConsole.setOption({ network: { maxNetworkNumber: 30 }}); vConsole.setOption({ network: { b: 123 }}); // overwrite previous line + vConsole.setOption({ '__proto__': { a: 1 }, 'prototype': { b: 2 }, 'constructor': 3 }); + vConsole.setOption('__proto__.noOrig', 1); + vConsole.setOption('prototype.noOrig', 2); + vConsole.setOption('constructor', () => { console.log('hack') }); + vConsole.setOption('log.__proto__.noOrig', 1); console.log(vConsole.option); }
src/core/core.ts+13 −2 modified@@ -517,21 +517,32 @@ export class VConsole { * @example `setOption({ log: { maxLogNumber: 20 }})`: overwrite 'log' object. */ public setOption(keyOrObj: any, value?: any) { + if (typeof keyOrObj === 'string') { // parse `a.b = val` to `a: { b: val }` const keys = keyOrObj.split('.'); let opt: any = this.option; - for (let i = 0; i < keys.length - 1; i++) { + for (let i = 0; i < keys.length; i++) { + if (keys[i] === '__proto__' || keys[i] === 'constructor' || keys[i] === 'prototype') { + console.debug(`[vConsole] Cannot set \`${keys[i]}\` in \`vConsole.setOption()\`.`); + return; + } if (opt[keys[i]] === undefined) { opt[keys[i]] = {}; } + if (i === keys.length - 1) { + opt[keys[i]] = value; + } opt = opt[keys[i]]; } - opt[keys[keys.length - 1]] = value; this._triggerPluginsEvent('updateOption'); this._updateComponentByOptions(); } else if (tool.isObject(keyOrObj)) { for (let k in keyOrObj) { + if (k === '__proto__' || k === 'constructor' || k === 'prototype') { + console.debug(`[vConsole] Cannot set \`${k}\` in \`vConsole.setOption()\`.`); + continue; + } this.option[k] = keyOrObj[k]; } this._triggerPluginsEvent('updateOption');
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
6- github.com/advisories/GHSA-f737-3fh6-jf6wghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2023-30363ghsaADVISORY
- cwe.mitre.org/data/definitions/1321.htmlghsaWEB
- github.com/Tencent/vConsole/commit/b91591703490e032451f7734212f6458bde9be6aghsaWEB
- github.com/Tencent/vConsole/issues/616ghsaWEB
- github.com/Tencent/vConsole/releases/tag/v3.15.1ghsaWEB
News mentions
0No linked articles in our index yet.