Automated Patch Intelligence for Security Engineers
CRITICAL 10.0 · 2026-10-07 · JavaScript
quasar · Pattern: UNSANITIZED_INPUT→XSS · 128x across ecosystem
Root cause : The Quasar Framework's Server-Side Rendering (SSR) mechanism for meta tags (like title, meta, link, script, noscript) did not properly escape user-controlled input before rendering it into the HTML head. This allowed attackers to inject arbitrary HTML and JavaScript.
Impact : An attacker could inject malicious scripts into web pages, leading to session hijacking, defacement, redirection, or other client-side attacks against users viewing the affected pages.
Diff
--- a/ui/src/plugins/meta/Meta.js
+++ b/ui/src/plugins/meta/Meta.js
@@ -148,15 +190,17 @@ function apply({ add, remove }) {
function getAttr(seed) {
return att => {
if (isValidAttrName(att) === false) return
const val = seed[att]
return att + (val !== true && val !== void 0 ? ="${val}" : '')
return att + (val !== true && val !== void 0 ? ="${encodeHtml(val)}" : '')
}
}
function getHead(meta) {
let output = ''
if (meta.title) {
output += <title>${meta.title}</title>
output += <title>${encodeHtml(meta.title)}</title>
}
;['meta', 'link', 'script'].forEach(type => {
const metaType = meta[type]Fix : The patch introduces several HTML and JSON encoding functions (`encodeHtml`, `encodeJson`, `protectRawText`) and a validation function for attribute names (`isValidAttrName`). These functions are applied to all user-controlled data rendered within meta tags, attributes, and script contents to ensure proper escaping and prevent injection.
CRITICAL 10.0 · 2026-10-07 · JavaScript
@payloadcms/plugin-form-builder · Pattern: MISSING_AUTHZ→RESOURCE · 127x across ecosystem
Root cause : The vulnerability stemmed from overly permissive access control configurations in the Payload Form Builder plugin. Specifically, the 'read' access for 'FormSubmissions' and the 'emails' field within 'Forms' collections was set to allow any logged-in user to read, rather than restricting it to administrative users.
Impact : An attacker, if authenticated as any user (not necessarily an admin), could read sensitive form submission data and email configurations, potentially leading to information disclosure or further attacks.
Diff
- read: ({ req: { user } }) => !!user, // logged-in users,
+ read: ({ req }) => req.user?.collection === req.payload.config.admin.user,Fix : The patch tightens access control by changing the 'read' access logic. Instead of allowing any logged-in user, it now explicitly checks if the logged-in user belongs to the admin user collection configured in Payload CMS, thereby restricting access to administrative users only.
CRITICAL 10.0 · 2026-10-05 · JavaScript
vm2 · Pattern: PROTOTYPE_POLLUTION→OVERRIDE · 39x across ecosystem
Root cause : The vm2 sandbox environment failed to properly protect the prototypes of host TypedArray and ArrayBuffer intrinsics, as well as various iterator prototypes. These prototypes were not included in the list of protected host objects, allowing sandbox code to modify their host-realm definitions.
Impact : An attacker could mutate host TypedArray and ArrayBuffer intrinsics, potentially leading to arbitrary code execution or other severe integrity violations outside the sandbox.
Diff
--- a/lib/bridge.js
+++ b/lib/bridge.js
@@ -31,6 +31,29 @@ const globalsList = [
'WeakSet',
'Promise',
'Function',
+ 'ArrayBuffer',
+ 'SharedArrayBuffer',
+ 'DataView',
+ 'Uint8Array',
+ 'Int8Array',
+ 'Uint8ClampedArray',
+ 'Uint16Array',
+ 'Int16Array',
+ 'Uint32Array',
+ 'Int32Array',
+ 'Float32Array',
+ 'Float64Array',
+ 'BigInt64Array',
+ 'BigUint64Array',
];
const errorsList = [
@@ -79,6 +102,54 @@ try {
thisGlobalPrototypes['AsyncGeneratorFunction'] = eval('(async function*() {})').constructor.prototype;
} catch (e) {}
+// SECURITY (GHSA-3vgf-8m4q-q4qr / GHSA-59g5-pmg6-5gr4): abstract intrinsic
+// prototypes with NO named global. Same protection gap as the binary-data
+// globals above, but they cannot be reached through global[key], so resolve
+// them structurally (mirroring the AsyncFunction / GeneratorFunction pattern).
+// Adding them to thisGlobalPrototypes routes them into protectedHostObjects
+// (which enumerates every key) and the mapping loops below, so the write traps
+// refuse sandbox set / defineProperty on host %TypedArray%.prototype,
+// %IteratorPrototype%, ArrayIterator.prototype, etc.
+// TypedArrayProto — the shared %TypedArray%.prototype above every concrete
+// typed array (Buffer -> Uint8Array.prototype -> %TypedArray%.prototype).
+try {
thisGlobalPrototypes['TypedArray'] = Object.getPrototypeOf(Uint8Array.prototype);
+} catch (e) {}
+// The iterator prototype chain: concrete iterator prototypes and the shared
+// %IteratorPrototype% they all inherit from (GHSA-59g5 targets both).
+try {
const arrayIteratorProto = Object.getPrototypeOf([]Symbol.iterator);
thisGlobalPrototypes['ArrayIterator'] = arrayIteratorProto;
thisGlobalPrototypes['IteratorPrototype'] = Object.getPrototypeOf(arrayIteratorProto);
+} catch (e) {}
+try {
thisGlobalPrototypes['StringIterator'] = Object.getPrototypeOf(''Symbol.iterator);
+} catch (e) {}
+try {
thisGlobalPrototypes['MapIterator'] = Object.getPrototypeOf(new Map()Symbol.iterator);
+} catch (e) {}
+try {
thisGlobalPrototypes['SetIterator'] = Object.getPrototypeOf(new Set()Symbol.iterator);
+} catch (e) {}
+try {
// %RegExpStringIteratorPrototype% — matchAll's iterator (Node 12+).
thisGlobalPrototypes['RegExpStringIterator'] = Object.getPrototypeOf('a'.matchAll(/a/g));
+} catch (e) {}
+// Keys in thisGlobalPrototypes that are NOT named globals (so the
+// globalsList/errorsList mapping loops below do not cover them) but MUST still
+// receive proto + identity mappings so their host prototypes are recognized
+// and their constructor reads collapse to the sandbox realm.
+const nonGlobalProtoKeys = [
'TypedArray',
'ArrayIterator',
'IteratorPrototype',
'StringIterator',
'MapIterator',
'SetIterator',
'RegExpStringIterator',
+];
// Cache this-realm dangerous function constructors.
// Used to block raw host Function constructors from leaking when handlerFix : The patch extends the list of protected global objects to include all TypedArray and ArrayBuffer related intrinsics, as well as various iterator prototypes. It ensures these prototypes are properly mapped and their constructors are collapsed to the sandbox realm, preventing modification from within the sandbox.
CRITICAL 10.0 · 2026-10-05 · JavaScript
vm2 · Pattern: UNCLASSIFIED · 878x across ecosystem
Root cause :
Impact :
Fix :
CRITICAL 10.0 · 2026-10-05 · JavaScript
vm2 · Pattern: PROTOTYPE_POLLUTION→OVERRIDE · 39x across ecosystem
Root cause : The vm2 sandbox allowed an attacker to obtain raw host-realm prototype-reading functions (like `Object.prototype.__proto__` getter or `Object.getPrototypeOf`). By invoking these functions on a wrapped host object, the sandbox could pierce the flattened prototype chain enforced by the bridge, gaining access to intermediate host builtin prototypes (e.g., `EventEmitter.prototype`). These intermediate prototypes were not protected against modification, allowing the attacker to write a callable function onto them.
Impact : An attacker could achieve Remote Code Execution (RCE) by installing a malicious function on a shared host prototype (e.g., `EventEmitter.prototype.emit = fn`). When a host-side operation later invoked this function with a host `this` context, the attacker's code would execute outside the sandbox with host privileges.
Diff
--- a/lib/bridge.js
+++ b/lib/bridge.js
@@ -1124,10 +1224,16 @@ function createBridge(otherInit, registerProxy) {
const protoDesc = otherSafeGetOwnPropertyDescriptor(otherGlobalPrototypes.Object, '__proto__');
if (protoDesc) {
addDangerousHostProtoMutator(protoDesc.set);
- // Note: we intentionally do NOT add the getter — reading a host
- // prototype is not, by itself, a privilege escalation primitive, and
- // blocking the getter would break legitimate `instanceof` and
- // inspection paths.
+ // SECURITY (GHSA-88hf-g992-jg85): classify the host `__proto__` GETTER
+ // as dangerous-to-DELIVER (not dangerous-to-invoke). Extracting the raw
+ // host getter and calling `gP.call(x)` pierces the bridge's flattened
+ // prototype view and hands the sandbox the true intermediate host
+ // builtin prototypes (EventEmitter.prototype, etc.), which are writable.
+ // We do NOT add it to the mutator set (which THROWS in the apply trap
+ // and would break legitimate `instanceof` / inspection that internally
+ // walk prototypes); instead we deny its DELIVERY at the read-side
+ // chokepoints so the sandbox can never hold the raw reader to invoke.
+ addDangerousHostProtoReader(protoDesc.get);
}
// Cache host `Function.prototype.call` / `Function.prototype.apply` as
// the canonical indirection primitives. The canonical PoC reaches hostFix : The patch introduces `dangerousHostProtoReaders` to identify and prevent the delivery of raw host prototype-reading functions into the sandbox. It also adds `hostObjectsUsedAsPrototype` and `looksLikeHostPrototype` to structurally identify and protect host prototype objects from having sandbox-controlled functions written to them, even if a future read path exposes them.
CRITICAL 10.0 · 2026-10-05 · JavaScript
vm2 · Pattern: UNCLASSIFIED · 878x across ecosystem
Root cause : The vm2 sandbox allowed sandboxed code to access Node.js's shared Buffer pool. When a small Buffer was created, it would often be backed by a shared 64 KiB ArrayBuffer. The sandboxed code could then obtain a reference to this entire shared ArrayBuffer, allowing it to read and write memory outside its intended boundaries, including data from other host-realm buffers.
Impact : An attacker could achieve a full sandbox escape, leading to arbitrary read and write access to the host-realm memory. This could result in information disclosure (e.g., reading secrets, database rows) and integrity compromise (e.g., corrupting host data), effectively breaking the isolation provided by the sandbox.
Diff
--- a/lib/setup-sandbox.js
+++ b/lib/setup-sandbox.js
@@ -584,7 +584,11 @@ class BufferHandler extends ReadOnlyHandler {
checkBufferAllocLimit(args[0]);
return LocalBuffer.alloc(args[0]);
}
- return apply(LocalBuffer.from, LocalBuffer, args);
+ // SECURITY (GHSA-fcqc-726x-5wfc): deprecated Buffer(array|string|arrayBuffer)
+ // form aliases Buffer.from. Route through `bufferFrom` so the result is
+ // depooled (exact-size backing store) — a raw `LocalBuffer.from` here would
+ // return a pool-backed buffer whose `.buffer` exposes the shared 64 KiB pool.
+ return apply(bufferFrom, LocalBuffer, args);
}
construct(target, args, newTarget) {</pre>
Fix : The patch modifies Buffer creation methods (Buffer.from, Buffer.concat, Buffer.copyBytesFrom, and Buffer constructor aliases) within the sandbox to ensure that any buffer returned to sandboxed code owns its entire backing store. This is achieved by 'depooling' buffers that would otherwise be backed by Node's shared pool, copying their contents into a new, exact-size, non-pooled ArrayBuffer. This prevents sandboxed code from accessing the larger shared memory pool.
CRITICAL 10.0 · 2026-10-05 · JavaScript
vm2 · Pattern: INSECURE_DEFAULT→CONFIG · 42x across ecosystem
Root cause : The vm2 library, when configured with `require.external: true` but without an explicit `require.root`, allowed sandboxed code to use the host's `require()` function to load arbitrary paths. This effectively granted unrestricted access to the host filesystem and enabled full Remote Code Execution (RCE) because the sandboxed code could load and execute any module available to the host process.
Impact : An attacker could escape the sandbox, execute arbitrary code on the host system with the privileges of the vm2 process, and potentially access or manipulate host files.
Diff
--- a/lib/cli.js
+++ b/lib/cli.js
NodeVM.file(path, {
verbose: true,
require: {
- external: true
+ external: true,
+ root: pa.dirname(path),
+ context: 'sandbox'
}
});Fix : The patch introduces defense-in-depth measures. It prevents sandboxed code from requiring vm2's own package (which could lead to nested unrestricted sandboxes). For the CLI, it explicitly sets `require.root` to the script's directory and `context: 'sandbox'` to ensure external requires are sandboxed. It also adds a security warning when `require.external: true` is used without `require.root` in a host context.
CRITICAL 10.0 · 2026-10-05 · JavaScript
vm2 · Pattern: TYPE_CONFUSION→BYPASS · 17x across ecosystem
Root cause : The vm2 sandbox failed to properly isolate WebAssembly streaming compilation APIs. Specifically, `WebAssembly.compileStreaming` and `WebAssembly.instantiateStreaming` could return Promises whose prototype chain reached the host realm's `Promise.prototype`. This bypasses the sandbox's `then`/`catch` overrides and `resetPromiseSpecies` mechanism, allowing an attacker to manipulate the `Symbol.species` property of the host Promise and execute arbitrary code in the host context.
Impact : An attacker could achieve a complete sandbox escape, executing arbitrary code in the host environment with the privileges of the vm2 process. This leads to remote code execution (RCE) outside the sandbox.
Diff
- if (typeof WebAssembly.promising !== 'undefined') {
- localReflectDeleteProperty(WebAssembly, 'promising');
- }
+ if (typeof WebAssembly.compileStreaming !== 'undefined') {
+ localReflectDeleteProperty(WebAssembly, 'compileStreaming');
+ }
+ if (typeof WebAssembly.instantiateStreaming !== 'undefined') {
+ localReflectDeleteProperty(WebAssembly, 'instantiateStreaming');
+ }Fix : The patch removes `WebAssembly.compileStreaming` and `WebAssembly.instantiateStreaming` from the sandbox environment. By removing these APIs, the sources of cross-realm-prototype Promises are eliminated, preventing attackers from leveraging the Promise species bypass to escape the sandbox.
CRITICAL 10.0 · 2026-10-02 · Python
vibe-trading-ai · Pattern: MISSING_AUTH→ENDPOINT · 82x across ecosystem
Root cause : The application had a 'dev mode' where authentication was skipped if the API_AUTH_KEY environment variable was not set. This dev mode was not sufficiently restricted to local clients, allowing remote attackers to bypass authentication entirely if the key was unset. Additionally, several sensitive API endpoints lacked explicit authentication dependencies.
Impact : An unauthenticated remote attacker could access sensitive API endpoints, potentially leading to command execution, code injection, or Server-Side Request Forgery (SSRF) if the LLM-callable tools were enabled, or at minimum, information disclosure.
Diff
--- a/agent/api_server.py
+++ b/agent/api_server.py
@@ -286,23 +289,74 @@ def _configured_api_key() -> str:
async def require_auth(
cred: HTTPAuthorizationCredentials = Security(_security),
request: Request,
cred: Optional[HTTPAuthorizationCredentials] = Security(_security),
) -> None:
"""Validate Bearer token against API_AUTH_KEY environment variable.
if not api_key:
return
if not cred or cred.credentials != api_key:
api_key = _configured_api_key()
if not api_key:
if _is_local_client(request):
return
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN,
detail="API_AUTH_KEY is required for non-local API access",
)
token = _auth_credential_from_header_or_query(cred, query_api_key, allow_query=allow_query)
if not token or not hmac.compare_digest(token, api_key):
raise HTTPException(status_code=401, detail="Invalid or missing API key")Fix : The patch introduces stricter checks for dev-mode authentication, ensuring it only applies to local clients. It also explicitly adds `require_auth` dependencies to several previously unprotected API endpoints and uses `hmac.compare_digest` for secure token comparison. New environment flags were added to control shell tools and Docker loopback trust.
CRITICAL 10.0 · 2026-10-02 · Python
vibe-trading-ai · Pattern: MISSING_AUTH→ENDPOINT · 82x across ecosystem
Root cause : The application's API endpoints lacked proper authentication checks, especially when the API_AUTH_KEY environment variable was not set. In 'dev mode' (API_AUTH_KEY unset), the system incorrectly allowed unauthenticated access from non-local clients, treating them as local. Additionally, the comparison of API keys was not constant-time, potentially leaking information.
Impact : An unauthenticated attacker could access sensitive API endpoints, including those for file upload and potentially remote code execution (RCE) chains, leading to full system compromise.
Diff
--- a/agent/api_server.py
+++ b/agent/api_server.py
@@ -286,10 +289,20 @@ def _configured_api_key() -> str:
async def require_auth(
cred: HTTPAuthorizationCredentials = Security(_security),
request: Request,
cred: Optional[HTTPAuthorizationCredentials] = Security(_security),
) -> None:
api_key = _configured_api_key()
if not api_key:
return
if not cred or cred.credentials != api_key:
_validate_api_auth(request=request, cred=cred)
+def _validate_api_auth(
*, request: Request, cred: Optional[HTTPAuthorizationCredentials],
query_api_key: Optional[str] = None, allow_query: bool = False,
+) -> None:
api_key = _configured_api_key()
if not api_key:
if _is_local_client(request):
return
raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="API_AUTH_KEY is required for non-local API access")
token = _auth_credential_from_header_or_query(cred, query_api_key, allow_query=allow_query)
if not token or not hmac.compare_digest(token, api_key):
raise HTTPException(status_code=401, detail="Invalid or missing API key")Fix : The patch introduces robust authentication checks, ensuring that even in 'dev mode' (API_AUTH_KEY unset), only genuinely local clients can bypass authentication. It also applies authentication to several previously unprotected GET endpoints and uses `hmac.compare_digest` for constant-time API key comparison to prevent timing attacks.
CRITICAL 10.0 · 2026-10-01 · JavaScript
vm2 · Pattern: UNCLASSIFIED · 878x across ecosystem
Root cause :
Impact :
Fix :
CRITICAL 10.0 · 2026-10-01 · JavaScript
vm2 · Pattern: PRIVILEGE_ESCALATION→ROLE · 53x across ecosystem
Root cause : The vm2 library's NodeVM allowed sandboxed code to call `tls.setDefaultCACertificates()`. This function, when called from within the sandbox, would modify the host process's global TLS trust store, effectively allowing the sandboxed code to influence the security of the entire host application's TLS connections.
Impact : An attacker could replace the host process's default CA trust store, enabling them to intercept and decrypt TLS traffic from the host application by presenting attacker-signed certificates. This leads to a complete compromise of the host's TLS security.
Diff
--- a/lib/builtin.js
+++ b/lib/builtin.js
@@ -210,6 +210,163 @@ if (EventEmitter.EventEmitterAsyncResource) {
// SECURITY (GHSA-98xx-8mx4-x7cm): tls.setDefaultCACertificates(list) replaces
// the calling thread's process-wide default CA trust store, so every subsequent
-// host TLS client that doesn't supply its own ca accepts attacker-signed
-// certificates. This is the same process-wide-mutation class as the already-
-// denied dns.setServers; unlike dns the rest of tls is legitimately useful
-// to sandboxed code, so neutralize just this member. (The native function
-// requires a real host array, which the sandbox can forge via url's
-// URLSearchParams.getAll() — the bridge unwraps it back to a host array — so
-// argument-side defenses are insufficient; the member itself must be removed.)
+function sanitizeTlsModule(mod) {
if (typeof mod.setDefaultCACertificates !== 'function') return mod;
const copy = Object.assign({}, mod);
copy.setDefaultCACertificates = function setDefaultCACertificates() {
throw new Error('tls.setDefaultCACertificates is disabled in vm2 sandboxes: it replaces the host process default CA trust store (GHSA-98xx-8mx4-x7cm).');
};
return copy;
+}Fix : The patch introduces a `sanitizeTlsModule` function that intercepts calls to `tls.setDefaultCACertificates`. Instead of forwarding the call to the host function, it now throws an error, preventing sandboxed code from modifying the host's TLS trust store.
CRITICAL 10.0 · 2026-10-01 · JavaScript
vm2 · Pattern: INFO_DISCLOSURE→STACK_TRACE · 5x across ecosystem
Root cause : The vm2 sandbox exposed host process-wide singletons like `http.globalAgent` and `https.globalAgent` directly to sandboxed code. While these were wrapped as 'read-only', the `readonly()` proxy only prevents property *assignment*, not method calls or event subscriptions. This allowed the sandbox to subscribe to events on the host's global agents.
Impact : An attacker could subscribe to events on the host's `globalAgent` objects, allowing them to observe sensitive information such as HTTP/HTTPS request options (including authorization tokens, private host/port details) and released TLS sockets from unrelated host requests, leading to credential and traffic exfiltration.
Diff
--- a/lib/builtin.js
+++ b/lib/builtin.js
@@ -210,6 +210,163 @@ if (EventEmitter.EventEmitterAsyncResource) {
EventEmitterReferencingAsyncResourceClass = EventEmitterReferencingAsyncResource;
}
+// SECURITY (GHSA-h85j-hv3c-qfgq): http.globalAgent / https.globalAgent are
+// the real process-wide host singletons. The read-only wrap hands them straight
+// to the sandbox, and .on('free'|'keylog'|...) is a read+subscribe, not a
+// property assignment, so it is forwarded to the host object. A sandbox listener
+// then receives live host request options (Authorization tokens, private
+// host/port) and the released host TLSSocket whenever an unrelated host request
+// completes — credential/traffic exfiltration. Replace the exposed globalAgent
+// with a fresh sandbox-dedicated Agent so the sandbox can never reach the host
+// singleton.
+function makeHttpAgentSanitizer(agentKey) {
return function sanitizeHttpModule(mod) {
if (typeof mod.Agent !== 'function' || !mod[agentKey]) return mod;
const copy = Object.assign({}, mod);
const sandboxAgent = new mod.Agent();
// The exposed globalAgent is the sandbox-dedicated one — a direct read +
// `.on('free')` reaches only this empty agent, never the host singleton.
copy[agentKey] = sandboxAgent;</pre>
Fix : The patch replaces the exposed `http.globalAgent` and `https.globalAgent` with fresh, sandbox-dedicated `Agent` instances. It also modifies the `request()` and `get()` methods of the `http` and `https` modules to default to using these sandbox-dedicated agents, preventing sandboxed code from interacting with the host's shared agents.
CRITICAL 10.0 · 2026-09-24 · JavaScript
suneditor · Pattern: UNSANITIZED_INPUT→XSS · 128x across ecosystem
Root cause : The vulnerability existed because the SunEditor's sanitizer could be bypassed. Specifically, when setting code data to the editor, the `_deleteDisallowedTags` function was not consistently applied, allowing malicious HTML content (like script tags) to persist. Additionally, the regular expressions used to identify and remove disallowed tags were not comprehensive enough, failing to catch certain variations or combinations of tags like 'style', 'meta', 'link', and namespaced tags.
Impact : An attacker could inject arbitrary JavaScript code into the editor's content, leading to Cross-Site Scripting (XSS). This could allow them to steal user sessions, deface websites, redirect users, or perform other malicious actions within the context of the user's browser.
Diff
--- a/src/lib/core.js
+++ b/src/lib/core.js
@@ -4764,7 +4764,7 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
* @private
*/
_setCodeDataToEditor: function () {
- const code_html = this._getCodeView();
+ const code_html = this._deleteDisallowedTags(this._getCodeView());
if (options.fullPage) {
const parseDocument = this._parser.parseFromString(code_html, 'text/html');</pre>
Fix : The patch addresses the vulnerability by ensuring that the `_deleteDisallowedTags` function is called when setting code data to the editor, thus sanitizing the input. It also updates the regular expressions (`__disallowedTagsRegExp` and `__disallowedTagNameRegExp`) to include a broader range of potentially malicious tags, such as 'style', 'meta', 'link', and namespaced tags (e.g., 'svg:script'), preventing their injection.
CRITICAL 10.0 · 2026-09-24 · Python
decepticon-sdk · Pattern: UNCLASSIFIED · 878x across ecosystem
Root cause : The vulnerability existed because attacker-controlled web crawl output, when composed into an LLM's context, could contain special-token literals (e.g., <|im_start|>, [INST]) that a self-hosted LLM tokenizer would parse as structural role delimiters. This allowed an attacker to forge system or operator turns, bypassing the intended quarantine envelope.
Impact : An attacker could achieve role-boundary forgery, making the LLM treat attacker-controlled input as authoritative system or operator instructions. This could lead to a full bypass of security controls and potentially arbitrary code execution or data exfiltration, depending on the LLM's capabilities and downstream integrations.
Diff
--- a/packages/decepticon/decepticon/middleware/untrusted_output.py
+++ b/packages/decepticon/decepticon/middleware/untrusted_output.py
@@ -145,5 +146,5 @@ def _format_envelope(
body: str,
) -> str:
cats_attr = f' categories="{",".join(categories)}"' if categories else ""
- safe_body = _MARKER_RE.sub("UNTRUSTED_TOOL\u200bOUTPUT", body)
+ safe_body = _MARKER_RE.sub("UNTRUSTED_TOOL\u200bOUTPUT", neutralize_special_tokens(body))
return (Fix : The patch introduces a `neutralize_special_tokens` function that identifies and 'defangs' known chat-template special-token literals by inserting a zero-width space (U+200B) immediately after the opening bracket. This prevents the tokenizer from recognizing the literal as a special token while keeping the text visually identical. This neutralization is applied to all untrusted content before it is composed into the LLM context.
CRITICAL 10.0 · 2026-09-22 · Python
mcp-atlassian · Pattern: UNSANITIZED_INPUT→SQL · 41x across ecosystem
Root cause : The application was vulnerable to JQL injection because it did not properly sanitize user-supplied project filters before incorporating them into JQL queries. Additionally, it lacked robust SSRF protection, allowing for potential server-side request forgery through redirect validation and DNS rebinding attacks.
Impact : An attacker could bypass configured project restrictions in Jira, potentially accessing or manipulating data outside their authorized scope. The SSRF vulnerabilities could allow an attacker to make arbitrary requests from the server, potentially accessing internal network resources or sensitive cloud metadata.
Diff
--- a/src/mcp_atlassian/jira/search.py
+++ b/src/mcp_atlassian/jira/search.py
- filter_to_use = projects_filter or self.config.projects_filter
- if filter_to_use:
- projects = [p.strip() for p in filter_to_use.split(",")]
+ for filter_str in (self.config.projects_filter, projects_filter):
+ if filter_str:
+ jql = self._and_projects_filter(jql, filter_str)Fix : The patch refactors JQL filtering to ensure that the configured project allowlist is always ANDed with any user-supplied filters, preventing bypass. It also introduces SSRF protection by validating redirects and pinning DNS resolution to prevent rebinding attacks.
CRITICAL 10.0 · 2026-09-08 · JavaScript
maplibre-gl · Pattern: UNSANITIZED_INPUT→XSS · 128x across ecosystem
Root cause : The vulnerability existed because the `DOM.removeAttributes` method iterated directly over `elem.attributes`, which is a live `NamedNodeMap`. When a dangerous attribute was removed using `elem.removeAttribute(name)`, it modified the live collection, causing the loop to skip the next attribute in the original sequence, thus failing to sanitize all malicious attributes.
Impact : An attacker could bypass the HTML sanitizer, allowing them to inject malicious scripts or content into the DOM. This could lead to arbitrary code execution in the user's browser, session hijacking, or defacement of the web application.
Diff
--- a/src/util/dom.ts
+++ b/src/util/dom.ts
@@ -131,7 +131,7 @@ export class DOM {
* @param elem - The element
*/
private static removeAttributes(elem: Element) {
- for (const {name, value} of elem.attributes) {
+ for (const {name, value} of Array.from(elem.attributes)) {
if (!DOM.isPossiblyDangerous(name, value)) continue;
elem.removeAttribute(name);
}Fix : The patch fixes the vulnerability by converting the live `NamedNodeMap` returned by `elem.attributes` into a static array using `Array.from()`. This ensures that all attributes are processed and sanitized, even when attributes are removed during the iteration, preventing the sanitizer bypass.
CRITICAL 10.0 · 2026-09-03 · Go
github.com/siyuan-note/siyuan/kernel · Pattern: UNSANITIZED_INPUT→SQL · 41x across ecosystem
Root cause : The application directly concatenated user-supplied input into SQL queries and regular expressions without proper sanitization or parameterization. Specifically, the `fullTextSearchAssetContent` function, when `method` was set to 2 (SQL) or 3 (Regexp), allowed unauthenticated users to inject arbitrary SQL or regular expression syntax.
Impact : An unauthenticated attacker could execute arbitrary SQL commands on the underlying database, leading to data exfiltration, modification, or deletion. Additionally, they could perform REGEXP injection, potentially causing denial of service or information disclosure through crafted regular expressions.
Diff
--- a/kernel/model/asset_content.go
+++ b/kernel/model/asset_content.go
@@ -74,10 +75,12 @@ func GetAssetContent(id, query string, queryMethod int) (ret *AssetContent) {
table := "asset_contents_fts_case_insensitive"
filter := " id = '" + id + "'"
filter := "id = ?"
args := []any{id}
if "" != query {
filter += " AND `" + table + "` MATCH '" + buildAssetContentColumnFilter() + ":(" + query + ")'"
filter += " AND `" + table + "` MATCH ?"
args = append(args, buildAssetContentColumnFilter()+":("+query+")")
}
projections := "id, name, ext, path, size, updated, " +
highlight(" + table + ", 6, '" + search.SearchMarkLeft + "', '" + search.SearchMarkRight + "') AS content"
stmt := "SELECT " + projections + " FROM " + table + " WHERE " + filter
assetContents := sql.SelectAssetContentsRawStmt(stmt, 1, 1)
highlight(" + table + ", 6, '" + search.SearchMarkLeft + "', '" + search.SearchMarkRight + "') AS content"
stmt := "SELECT " + projections + " FROM " + table + " WHERE " + filter
assetContents := sql.SelectAssetContentsRawStmtNoParseArgs(stmt, args, 1)Fix : The patch refactors SQL query construction to use parameterized queries (prepared statements) via `?` placeholders and `sql.SelectAssetContentsRawStmtNoParseArgs` for all affected functions. It also modifies the regular expression search to use parameterized queries for the `REGEXP` operator, preventing direct concatenation of user input into the regex pattern.
CRITICAL 10.0 · 2026-09-03 · Go
github.com/siyuan-note/siyuan/kernel · Pattern: UNSANITIZED_INPUT→SQL · 41x across ecosystem
Root cause : The application constructed SQL queries by directly concatenating user-controlled input (mentionKeywords and keyword) into the FTS MATCH clause without proper escaping. This allowed an attacker to inject arbitrary SQL into the query by crafting malicious input containing double quotes, breaking out of the intended string literal.
Impact : An attacker could execute arbitrary SQL commands within the database, potentially leading to data exfiltration, modification, or deletion, and could bypass intended access controls.
Diff
- buf.WriteString("\"" + mentionKeyword + "\"")
+ buf.WriteString(quoteFTSPhrase(mentionKeyword))
...
- sqlBlocks := sql.SelectBlocksRawStmtInBox(query, 1, Conf.Search.Limit, boxID)
+ sqlBlocks := sql.SelectBlocksRawStmtArgsInBox(query, args, Conf.Search.Limit, boxID)Fix : The patch introduces a `quoteFTSPhrase` function to properly escape double quotes in user input for FTS queries. It also refactors the query construction to use parameterized queries via `sql.SelectBlocksRawStmtArgsInBox`, ensuring that user input is treated as data rather than executable code.
CRITICAL 10.0 · 2026-09-03 · Go
github.com/siyuan-note/siyuan/kernel · Pattern: UNCLASSIFIED · 878x across ecosystem
Root cause :
Impact :
Fix :
CRITICAL 10.0 · 2026-08-21 · Python
xinference · Pattern: UNSANITIZED_INPUT→COMMAND · 111x across ecosystem
Root cause : The application used the unsafe `eval()` function to parse tool-call arguments from untrusted model outputs. An attacker could craft a malicious string that, when evaluated by `eval()`, would execute arbitrary Python code on the server.
Impact : An attacker could achieve full remote code execution on the server hosting the Xinference application, leading to complete system compromise.
Diff
--- a/xinference/model/llm/utils.py
+++ b/xinference/model/llm/utils.py
- data = eval(text, {}, {})
+ data = json.loads(text)
+ except (json.JSONDecodeError, TypeError):
+ try:
+ data = ast.literal_eval(text)Fix : The patch replaces the unsafe `eval()` calls with a safer parsing mechanism. It first attempts to parse the input as JSON and, if that fails, falls back to `ast.literal_eval()`. `ast.literal_eval()` is a safe alternative to `eval()` for evaluating strings containing Python literal structures, preventing arbitrary code execution.
CRITICAL 10.0 · 2026-08-18 · Ruby
kobako · Pattern: DESERIALIZATION→RCE · 31x across ecosystem
Root cause : The `kobako` gem allowed guest code to invoke arbitrary methods on host objects via `public_send`. This included Ruby's reflection and metaprogramming methods like `send`, `public_send`, `instance_eval`, `method`, `tap`, and `instance_variable_get`. An attacker could chain these methods to bypass the sandbox and execute arbitrary code on the host system.
Impact : An attacker could achieve Remote Code Execution (RCE) on the host system, completely escaping the intended sandbox environment. This allows full control over the host machine.
Diff
--- a/lib/kobako/transport/dispatcher.rb
+++ b/lib/kobako/transport/dispatcher.rb
@@ -109,14 +120,33 @@ def encode_caught_error(error)
# so the same call site handles both cases without an explicit
# conditional.
def invoke(target, method, args, kwargs, yielder = nil)
+ name = method.to_sym
+ reject_meta_method!(target, name)
block = yielder&.to_proc
if kwargs.empty?
- target.public_send(method.to_sym, *args, &block)
+ target.public_send(name, *args, &block)
else
- target.public_send(method.to_sym, *args, **kwargs, &block)
+ target.public_send(name, *args, **kwargs, &block)
end
end
# Guard the +public_send+ below against ambient reflection methods
# (see {META_OWNERS}).
def reject_meta_method!(target, name)
owner = target.public_method(name).owner
return unless META_OWNERS.include?(owner)
raise UndefinedTargetError, "method #{name.inspect} is not a Service method"
rescue NameError
return if target.respond_to?(name)
raise UndefinedTargetError, "no public method #{name.inspect} on target"
end</pre>
Fix : The patch introduces a `META_OWNERS` constant listing modules that contain dangerous reflection methods. A new `reject_meta_method!` guard is added to the `invoke` method, which checks if the method being called belongs to one of these meta modules. If so, the call is rejected, preventing guest code from invoking these sensitive methods.
CRITICAL 10.0 · 2026-07-31 · JavaScript
@nocobase/plugin-notification-in-app-message · Pattern: UNCLASSIFIED · 878x across ecosystem
Root cause :
Impact :
Fix :
CRITICAL 10.0 · 2026-07-30 · Python
flyto-core · Pattern: PATH_TRAVERSAL→FILE_WRITE · 67x across ecosystem
Root cause : The application allowed an attacker to control both the target file path and its base directory when writing files. The existing path traversal check was ineffective because it validated the output path against a caller-supplied output directory, which an attacker could manipulate to bypass the check and write files outside the intended sandbox.
Impact : An attacker could write arbitrary files to any location on the file system where the application has write permissions, potentially leading to remote code execution, data corruption, or denial of service.
Diff
- base_real = os.path.realpath(output_dir)
- target_real = os.path.realpath(output_path)
- if os.path.commonpath([base_real, target_real]) != base_real:
- raise Exception('Invalid file path')
+ try:
+ target_real = validate_path_with_env_config(output_path)
+ except PathTraversalError as e:
+ raise ModuleError(str(e), code="PATH_TRAVERSAL")Fix : The patch removes the ineffective local path traversal check and replaces it with a centralized `validate_path_with_env_config` utility function. This new function enforces that all file write operations are confined to a secure, operator-configured sandbox directory (`FLYTO_SANDBOX_DIR`), preventing path traversal attacks.
CRITICAL 10.0 · 2026-07-29 · Go
github.com/prebid/prebid-server · Pattern: SSRF→INTERNAL_ACCESS · 142x across ecosystem
Root cause : The application was vulnerable to Server-Side Request Forgery (SSRF) because it constructed outbound HTTP requests using user-controlled input (e.g., 'endpoint', 'host', 'account') without sufficient validation. An attacker could manipulate these parameters to make the server send requests to arbitrary internal or external hosts.
Impact : An attacker could force the Prebid Server to make requests to internal network resources, potentially extracting sensitive data from the host environment (e.g., cloud metadata, internal services) or bypassing firewall rules.
Diff
--- /dev/null
+++ b/util/urlutil/security.go
@@ -0,0 +1,12 @@
+package urlutil
+
+import "regexp"
+
+var safeHostPattern = regexp.MustCompile(`^[a-zA-Z0-9.-]+(:[0-9]+)?$`)
+
+// IsSafeHost returns true for bare hostnames with an optional port.
+// It intentionally rejects URL control characters such as '/', '?', '#', and '@'
+// so user-supplied host values cannot rewrite the outbound request URL.
+func IsSafeHost(host string) bool {
+ return safeHostPattern.MatchString(host)
+}
--- adapters/acuityads/acuityads.go
+++ b/adapters/acuityads/acuityads.go
@@ -107,6 +108,9 @@ func (a *AcuityAdsAdapter) buildEndpointURL(params *openrtb_ext.ExtAcuityAds) (string, error) {
}Fix : The patch introduces a new utility function, `urlutil.IsSafeHost`, which validates user-supplied hostnames to ensure they do not contain URL control characters. This function is then applied to all user-controlled parameters that are used in constructing outbound request URLs, preventing attackers from injecting malicious URLs or paths.
CRITICAL 10.0 · 2026-07-24 · PHP
pheditor/pheditor · Pattern: MISSING_AUTH→ENDPOINT · 82x across ecosystem
Root cause : The vulnerability existed because the application had a hardcoded default password 'admin' which, when set, triggered a forced password change flow. During this flow, the application did not verify the current password provided by the user against the actual stored password. Instead, it only checked if the submitted password was 'admin' (which was hardcoded into a hidden input field in the password change form), allowing an attacker to bypass authentication and set a new password without knowing the original one.
Impact : An attacker could completely bypass the authentication mechanism, gain administrative access to the Pheditor application, and potentially execute arbitrary code or modify files on the server, leading to full system compromise.
Diff
--- a/pheditor.php
+++ b/pheditor.php
@@ -152,7 +152,9 @@
if (empty(PASSWORD) === false && (isset($_SESSION['pheditor_admin'], $_SESSION['pheditor_password']) === false || $_SESSION['pheditor_admin'] !== true || $_SESSION['pheditor_password'] != PASSWORD)) {
if (isset($_POST['pheditor_password']) && empty($_POST['pheditor_password']) === false) {
if (PASSWORD == hash('sha512', 'admin')) {
$submitted_hash = hash('sha512', $_POST['pheditor_password']);
if (PASSWORD == hash('sha512', 'admin') && $submitted_hash === PASSWORD) {
if (isset($_POST['pheditor_new_password']) && isset($_POST['pheditor_confirm_password'])) {
if ($_POST['pheditor_new_password'] === 'admin') {
$error = 'Password cannot be admin';</pre>
Fix : The patch introduces a check to ensure that when the hardcoded 'admin' password triggers a forced password change, the submitted password hash also matches the actual stored password. This prevents an attacker from simply submitting 'admin' as the current password without knowing the real password, thereby enforcing proper authentication during the password change process.
CRITICAL 10.0 · 2026-07-24 · JavaScript
@prompty/core · Pattern: UNSANITIZED_INPUT→TEMPLATE · 28x across ecosystem
Root cause : The Nunjucks templating engine was used to render user-controlled templates and inputs without sufficient sanitization or sandboxing. This allowed attackers to access and invoke dangerous properties and methods (like `__proto__`, `constructor`, `prototype`) through template expressions, leading to arbitrary code execution.
Impact : An attacker could achieve remote code execution on the server by injecting malicious template code, potentially compromising the entire system.
Diff
--- a/runtime/typescript/packages/core/src/renderers/nunjucks.ts
+++ b/runtime/typescript/packages/core/src/renderers/nunjucks.ts
@@ -13,11 +13,91 @@ import type { Prompty } from "../model/agent/prompty.js";
import type { Renderer } from "../core/interfaces.js";
import { prepareRenderInputs } from "./common.js";
+type NunjucksRuntime = {
memberLookup: (object: unknown, property: unknown) => unknown;
callWrap: (callable: unknown, name: string, context: unknown, args: unknown[]) => unknown;
+};
+const UNSAFE_PROPERTIES = new Set(["proto", "constructor", "prototype"]);
+
const env = new nunjucks.Environment(null, {
autoescape: false,
throwOnUndefined: false,
});
+function safeMemberLookup(object: unknown, property: unknown): unknown {
if (typeof property === "string" && UNSAFE_PROPERTIES.has(property)) {
throw new Error(Unsafe template member access: ${property});
}
if (
(typeof property !== "string" && typeof property !== "number") ||
object === null ||
typeof object !== "object"
) {
return undefined;
}
const descriptor = Object.getOwnPropertyDescriptor(object, property);
return descriptor !== undefined && "value" in descriptor ? descriptor.value : undefined;
+}
+function safeCallWrap(_callable: unknown, name: string, _context: unknown, _args: unknown[]): never {
throw new Error(Template function calls are not allowed: ${name});
+}
+function sanitizeValue(value: unknown, seen = new WeakMap<object, unknown>()): unknown {
if (value === null || typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
return value;
}
if (typeof value !== "object") {
return undefined;
}
const existing = seen.get(value);
if (existing !== undefined) {
return existing;
}
if (Array.isArray(value)) {
const result: unknown[] = [];
seen.set(value, result);
for (const item of value) {
result.push(sanitizeValue(item, seen));
}
return result;
}
const result = Object.create(null) as Record<string, unknown>;
seen.set(value, result);
for (const [key, descriptor] of Object.entries(Object.getOwnPropertyDescriptors(value))) {
if (!UNSAFE_PROPERTIES.has(key) && "value" in descriptor) {
result[key] = sanitizeValue(descriptor.value, seen);
}
}
return result;
+}
+function sanitizeInputs(inputs: Record<string, unknown>): Record<string, unknown> {
return sanitizeValue(inputs) as Record<string, unknown>;
+}
+function renderSafely(template: string, inputs: Record<string, unknown>): string {
const runtime = nunjucks.runtime as unknown as NunjucksRuntime;
const memberLookup = runtime.memberLookup;
const callWrap = runtime.callWrap;
runtime.memberLookup = safeMemberLookup;
runtime.callWrap = safeCallWrap;
try {
return env.renderString(template, inputs);
} finally {
runtime.memberLookup = memberLookup;
runtime.callWrap = callWrap;
}
+}
export class NunjucksRenderer implements Renderer {
async render(
agent: Prompty,
template: string,
inputs: Record<string, unknown>,
): Promise<string> {
const [modified] = prepareRenderInputs(agent, inputs);
return env.renderString(template, modified);
return renderSafely(template, sanitizeInputs(modified));
}
}Fix : The patch introduces `safeMemberLookup` and `safeCallWrap` functions to restrict access to unsafe properties and prevent function calls within templates. It also includes `sanitizeValue` and `sanitizeInputs` to recursively clean input data by creating a new object with only safe properties, effectively sandboxing the template rendering environment.
CRITICAL 10.0 · 2026-07-08 · Go
github.com/nuclio/nuclio · Pattern: UNCLASSIFIED · 878x across ecosystem
Root cause :
Impact :
Fix :
CRITICAL 10.0 · 2026-06-26 · Python
mcp-pinot-server · Pattern: UNSANITIZED_INPUT→SQL · 41x across ecosystem
Root cause : The application allowed unauthenticated users to execute arbitrary SQL queries against the Pinot database. The `oauth_enabled=False` default configuration combined with binding to `0.0.0.0` made the Pinot server publicly accessible without authentication, enabling attackers to send malicious SQL.
Impact : An attacker could execute arbitrary SQL commands, potentially leading to data exfiltration, modification, or deletion, and could also invoke administrative functions or other tools if the underlying database permissions allowed.
Diff
--- a/mcp_pinot/pinot_client.py
+++ b/mcp_pinot/pinot_client.py
@@ -46,6 +49,289 @@ class PinotEndpoints:
TABLE_CONFIG = "tableConfigs/{}"
+_READ_QUERY_START_KEYWORDS = {"SELECT", "WITH"}
+_PROHIBITED_READ_QUERY_KEYWORDS = {
"ALTER",
"CALL",
"COPY",
"CREATE",
"DELETE",
"DESCRIBE",
"DROP",
"EXEC",
"EXECUTE",
"EXPLAIN",
"EXPORT",
"GRANT",
"IMPORT",
"INSERT",
"INTO",
"LOAD",
"MERGE",
"REFRESH",
"REPLACE",
"RESET",
"REVOKE",
"SET",
"SHOW",
"TRUNCATE",
"UPDATE",
"UPSERT",
"USE",
+}
+def _strip_sql_comments(query: str) -> str:
"""Remove SQL comments while preserving quoted strings and identifiers."""
result: list[str] = []
quote: str | None = None
i = 0Fix : The patch introduces extensive SQL parsing and validation logic. It defines a set of allowed starting keywords for read queries and a comprehensive list of prohibited keywords for write/administrative operations. It also includes functions to strip comments and split statements, ensuring that only safe read queries are processed.
CRITICAL 10.0 · 2026-06-23 · Go
gogs.io/gogs · Pattern: UNCLASSIFIED · 878x across ecosystem
Root cause :
Impact :
Fix :
CRITICAL 10.0 · 2026-05-29 · JavaScript
vm2 · Pattern: UNCLASSIFIED · 878x across ecosystem
Root cause :
Impact :
Fix :
CRITICAL 10.0 · 2026-05-29 · JavaScript
vm2 · Pattern: UNCLASSIFIED · 878x across ecosystem
Root cause :
Impact :
Fix :
CRITICAL 10.0 · 2026-05-29 · JavaScript
vm2 · Pattern: UNCLASSIFIED · 878x across ecosystem
Root cause : The vm2 sandbox failed to properly denylist certain Node.js built-in modules and their subpaths, specifically 'process' and 'inspector/promises'. This allowed an attacker to bypass the sandbox's security mechanisms by requiring these modules, which provide direct access to host system capabilities.
Impact : An attacker could execute arbitrary code on the host system, completely escaping the sandbox environment and gaining full control over the application running the vm2 instance.
Diff
--- a/lib/builtin.js
+++ b/lib/builtin.js
@@ -69,6 +87,7 @@ const DANGEROUS_BUILTINS = new Set([
'vm',
'repl',
'inspector',
+ 'process',
// Host-process abort DoS: `trace_events.createTracing({categories: [...]})`
// asserts `args[0]->IsArray()` in C++; the array crosses the bridge as a
// Proxy, which fails the assertion and aborts the entire host process.
@@ -83,8 +102,21 @@ const DANGEROUS_BUILTINS = new Set([
'wasi'
]);
+// SECURITY (GHSA-rp36-8xq3-r6c4): Family-prefix denylist check. inspector and
+// inspector/promises must share fate; same for any future subpath under a
+// dangerous family. Also strips the node: URL-style prefix so
+// node:process and node:inspector/promises cannot bypass via spelling.
+function isDangerousBuiltin(key) {
if (typeof key !== 'string') return false;
if (key.startsWith('node:')) key = key.slice(5);
if (DANGEROUS_BUILTINS.has(key)) return true;
const slash = key.indexOf('/');
if (slash > 0 && DANGEROUS_BUILTINS.has(key.slice(0, slash))) return true;
return false;
+}
const BUILTIN_MODULES = (nmod.builtinModules || Object.getOwnPropertyNames(process.binding('natives')))
.filter(s=>!s.startsWith('internal/') && !DANGEROUS_BUILTINS.has(s));
.filter(s=>!s.startsWith('internal/') && !isDangerousBuiltin(s));Fix : The patch expands the denylist of dangerous built-in modules to include 'process' and implements a family-based matching function, `isDangerousBuiltin`, to block subpaths like 'inspector/promises'. It also strips the 'node:' prefix from module names to prevent bypasses via alternative spellings, ensuring that these critical modules are never accessible from within the sandbox.
CRITICAL 10.0 · 2026-05-29 · JavaScript
vm2 · Pattern: UNCLASSIFIED · 878x across ecosystem
Root cause :
Impact :
Fix :
CRITICAL 10.0 · 2026-05-11 · JavaScript
@nyariv/sandboxjs · Pattern: TYPE_CONFUSION→BYPASS · 17x across ecosystem
Root cause : The sandbox environment in SandboxJS failed to restrict access to sensitive JavaScript properties like 'caller', 'callee', and 'arguments'. These properties, when accessed from within a sandboxed function, could leak references to the internal execution context or global objects, effectively allowing an attacker to break out of the sandbox.
Impact : An attacker could escape the JavaScript sandbox, gaining access to the host environment and potentially executing arbitrary code or accessing sensitive resources outside the intended sandboxed scope.
Diff
--- a/src/executor/ops/prop.ts
+++ b/src/executor/ops/prop.ts
@@ -93,12 +93,15 @@ addOps<unknown, PropertyKey>(LispType.Prop, ({ done, a, b, obj, context, scope,
}
}
const val = a[b as keyof typeof a] as unknown;
if (typeof a === 'function') {
if (b === 'prototype' && !context.ctx.sandboxedFunctions.has(a)) {
throw new SandboxAccessError(Access to prototype of global object is not permitted);
}
if (['caller', 'callee', 'arguments'].includes(b as string)) {
throw new SandboxAccessError(`Access to '${b as string}' property is not permitted`);
}
}
const val = a[b as keyof typeof a] as unknown;
if (b === 'proto' && !context.ctx.sandboxedFunctions.has(val?.constructor as any)) {
throw new SandboxAccessError(Access to prototype of global object is not permitted);Fix : The patch explicitly disallows access to the 'caller', 'callee', and 'arguments' properties when a property is accessed on a function within the sandboxed environment. It introduces a check that throws a SandboxAccessError if an attempt is made to access these forbidden properties.
CRITICAL 10.0 · 2026-05-08 · Go
github.com/free5gc/smf · Pattern: MISSING_AUTH→ENDPOINT · 82x across ecosystem
Root cause : The free5GC SMF's UPI management interface was not protected by any authentication middleware. This allowed unauthenticated requests to reach the underlying handlers for reading and writing topology information.
Impact : An unauthenticated attacker could perform read and write operations on the SMF's UPI topology, potentially disrupting network operations or gaining unauthorized access to sensitive network configuration.
Diff
--- a/internal/sbi/server.go
+++ b/internal/sbi/server.go
@@ -74,6 +74,10 @@ func newRouter(s *Server) *gin.Engine {
upiGroup := router.Group(factory.UpiUriPrefix)
upiAuthCheck := util_oauth.NewRouterAuthorizationCheck(models.ServiceName_NSMF_OAM)
upiGroup.Use(func(c *gin.Context) {
upiAuthCheck.Check(c, smf_context.GetSelf())
})
upiRoutes := s.getUPIRoutes()
applyRoutes(upiGroup, upiRoutes)Fix : The patch introduces an authentication check for the UPI management interface. It adds a new router authorization check using `util_oauth.NewRouterAuthorizationCheck` and applies it as middleware to the `upiGroup` router, ensuring all requests to this interface are authenticated.
CRITICAL 10.0 · 2026-05-07 · Go
github.com/enchant97/note-mark/backend · Pattern: INSECURE_DEFAULT→CONFIG · 42x across ecosystem
Root cause : The application allowed a JWT secret to be configured without a minimum length validation. This meant that a short, easily guessable secret could be used, making JWT tokens vulnerable to brute-force attacks.
Impact : An attacker could brute-force the weak JWT secret, forge valid authentication tokens, and achieve full account takeover for any user, including administrative accounts.
Diff
- JWTSecret Base64Decoded `env:"JWT_SECRET,notEmpty"`
+ JWTSecret Base64Decoded `env:"JWT_SECRET,notEmpty" validate:"gte=32"`Fix : The patch adds a validation rule to the `JWTSecret` configuration field, ensuring that the secret must have a minimum length of 32 characters. This significantly increases the entropy and makes brute-forcing infeasible.
CRITICAL 10.0 · 2026-04-22 · Go
github.com/jkroepke/openvpn-auth-oauth2 · Pattern: MISSING_AUTH→ENDPOINT · 82x across ecosystem
Root cause : The application incorrectly returned 'FUNC_SUCCESS' even when a client's authentication was explicitly denied or an error occurred during the authentication process. This misinterpretation of the return code by OpenVPN led to clients being granted access despite failing authentication.
Impact : An attacker could gain unauthorized access to the VPN without providing valid credentials, effectively bypassing the entire authentication mechanism.
Diff
--- a/lib/openvpn-auth-oauth2/openvpn/handle.go
+++ b/lib/openvpn-auth-oauth2/openvpn/handle.go
@@ -144,7 +144,7 @@ func (p *PluginHandle) handleAuthUserPassVerify(clientEnvList **c.Char, perClien
slog.Any("err", err),
)
- return c.OpenVPNPluginFuncSuccess
+ return c.OpenVPNPluginFuncError
case management.ClientAuthPending:
pendingRespCh, err := p.managementClient.RegisterPendingPoller(currentClientID)Fix : The patch changes the return value from 'c.OpenVPNPluginFuncSuccess' to 'c.OpenVPNPluginFuncError' when a client's authentication is denied or an error occurs during the process. This ensures that OpenVPN correctly interprets the authentication failure and denies access.
CRITICAL 10.0 · 2026-04-14 · PHP
wwbn/avideo · Pattern: UNSANITIZED_INPUT→XSS · 128x across ecosystem
Root cause : The application's WebSocket broadcast relay allowed unauthenticated users to inject arbitrary JavaScript code into messages. Specifically, the 'autoEvalCodeOnHTML' field and the 'callback' field in WebSocket messages were not properly sanitized or validated before being relayed to other clients, which would then execute the injected code via client-side eval() sinks.
Impact : An attacker could achieve unauthenticated cross-user JavaScript execution, leading to session hijacking, data theft, defacement, or other malicious activities on the client-side for any user connected to the WebSocket.
Diff
- //_log_message("onMessage:msgObj: " . json_encode($json));
+ //_log_message("onMessage:msgObj: " . json_encode($json));
+ // Strip eval-able fields from browser/guest messages.
+ if (empty($msgObj->isCommandLineInterface) && ($msgObj->sentFrom ?? '') !== 'php') {
+ if (is_array($json['msg'] ?? null)) {
+ unset($json['msg']['autoEvalCodeOnHTML']);
+ }
+ if (isset($json['callback']) && !preg_match('/^[a-zA-Z_][a-zA-Z0-9_]*$/', (string)$json['callback'])) {
+ unset($json['callback']);
+ }
+ }
if (!empty($msgObj->send_to_uri_pattern)) {
$this->msgToSelfURI($json, $msgObj->send_to_uri_pattern);
} else if (!empty($json['resourceId'])) {Fix : The patch introduces input validation and sanitization for WebSocket messages. It specifically removes the 'autoEvalCodeOnHTML' field from messages originating from browsers or guests and ensures that the 'callback' field, if present, adheres to a strict alphanumeric and underscore pattern, effectively preventing arbitrary JavaScript injection.
CRITICAL 10.0 · 2026-04-10 · Go
github.com/daptin/daptin · Pattern: PATH_TRAVERSAL→FILE_WRITE · 67x across ecosystem
Root cause : The application allowed user-supplied filenames and archive entry names to be used directly in file system operations (e.g., `filepath.Join`, `os.OpenFile`, `os.MkdirAll`) without sufficient sanitization. This enabled attackers to manipulate file paths using `../` sequences or absolute paths.
Impact : An unauthenticated attacker could write arbitrary files to arbitrary locations on the server's file system, potentially leading to remote code execution, data corruption, or denial of service. In the case of Zip Slip, files within an uploaded archive could be extracted outside the intended directory.
Diff
--- a/server/asset_upload_handler.go
+++ b/server/asset_upload_handler.go
@@ -67,6 +67,13 @@ func AssetUploadHandler(cruds map[string]*resource.DbResource) func(c *gin.Conte
c.AbortWithError(400, errors.New("filename query parameter is required"))
return
}
+ // Strip path traversal from filename
+ if fileName != "" {
+ fileName = filepath.Clean(fileName)
+ for strings.HasPrefix(fileName, "..") {
+ fileName = strings.TrimPrefix(strings.TrimPrefix(fileName, ".."), string(filepath.Separator))
+ }
+ }
// Validate table and column
dbResource, ok := cruds[typeName]
if !ok || dbResource == nil {Fix : The patch introduces robust path sanitization by using `filepath.Clean` and then iteratively stripping any leading `..` components from user-supplied filenames and archive entry names. This ensures that all file system operations are constrained to the intended directories.
CRITICAL 10.0 · 2026-04-10 · JavaScript
axios · Pattern: UNSANITIZED_INPUT→HEADER · 23x across ecosystem
Root cause : The Axios library did not properly sanitize header values, allowing newline characters (CRLF) to be injected. This meant that an attacker could append arbitrary headers or even inject a new HTTP request body by including these characters in a user-controlled header value.
Impact : An attacker could inject arbitrary HTTP headers, potentially leading to SSRF (Server-Side Request Forgery) against cloud metadata endpoints or other internal services, and could also manipulate the request body.
Diff
--- a/lib/core/AxiosHeaders.js
+++ b/lib/core/AxiosHeaders.js
@@ -5,18 +5,49 @@ import parseHeaders from '../helpers/parseHeaders.js';
const $internals = Symbol('internals');
+const isValidHeaderValue = (value) => !/[
]/.test(value);
+
+function assertValidHeaderValue(value, header) {
if (value === false || value == null) {
return;
}
if (utils.isArray(value)) {
value.forEach((v) => assertValidHeaderValue(v, header));
return;
}
if (!isValidHeaderValue(String(value))) {
throw new Error(Invalid character in header content ["${header}"]);
}
+}
function normalizeValue(value) {
if (value === false || value == null) {
return value;
}
return utils.isArray(value)
? value.map(normalizeValue)
: String(value).replace(/[
]+$/, '');
return utils.isArray(value) ? value.map(normalizeValue) : stripTrailingCRLF(String(value));
}
function parseTokens(str) {
@@ -98,6 +129,7 @@ class AxiosHeaders {
_rewrite === true ||
(_rewrite === undefined && self[key] !== false)
) {
assertValidHeaderValue(_value, _header);
self[key || _header] = normalizeValue(_value);
}
}Fix : The patch introduces a `isValidHeaderValue` function to explicitly check for and disallow newline characters (CRLF) in header values. It also adds an `assertValidHeaderValue` function to enforce this validation before header values are set, preventing header injection.
CRITICAL 9.9 · 2026-10-07 · Python
lfx · Pattern: UNCLASSIFIED · 878x across ecosystem
Root cause :
Impact :
Fix :
CRITICAL 9.9 · 2026-10-06 · Python
langflow · Pattern: MISSING_AUTHZ→RESOURCE · 127x across ecosystem
Root cause : The Langflow application's PythonREPLComponent and PythonREPLToolComponent allowed authenticated users to execute arbitrary Python code without proper authorization checks. Although there was a `allow_custom_components` setting, it was not enforced for these specific components, enabling a bypass.
Impact : An authenticated attacker could execute arbitrary Python code on the server, leading to full system compromise (Remote Code Execution) and potential privilege escalation.
Diff
--- a/src/lfx/src/lfx/components/tools/python_repl.py
+++ b/src/lfx/src/lfx/components/tools/python_repl.py
@@ -78,6 +78,9 @@ def get_globals(self, global_imports: str | list[str]) -> dict:
def build_tool(self) -> Tool:
def run_python_code(code: str) -> str:
try:
+ # Refuse to run user code when allow_custom_components is disabled
+ # (GHSA-8qpj-27x8-pwpq).
+ ensure_code_execution_enabled()
# Validate the exact (sanitized) code that will run, rejecting inlineFix : The patch introduces a new function, `ensure_code_execution_enabled()`, which is called before any user-supplied Python code is executed in the PythonREPLComponent and PythonREPLToolComponent. This function checks the `allow_custom_components` setting and raises an error if code execution is disabled, thereby enforcing the security policy.
CRITICAL 9.9 · 2026-10-01 · JavaScript
vm2 · Pattern: DESERIALIZATION→RCE · 31x across ecosystem
Root cause : The vm2 sandbox allowed access to certain Node.js built-in modules (like `crypto`) without properly sanitizing or restricting dangerous functions. Specifically, `crypto.setEngine()` could be called by sandboxed code, which then instructed OpenSSL to dynamically load a native library from a specified path into the host process. The constructor of this native library would execute arbitrary code before OpenSSL even validated it as a legitimate engine.
Impact : An attacker could achieve arbitrary native code execution on the host system, effectively escaping the vm2 sandbox and gaining full control over the host process.
Diff
--- a/lib/builtin.js
+++ b/lib/builtin.js
@@ -210,6 +210,163 @@ if (EventEmitter.EventEmitterAsyncResource) {
EventEmitterReferencingAsyncResourceClass = EventEmitterReferencingAsyncResource;
}
+// SECURITY (GHSA-46pr-c5wc-xffx): Some builtins are safe to expose EXCEPT for a
+// handful of members that reach host-process authority the vm.readonly() wrap
+// cannot contain. readonly() blocks property assignment through the sandbox
+// proxy, but it forwards every call to the host member with full host
+// authority -- so a callable that loads native code, mutates a process-wide
+// security setting, or hands back a shared host singleton is a sandbox-escape
+// primitive even behind the read-only proxy. Rather than deny these
+// otherwise-useful modules wholesale (hashing/signing is a legitimate sandbox
+// use of crypto), expose a sanitized shallow copy with just the dangerous
+// member neutralized.
+//
+// - crypto.setEngine(path[, flags]) : hands path to OpenSSL's ENGINE loader,
+// which asks the OS dynamic loader to load the named shared library. The
+// library's constructor runs as arbitrary native code BEFORE OpenSSL decides
+// whether the file is a usable engine -- so even the expected
+// ERR_CRYPTO_ENGINE_UNKNOWN rejection happens only after host-native code has
+// already executed. A sandbox with only crypto allowed and a native file in
+// its own package directory therefore has a native-RCE primitive.
+//
+// The stub throws instead of forwarding to host OpenSSL, so no library is ever
+// loaded. Matching strips the node: prefix so node:crypto shares fate.
+function sanitizeCryptoModule(mod) {
const copy = Object.assign({}, mod);
copy.setEngine = function setEngine() {
throw new Error('crypto.setEngine is disabled in vm2 sandboxes: it asks OpenSSL to dynamically load a native library into the host process, executing arbitrary native code (GHSA-46pr-c5wc-xffx).');
};
return copy;
+}Fix : The patch introduces a `sanitizeCryptoModule` function that intercepts calls to `crypto.setEngine()`. Instead of forwarding the call to the host's OpenSSL, it now throws an error, preventing the dynamic loading of native libraries and thus neutralizing the sandbox escape vector.
CRITICAL 9.9 · 2026-10-01 · JavaScript
vm2 · Pattern: DESERIALIZATION→RCE · 31x across ecosystem
Root cause : The vm2 sandbox failed to properly restrict access to certain Node.js built-in modules, specifically `node:sqlite`. The `DatabaseSync` constructor in `node:sqlite` allowed the `allowExtension` option to be set, which, if enabled, permits loading native SQLite extensions. This capability was not adequately neutralized by the sandbox's read-only proxy, enabling a sandboxed plugin to execute arbitrary native code in the host process.
Impact : An attacker could execute arbitrary native code on the host system, effectively escaping the sandbox and achieving full remote code execution (RCE) with the privileges of the Node.js process.
Diff
--- a/lib/builtin.js
+++ b/lib/builtin.js
@@ -210,6 +210,163 @@ if (EventEmitter.EventEmitterAsyncResource) {
+// SECURITY (GHSA-6w8r-xxw2-g3hx): node:sqlite's DatabaseSync can load a native
+// SQLite extension (loadExtension(path) / the loadExtension SQL function) —
+// arbitrary native code in the host process. Node gates this entirely on the
+// constructor's allowExtension option: with it off (the default), both
+// loadExtension() and enableLoadExtension() throw ERR_INVALID_STATE.
+// Wrap the DatabaseSync constructor so allowExtension is forced off, which
+// closes every extension-loading path while leaving normal SQL usable.
+function sanitizeSqliteModule(mod) {
const HostDatabaseSync = mod.DatabaseSync;
if (typeof HostDatabaseSync !== 'function') return mod;
const copy = Object.assign({}, mod);
class DatabaseSync extends HostDatabaseSync {
constructor(location, ...rest) {
// Preserve call arity (native DatabaseSync rejects an explicit
// `undefined` options arg). Force `allowExtension` off only when an
// options value is actually supplied; otherwise the native default
// (off) already applies. SECURITY (GHSA-6w8r-xxw2-g3hx follow-up): the
// native DatabaseSync also accepts a FUNCTION as its options argument
// (functions carry own properties), so `function o(){}; o.allowExtension
// = true` bypassed an `object`-only check. Treat functions as options
// too — Object.assign copies their own enumerable props and forces
// allowExtension off.
if (rest.length > 0 && rest[0] !== null &&
(typeof rest[0] === 'object' || typeof rest[0] === 'function')) {
rest[0] = Object.assign({}, rest[0], {allowExtension: false});
}
super(location, ...rest);
}
}
copy.DatabaseSync = DatabaseSync;
return copy;
+}
+// SECURITY (GHSA-98xx-8mx4-x7cm): tls.setDefaultCACertificates(list) replacesFix : The patch introduces a `sanitizeSqliteModule` function that wraps the `node:sqlite.DatabaseSync` constructor. This wrapper forces the `allowExtension` option to `false` when an options object is provided, preventing the loading of native SQLite extensions. This ensures that even if a sandboxed plugin attempts to enable extensions, the underlying host functionality will deny it.
CRITICAL 9.9 · 2026-10-01 · JavaScript
vm2 · Pattern: UNCLASSIFIED · 878x across ecosystem
Root cause :
Impact :
Fix :
CRITICAL 9.9 · 2026-10-01 · JavaScript
vm2 · Pattern: UNCLASSIFIED · 878x across ecosystem
Root cause : The vulnerability stemmed from an insufficiently strict regular expression used to validate allowed external package names. The regex allowed partial matches, meaning a malicious package name like 'evil-left-pad' could bypass the allowlist if 'left-pad' was permitted. Additionally, even with an anchored regex, path traversal sequences ('..') within subpaths of allowed packages were not explicitly forbidden, allowing an attacker to escape the intended package and load an arbitrary host package.
Impact : An attacker could bypass the `vm2` sandbox and execute arbitrary code in the host environment with the privileges of the Node.js process running the sandbox.
Diff
- this.externalCache = externals.map(pattern => new RegExp(makeExternalMatcherRegex(pattern)));
+ this.externalCache = externals.map(pattern => new RegExp('^(?:' + makeExternalMatcherRegex(pattern) + ')(?:[\\/].*)?$'));
+ if (x.split(/[\/]/).indexOf('..') !== -1) return undefined;Fix : The patch introduces two main fixes: first, it anchors the regular expression used for external package allowlisting to ensure it matches the entire package name, optionally followed by a subpath. Second, it explicitly checks for and rejects any package specifier containing '..' path segments before calling the custom resolver, preventing path traversal attacks.
CRITICAL 9.9 · 2026-10-01 · JavaScript
vm2 · Pattern: UNSANITIZED_INPUT→COMMAND · 111x across ecosystem
Root cause : The vm2 sandbox environment failed to properly restrict access to the 'node:test' built-in module. This module, when invoked with specific `execArgv` parameters, could spawn a separate Node.js process outside the sandbox, executing attacker-controlled code with full host privileges.
Impact : An attacker could achieve arbitrary code execution on the host system, completely escaping the vm2 sandbox and gaining full control over the environment.
Diff
--- a/lib/builtin.js
+++ b/lib/builtin.js
@@ -162,7 +162,20 @@ const DANGEROUS_BUILTINS = new Set([
// `os.platform()`, `os.EOL`, `os.constants`) can register a controlled
// wrapper under the same name via `mock` / `override`.
'os',
- 'dns'
+ 'dns',
+ 'test'
]);
// SECURITY (GHSA-rp36-8xq3-r6c4): Family-prefix denylist check. inspector and
@@ -171,7 +184,10 @@ const DANGEROUS_BUILTINS = new Set([
// node:process and node:inspector/promises cannot bypass via spelling.
function isDangerousBuiltin(key) {
if (typeof key !== 'string') return false;
if (key.startsWith('node:')) key = key.slice(5);
while (key.startsWith('node:')) key = key.slice(5);Fix : The patch adds 'test' to the `DANGEROUS_BUILTINS` denylist, preventing its use within the sandbox. It also enhances the `isDangerousBuiltin` function to strip all leading 'node:' prefixes from module names, preventing bypasses via double-prefixed spellings like 'node:node:test'.
CRITICAL 9.9 · 2026-09-23 · Ruby
openc3 · Pattern: MISSING_AUTHZ→RESOURCE · 127x across ecosystem
Root cause : The system allowed authenticated non-admin users to write to specific configuration overlay paths (targets_modified/TARGET/cmd_tlm/) which were later loaded and executed as code (via ERB rendering and GENERIC_*_CONVERSION evaluation) by PacketConfig. This bypasses intended authorization checks for code execution.
Impact : An authenticated attacker could inject and execute arbitrary code on the server, leading to full system compromise and potentially impacting the underlying infrastructure.
Diff
--- a/openc3-cosmos-cmd-tlm-api/app/controllers/storage_controller.rb
+++ b/openc3-cosmos-cmd-tlm-api/app/controllers/storage_controller.rb
@@ -429,8 +429,10 @@ def get_upload_presigned_request
end
end
Anywhere other than config/SCOPE/targets_modified or config/SCOPE/tmp requires admin
if !(params[:bucket] == 'OPENC3_CONFIG_BUCKET' && (key_split[1] == 'targets_modified' || key_split[1] == 'tmp'))
Non-admins may only write the user-writable overlay (config/SCOPE/targets_modified
or config/SCOPE/tmp), and never the cmd_tlm overlay, which PacketConfig ERB-renders
and whose GENERIC_*_CONVERSION blocks it evaluates as code. Everything else is admin.
unless non_admin_config_overlay_write?(params[:bucket], path)
return unless authorization('admin')Fix : The patch introduces a new authorization check, `non_admin_config_overlay_write?`, to explicitly prevent non-admin users from writing to the `cmd_tlm` overlay path within the `targets_modified` directory. Additionally, a new `original: true` parameter is added to the `TargetFile.body` method, ensuring that code execution paths only load files from the read-only plugin-installed `targets/` tree, ignoring user-writable overlays.
CRITICAL 9.9 · 2026-09-23 · Python
plone.app.portlets · Pattern: UNSANITIZED_INPUT→TEMPLATE · 28x across ecosystem
Root cause : The application allowed user-controlled input (template and macro names) to be directly used in a TALES (TAL Expression Syntax) path expression without sufficient validation. This enabled an attacker to inject TALES metacharacters, transforming a simple path traversal into an arbitrary TALES expression, which could then execute Python code.
Impact : An attacker could achieve arbitrary remote code execution on the server, leading to full compromise of the application and potentially the underlying system.
Diff
--- a/src/plone/app/portlets/portlets/classic.py
+++ b/src/plone/app/portlets/portlets/classic.py
@@ -13,6 +30,7 @@ class IClassicPortlet(IPortletDataProvider):
title=_("Template"),
description=_("The template containing the portlet."),
required=True,
+ constraint=_valid_name,
)
macro = schema.ASCIILine(
@@ -22,6 +40,7 @@ class IClassicPortlet(IPortletDataProvider):
),
default="portlet",
required=False,
constraint=_valid_name,
)
@@ -48,6 +67,20 @@ def use_macro(self):
return bool(self.data.macro)
def path_expression(self):
# Defense in depth: validate again at render time so assignments
# created programmatically (e.g. via GenericSetup import) that bypass
# the form field constraint are still rejected. Raises on illegal names.
_valid_name(self.data.template)
_valid_name(self.data.macro)
expr = "context/%s" % self.data.template
if self.use_macro():
expr += "/macros/%s" % self.data.macro</pre>
Fix : The patch introduces a strict regular expression validator for the 'template' and 'macro' fields. This validator ensures that only alphanumeric characters, underscores, at signs, periods, hyphens, and forward slashes are allowed, effectively preventing the injection of TALES metacharacters like ':' or '|'. The validation is applied both at the schema level and as a defense-in-depth measure at render time.
06:00 UTC Pull advisories (GitHub Advisory DB, GraphQL)
Filter: has linked patch commit, severity >= MEDIUM
↓
06:00:10 Fetch commit diff via GitHub API
Filter: exclude tests/docs/lockfiles, keep top 5 source files
↓
06:00:15 LLM analysis (Gemini 2.5 Flash)
Extract: vuln_type, root_cause, impact, fix_summary, key_diff
Map to closed taxonomy of 51 normalized pattern IDs
↓
06:00:20 Pattern matching against SQLite historical DB
Cross-language correlation, recurrence scoring
↓
06:00:25 Output: patches/*.md, README.md, docs/index.html
Single atomic commit per run
Three runs per day: 06:00, 14:00, 23:00 UTC. Render pipeline runs independently at 07:00, 15:00, 00:00 UTC.
Stack
| Component | Tech | Notes |
|---|---|---|
| Automation | GitHub Actions cron | Zero infra |
| Data source | GitHub Advisory DB | GraphQL, filtered on patch commits |
| LLM | Gemini 2.5 Flash | Free tier, JSON-only output |
| DB | SQLite rebuilt from JSONL | Git-friendly, versioned |
| Frontend | Static HTML | Client-side search, zero build step |
| Scripting | Python 3.11 | requests, jinja2, sqlite3 |
Stats
| Metric | Value |
|---|---|
| Total advisories | 2559 |
| Unique patterns | 51 |
| Pending | 86 |
| Last updated | 2026-10-12 |
christbowel.com