Automated Patch Intelligence for Security Engineers
CRITICAL 10.0 · 2026-07-24 · PHP
pheditor/pheditor · Pattern: MISSING_AUTH→ENDPOINT · 45x 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 · 5x 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 · 343x across ecosystem
Root cause :
Impact :
Fix :
CRITICAL 10.0 · 2026-06-26 · Python
mcp-pinot-server · Pattern: UNSANITIZED_INPUT→SQL · 22x 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 · 343x across ecosystem
Root cause :
Impact :
Fix :
CRITICAL 10.0 · 2026-05-29 · JavaScript
vm2 · Pattern: UNCLASSIFIED · 343x across ecosystem
Root cause :
Impact :
Fix :
CRITICAL 10.0 · 2026-05-29 · JavaScript
vm2 · Pattern: UNCLASSIFIED · 343x across ecosystem
Root cause :
Impact :
Fix :
CRITICAL 10.0 · 2026-05-29 · JavaScript
vm2 · Pattern: UNCLASSIFIED · 343x 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 · 343x across ecosystem
Root cause :
Impact :
Fix :
CRITICAL 10.0 · 2026-05-11 · JavaScript
@nyariv/sandboxjs · Pattern: TYPE_CONFUSION→BYPASS · 4x 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 · 45x 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 · 22x 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 · 45x 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 · 73x 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 · 35x 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 · 11x 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-07-24 · JavaScript
@better-auth/scim · Pattern: MISSING_AUTHZ→RESOURCE · 76x across ecosystem
Root cause : The vulnerability stemmed from the SCIM provider's update functionality not properly validating email uniqueness during user updates (PUT/PATCH operations). An attacker could change a user's email to one already registered by another user, leading to a collision. Additionally, the system did not properly handle user deactivation via the 'active' SCIM attribute, failing to revoke sessions or enforce the deactivation consistently.
Impact : An attacker could take over another user's account by reassigning their email address. They could also maintain access to a deactivated account if their sessions were not properly revoked, or bypass deactivation entirely if the 'admin' plugin was not present.
Diff
--- a/packages/scim/src/routes.ts
+++ b/packages/scim/src/routes.ts
@@ -850,19 +932,37 @@ export const updateSCIMUser = (authMiddleware: AuthMiddleware) =>
});
}
const email = getUserPrimaryEmail(
body.userName,
body.emails,
).toLowerCase();
const name = getUserFullName(email, body.name);
const emailChanged = email !== user.email;
if (emailChanged) {
await assertSCIMEmailAvailable(ctx, email, userId);
}
const userUpdate: Record<string, unknown> = {
email,
name,
updatedAt: new Date(),
};
if (emailChanged) {
// A reassigned email is unverified until the new address is confirmed.
userUpdate.emailVerified = false;
}
if (body.active !== undefined) {
userUpdate.banned = body.active === false;
}
const deactivating = resolveSCIMActiveDeactivation(ctx, userUpdate);
const [updatedUser, updatedAccount] =
await ctx.context.adapter.transaction<[User | null, Account | null]>(
async () => {
const email = getUserPrimaryEmail(body.userName, body.emails);
const name = getUserFullName(email, body.name);
const updatedUser = await ctx.context.internalAdapter.updateUser(
userId,
{
email,
name,
updatedAt: new Date(),
},
userUpdate,
);
const updatedAccount =
@@ -875,6 +975,10 @@ export const updateSCIMUser = (authMiddleware: AuthMiddleware) =>
},
);
if (deactivating) {
await ctx.context.internalAdapter.deleteUserSessions(userId);
}
const userResource = createUserResource(
ctx.context.baseURL,
updatedUser!,</pre>
Fix : The patch introduces `assertSCIMEmailAvailable` to enforce email uniqueness during user updates. It also adds `resolveSCIMActiveDeactivation` to correctly map SCIM `active` status to the internal `banned` field, revoke user sessions upon deactivation, and ensure the admin plugin is present for deactivation. The `deleteSCIMUser` function was also updated to only delete the global user if no other accounts are linked.
CRITICAL 9.9 · 2026-06-30 · Go
github.com/fission/fission · Pattern: UNCLASSIFIED · 343x across ecosystem
Root cause :
Impact :
Fix :
CRITICAL 9.9 · 2026-06-30 · Go
github.com/fission/fission · Pattern: PRIVILEGE_ESCALATION→ROLE · 32x across ecosystem
Root cause : The Fission platform allowed users to specify container configurations for environments (Runtime.Container and Builder.Container) that were not subject to the same security context validation as standard PodSpecs. This oversight meant that dangerous security settings like 'privileged=true' or 'allowPrivilegeEscalation=true' could be set in these specific container fields, bypassing existing security checks.
Impact : An attacker could create privileged pods within the Kubernetes cluster, effectively escaping the container sandbox and gaining root-level access to the host or other cluster resources, leading to full cluster compromise.
Diff
--- a/pkg/apis/core/v1/validation.go
+++ b/pkg/apis/core/v1/validation.go
errs = errors.Join(errs, ValidatePodSpecSafety("Environment.spec.runtime.podspec", e.Spec.Runtime.PodSpec))
errs = errors.Join(errs, ValidatePodSpecSafety("Environment.spec.builder.podspec", e.Spec.Builder.PodSpec))
+ errs = errors.Join(errs, ValidateContainerSafety("Environment.spec.runtime.container", e.Spec.Runtime.Container))
+ errs = errors.Join(errs, ValidateContainerSafety("Environment.spec.builder.container", e.Spec.Builder.Container))
return errsFix : The patch introduces a new `ValidateContainerSafety` function to explicitly check the security context of individual containers, specifically applying it to the previously unchecked `Runtime.Container` and `Builder.Container` fields in the Environment CRD. Additionally, a sanitization step is added during container merging to strip dangerous security context settings, providing a defense-in-depth measure even if admission webhooks are bypassed.
CRITICAL 9.9 · 2026-06-30 · Go
github.com/fission/fission · Pattern: UNCLASSIFIED · 343x across ecosystem
Root cause :
Impact :
Fix :
CRITICAL 9.9 · 2026-06-30 · Go
github.com/fission/fission · Pattern: UNCLASSIFIED · 343x across ecosystem
Root cause :
Impact :
Fix :
CRITICAL 9.9 · 2026-06-26 · JavaScript
@deepstream/server · Pattern: UNCLASSIFIED · 343x across ecosystem
Root cause :
Impact :
Fix :
CRITICAL 9.9 · 2026-06-23 · Go
gogs.io/gogs · Pattern: UNCLASSIFIED · 343x across ecosystem
Root cause :
Impact :
Fix :
CRITICAL 9.9 · 2026-06-22 · PHP
paymenter/paymenter · Pattern: UNCLASSIFIED · 343x across ecosystem
Root cause : The application allowed users to upload files via the EasyMDE editor in ticket creation and viewing forms. The `completeUpload` method in Livewire components directly stored these uploaded files without sufficient validation of their content or type, allowing an attacker to upload malicious executable files.
Impact : An attacker could upload a malicious file (e.g., a PHP script) to the server and then execute it, leading to full compromise of the server.
Diff
--- a/themes/default/views/components/easymde-editor.blade.php
+++ b/themes/default/views/components/easymde-editor.blade.php
@@ -8,7 +8,7 @@
element: document.getElementById('editor'),
spellChecker: false,
previewImagesInEditor: true,
- uploadImage: true,
+ uploadImage: false,
autoDownloadFontAwesome: false,
status: [{
className: 'upload-image',
@@ -45,11 +45,6 @@ className: 'upload-image',
name: 'ordered-list',
action: EasyMDE.toggleOrderedList,
}, '|',
- {
- name: 'upload-image',
- action: EasyMDE.drawUploadedImage,
- title: 'Upload Image',
- }, '|',
{
name: 'undo',
action: EasyMDE.undo,
@@ -59,13 +54,6 @@ className: 'upload-image',
},
],
imageUploadFunction: async (file, onSuccess, onError) => {
@this.upload('attachments', file, (url) => {
@this.completeUpload(url).then((url) => {
onSuccess(url);
});
});
},
});</pre>
Fix : The patch removes the file upload functionality from the EasyMDE editor in ticket forms by disabling the `uploadImage` option and removing the associated `imageUploadFunction`. It also removes the `WithFileUploads` trait and related attachment handling logic from the Livewire components, effectively preventing any file uploads through these interfaces.
CRITICAL 9.9 · 2026-06-09 · PHP
pheditor/pheditor · Pattern: UNSANITIZED_INPUT→COMMAND · 56x across ecosystem
Root cause : The application was directly embedding user-supplied input from the 'dir' parameter into a shell command without proper sanitization. This allowed an attacker to inject arbitrary shell commands by manipulating the 'dir' value.
Impact : An attacker could execute arbitrary operating system commands on the server, leading to full system compromise, data exfiltration, or denial of service.
Diff
- $output = shell_exec((empty($dir) ? null : 'cd ' . $dir . ' && ') . $command . ' && echo \ ; pwd');
+ $output = shell_exec((empty($dir) ? null : 'cd ' . escapeshellarg($dir) . ' && ') . $command . ' && echo \ ; pwd');Fix : The patch addresses the vulnerability by wrapping the user-supplied 'dir' parameter with `escapeshellarg()` before it is used in the `shell_exec()` function. This ensures that any special characters in the 'dir' value are properly escaped, preventing command injection.
CRITICAL 9.9 · 2026-06-08 · Go
github.com/juev/nebula-mesh · Pattern: PRIVILEGE_ESCALATION→ROLE · 32x across ecosystem
Root cause : The application used a cached context value for `actorIsAdmin` checks, which meant that if an operator's role was downgraded from 'admin' to a regular user, their active session would still incorrectly reflect them as an administrator. This allowed them to bypass authorization checks on various API endpoints.
Impact : An attacker could maintain administrative privileges even after their role was revoked, enabling them to perform actions such as managing other operators, accessing audit logs, listing all CAs, and other sensitive operations that should be restricted to active administrators.
Diff
--- a/internal/api/authz.go
+++ b/internal/api/authz.go
@@ -8,10 +8,29 @@ import (
"github.com/juev/nebula-mesh/internal/store"
)
+// isActiveAdmin re-fetches the captured-ctx actor and reports whether
+// they are still an active admin.
+func (s *Server) isActiveAdmin(ctx context.Context) bool {
captured := ActorOf(ctx)
if captured == nil {
return false
}
fresh, err := s.store.GetOperator(ctx, captured.ID)
if err != nil {
if !errors.Is(err, store.ErrNotFound) {
s.logger.Error("isActiveAdmin: store lookup", "operator", captured.ID, "error", err)
}
return false
}
return fresh.Status == models.OperatorStatusActive && fresh.Role == "admin"
+}
// actorOwnsCA returns true if the actor in ctx is admin, or owns the CA with caID.
// Returns (false, nil) for empty caID or ErrNotFound. Errors only for unexpected DB errors.
func (s *Server) actorOwnsCA(ctx context.Context, caID string) (bool, error) {
if actorIsAdmin(ctx) {
if s.isActiveAdmin(ctx) {
return true, nil
}
if caID == "",Fix : A new function `isActiveAdmin` was introduced to re-fetch the operator's status and role directly from the database for each authorization check. All calls to the old `actorIsAdmin` function were replaced with `s.isActiveAdmin(ctx)` to ensure that administrative checks are always based on the most current operator status.
CRITICAL 9.9 · 2026-05-05 · Python
firefighter-incident · Pattern: SSRF→CLOUD_METADATA · 1x across ecosystem
Root cause : The application's `jira_bot` endpoint allowed unauthenticated users to provide arbitrary URLs for attachments. These URLs were then fetched by the server without proper validation, enabling an attacker to direct the server to make requests to internal network resources or cloud metadata endpoints.
Impact : An attacker could perform Server-Side Request Forgery (SSRF) attacks, leading to the theft of IAM credentials or access to other sensitive internal services and data.
Diff
--- a/src/firefighter/raid/serializers.py
+++ b/src/firefighter/raid/serializers.py
@@ -56,6 +59,58 @@
logger = logging.getLogger(__name__)
+ATTACHMENT_MAX_COUNT = 10
+ATTACHMENT_URL_MAX_LENGTH = 2048
+ATTACHMENT_ALLOWED_SCHEMES = frozenset({"http", "https"})
+
+
+def parse_attachment_urls(raw: str | None) -> list[str]:
"""Normalise the attachments payload sent by Landbot into a list of URLs.
Landbot historically sends a Python-stringified list (e.g. "['https://a', 'https://b']")
rather than a JSON array. This helper tolerates that legacy format along with
a plain comma-separated string or a single URL.
"""
if not raw:
return []
stripped = raw.replace("[", "").replace("]", "").replace("'", "").replace('"', "")
return [item.strip() for item in stripped.split(",") if item.strip()]
+def _validate_attachment_url(url: str) -> None:
if len(url) > ATTACHMENT_URL_MAX_LENGTH:
msg = f"Attachment URL exceeds {ATTACHMENT_URL_MAX_LENGTH} characters."
raise serializers.ValidationError(msg)
parsed = urlparse(url)
if parsed.scheme not in ATTACHMENT_ALLOWED_SCHEMES:
msg = f"Attachment URL scheme '{parsed.scheme}' is not allowed."
raise serializers.ValidationError(msg)
host = parsed.hostname
if not host:
raise serializers.ValidationError("Attachment URL is missing a host.")
try:
addr_infos = socket.getaddrinfo(host, None)
except socket.gaierror as err:
msg = f"Attachment URL host '{host}' could not be resolved."
raise serializers.ValidationError(msg) from err
SSRF guard: reject any host resolving to a non-routable address so the
fetch in add_attachments_to_issue can never reach internal services
(cloud metadata endpoint, RFC1918 networks, loopback).
for info in addr_infos:
ip = ipaddress.ip_address(info[4][0])
if (
ip.is_private
or ip.is_loopback
or ip.is_link_local
or ip.is_reserved
or ip.is_multicast
or ip.is_unspecified
):
raise serializers.ValidationError(
"Attachment URL host resolves to a private, loopback or link-local address."
)
class IgnoreEmptyStringListField(serializers.ListField):
def to_internal_value(self, data: list[Any] | Any) -> list[str]:
# Check if data is a listFix : The patch introduces authentication for the `jira_bot` endpoint, requiring a bearer token. Additionally, it implements robust URL validation for attachments, including scheme checks, host resolution, and a critical SSRF guard that rejects URLs resolving to private, loopback, link-local, reserved, multicast, or unspecified IP addresses.
CRITICAL 9.8 · 2026-07-28 · JavaScript
@hypequery/clickhouse · Pattern: UNSANITIZED_INPUT→SQL · 22x across ecosystem
Root cause : The vulnerability existed because the `escapeValue` function, which is responsible for sanitizing string inputs before they are used in SQL queries, did not properly escape backslash characters. While it correctly handled single quotes by doubling them, an attacker could use backslashes to bypass this escaping mechanism and inject arbitrary SQL.
Impact : An attacker could inject arbitrary SQL commands into queries, potentially leading to unauthorized data access, modification, or deletion, and even remote code execution on the underlying database server.
Diff
- return `'${value.replace(/'/g, "''")}'`;
+ const escaped = value.replace(/\\/g, '\\\\').replace(/'/g, "''");
+ return `'${escaped}'`;Fix : The patch modifies the `escapeValue` function to correctly handle backslash characters in string inputs. It now replaces each backslash with a double backslash (`\\`) before replacing single quotes, ensuring that backslashes cannot be used to escape the single quote delimiter.
CRITICAL 9.8 · 2026-07-24 · JavaScript
velocityjs · Pattern: PROTOTYPE_POLLUTION→OVERRIDE · 17x across ecosystem
Root cause : The vulnerability stemmed from insufficient prototype chain protection in the Velocity.js template engine. An attacker could craft a template that, when evaluated, would traverse the prototype chain using keys like 'constructor' and 'prototype' to access and manipulate sensitive JavaScript built-in objects, specifically the Function constructor. This allowed for arbitrary code execution.
Impact : An attacker could achieve arbitrary remote code execution within the context of the application running the Velocity.js template engine, leading to full system compromise or data exfiltration.
Diff
--- a/src/compile/references.ts
+++ b/src/compile/references.ts
@@ -31,12 +32,12 @@ export class References extends Compile {
const isSilent = this.silence || ast.leader === '$!';
const isFunction = ast.args !== undefined;
const context = this.context;
- let ret = context[ast.id];
+ let ret = this.isBlockedPathKey(context, ast.id) ? undefined : context[ast.id];
const local = this.getLocal(ast);
const text = getRefText(ast);
if (text in context) {
if (hasOwnProperty(context, text)) {
return ast.prue && escape ? convert(context[text]) : context[text];
}Fix : The patch introduces a new `prototype-guard.ts` module with functions to explicitly block access to dangerous prototype chain keys like `__proto__`, `constructor`, and `prototype` when they are not own properties or when accessed on a function's prototype. These new guard functions are integrated into the `set.ts` and `references.ts` compilation logic to prevent malicious prototype chain traversal during template evaluation.
CRITICAL 9.8 · 2026-07-24 · Java
org.openidentityplatform.openam:openam-core · Pattern: DESERIALIZATION→RCE · 15x across ecosystem
Root cause : The application allowed unauthenticated attackers to control the class name passed to `Class.forName` and subsequently `newInstance()` without proper validation. Additionally, a separate deserialization vulnerability existed where an encrypted but attacker-controlled serialized Java object (Subject) could be deserialized without a class allowlist, leading to gadget-chain execution.
Impact : An unauthenticated attacker could achieve remote code execution on the server by specifying a malicious class name or by crafting a malicious serialized object, leading to full compromise of the system.
Diff
--- a/openam-core/src/main/java/com/sun/identity/authentication/share/AuthXMLUtils.java
+++ b/openam-core/src/main/java/com/sun/identity/authentication/share/AuthXMLUtils.java
@@ -1609,7 +1611,19 @@ static DSAMECallbackInterface createCustomCallback(
if (callback == null) {
if ((className != null) && (className.length() != 0)) {
Class xmlClass = Class.forName(className);
Class xmlClass = Class.forName(className, false,
AuthXMLUtils.class.getClassLoader());
if (!DSAMECallbackInterface.class.isAssignableFrom(xmlClass)) {
debug.error("createCustomCallback : class " + className
+ " is not a DSAMECallbackInterface implementation");
return null;
}
callback = (DSAMECallbackInterface) xmlClass.newInstance();
}
}
@@ -1784,6 +1836,7 @@ public static Subject getDeSerializedSubject(String subjectSerialized)
//convert byte to object using streams
byteIn = new ByteArrayInputStream(byteDecrypted);
objInStream = new ObjectInputStream(byteIn);
objInStream.setObjectInputFilter(SUBJECT_DESERIALISATION_FILTER);
tempObject = objInStream.readObject();</pre>
Fix : The patch modifies `Class.forName` to prevent static initializers from running and adds a check to ensure the loaded class implements `DSAMECallbackInterface` before instantiation. It also introduces an `ObjectInputFilter` for `Subject` deserialization, allowing only a predefined set of safe classes (primitives, `Principal` implementations, and specific JDK/security classes) to prevent arbitrary object deserialization.
CRITICAL 9.8 · 2026-07-21 · Go
code.gitea.io/gitea · Pattern: RACE_CONDITION→DOUBLE_SPEND · 2x across ecosystem
Root cause : The Gitea Docker image, when configured with `REVERSE_PROXY_TRUSTED_PROXIES = *`, allowed any source IP to impersonate any user via the `X-WEBAUTH-USER` header. Additionally, the TOTP (Time-based One-Time Password) validation logic was susceptible to replay attacks because it did not atomically consume the passcode after successful validation, allowing the same passcode to be used multiple times within its validity window.
Impact : An attacker could bypass two-factor authentication by replaying a valid TOTP passcode. In the context of the Docker image misconfiguration, this could be combined with user impersonation to gain unauthorized access to user accounts.
Diff
--- a/models/auth/twofactor.go
+++ b/models/auth/twofactor.go
-func (t *TwoFactor) ValidateTOTP(passcode string) (bool, error) {
+func (t *TwoFactor) ValidateAndConsumeTOTP(ctx context.Context, passcode string) (bool, error) {
return totp.Validate(passcode, secretStr), nil
}
+ // Conditional update: only a row whose stored passcode differs from this one is updated, so a
+ // replay (or a concurrent duplicate) matches zero rows and is rejected. The row lock taken by
+ // the UPDATE serializes racing requests, closing the read-validate-write TOCTOU window.
+ t.LastUsedPasscode = passcodeFix : The patch introduces `ValidateAndConsumeTOTP` which atomically validates and consumes a TOTP passcode by updating a `last_used_passcode` field in the database. This prevents replay attacks by ensuring a passcode can only be used once. The web and API authentication flows are updated to use this new atomic validation function.
CRITICAL 9.8 · 2026-07-09 · PHP
yeswiki/yeswiki · Pattern: UNSANITIZED_INPUT→COMMAND · 56x across ecosystem
Root cause : The application used `eval()` on user-supplied input for a formula calculator. While there was a regular expression to validate the formula, it was insufficient to prevent malicious code injection, allowing an attacker to execute arbitrary PHP code.
Impact : An attacker could achieve full remote code execution on the server, leading to complete compromise of the application and underlying system, as well as denial of service.
Diff
- if (preg_match($regexpToCheckIfMathFormula, $formula)) {
- $formula = preg_replace('!pi|π!', 'pi()', $formula);
- try {
- eval("$value = $formula;");
- $value = $value ?? 0;
- } catch (Throwable $th) {
- $value = 0;
- }
- } else {
- $value = 'formula not correct !';
+ try {
+ $value = $this->evaluateFormula($formula);
+ if (!is_finite($value)) {
+ $value = 0;
+ }
+ } catch (Throwable $th) {
+ $value = 0;
}Fix : The `eval()` function has been removed. The application now uses a custom-built parser and evaluator for mathematical formulas, which tokenizes the input and processes it through a defined set of allowed operations and functions, preventing arbitrary code execution.
CRITICAL 9.8 · 2026-06-11 · PHP
codeigniter4/framework · Pattern: UNCLASSIFIED · 343x across ecosystem
Root cause : The vulnerability existed because the `ext_in` validation rule only checked the guessed file extension, which could be manipulated by an attacker. The `guessExtension()` method might return an empty string or an incorrect extension if the file's MIME type or content was malformed, allowing a malicious file with a dangerous extension (e.g., .php) to bypass the intended extension whitelist.
Impact : An attacker could upload files with disallowed extensions, potentially leading to remote code execution if the server is configured to execute scripts based on their extension, or other forms of system compromise.
Diff
- if (! in_array($file->guessExtension(), $params, true)) {
+ $clientExtension = strtolower($file->getClientExtension());
+
+ if ($clientExtension === '' || ! in_array($clientExtension, $params, true)) {
+ return false;
+ }
+
+ if ($file->guessExtension() !== $clientExtension) {
return false;
}Fix : The patch enhances the `ext_in` validation rule by explicitly checking both the client-provided file extension (`getClientExtension()`) and comparing it with the guessed extension (`guessExtension()`). It ensures that the client extension is not empty and is part of the allowed list, and that the guessed extension matches the client extension, preventing bypasses through manipulated file types.
CRITICAL 9.8 · 2026-05-29 · JavaScript
vm2 · Pattern: TYPE_CONFUSION→BYPASS · 4x across ecosystem
Root cause : The vm2 sandbox failed to properly isolate WebAssembly JavaScript Promise Integration (JSPI) Promises. These Promises, when created within the sandbox, had their prototype chain directly linked to the host realm's `Promise.prototype`, bypassing the sandbox's proxy mechanisms and overrides. This allowed an attacker to manipulate the `constructor` property of a JSPI Promise, leading to the creation of host-realm Promise resolution/rejection functions that executed attacker-controlled code in the host context.
Impact : An attacker could execute arbitrary code in the host environment, effectively escaping the vm2 sandbox and gaining full control over the system running the sandboxed code.
Diff
--- a/lib/setup-sandbox.js
+++ b/lib/setup-sandbox.js
@@ -473,6 +473,57 @@ if (typeof WebAssembly !== 'undefined' && WebAssembly.JSTag !== undefined) {
localReflectDeleteProperty(WebAssembly, 'JSTag');
}
+if (typeof WebAssembly !== 'undefined') {
// SECURITY (GHSA-6j2x-vhqr-qr7q): WebAssembly.promising returns Promises with
// host-realm Promise.prototype in their [[Prototype]] chain. No sandbox-side
// override and no bridge proxy can intercept method dispatch on such objects.
if (typeof WebAssembly.promising !== 'undefined') {
localReflectDeleteProperty(WebAssembly, 'promising');
}
// SECURITY (GHSA-6j2x-vhqr-qr7q): WebAssembly.Suspending is required to satisfy
// the suspending-import slot in any JSPI module. Removing it alone closes the
// instantiation half of the chain; removing .promising closes the export half.
if (typeof WebAssembly.Suspending !== 'undefined') {
localReflectDeleteProperty(WebAssembly, 'Suspending');
}
+}
if (
!localReflectDefineProperty(global, 'VMError', {Fix : The patch removes `WebAssembly.promising` and `WebAssembly.Suspending` from the sandbox environment. By deleting these properties, the sandbox prevents the creation of JSPI Promises that exhibit the problematic cross-realm prototype behavior, thereby eliminating the attack vector.
CRITICAL 9.8 · 2026-05-18 · PHP
verbb/formie · Pattern: UNSANITIZED_INPUT→TEMPLATE · 5x across ecosystem
Root cause : The application was parsing the 'defaultValue' of a hidden field as a Twig template even when the value was directly provided by the user. This allowed an attacker to inject malicious Twig template code into the 'defaultValue' which would then be executed by the server.
Impact : An unauthenticated attacker could achieve remote code execution on the server by injecting arbitrary Twig template code, leading to full system compromise.
Diff
--- a/src/fields/formfields/Hidden.php
+++ b/src/fields/formfields/Hidden.php
@@ -111,11 +111,9 @@ public function serializeValue(mixed $value, ?ElementInterface $element = null):
// Check if there's no value been added on the front-end, and use the default value
if ($value === '') {
$value = $this->defaultValue;
$value = Variables::getParsedValue($this->defaultValue, $element);
}
$value = Variables::getParsedValue($value, $element);
// Immediately update the value for the element, so integrations use the up-to-date value
if ($element) {</pre>
Fix : The patch modifies the logic to ensure that the 'defaultValue' is only parsed as a Twig template if the front-end value is empty. If a value is provided from the front-end, it is no longer passed through the template parser, preventing injection.
CRITICAL 9.8 · 2026-05-14 · JavaScript
vm2 · Pattern: UNCLASSIFIED · 343x across ecosystem
Root cause : The vm2 sandbox failed to properly sanitize values returned from async generator functions, specifically when an async generator's `yield*` delegates to an inner async iterator and a thenable's `.then` callback throws synchronously. V8's internal PromiseResolveThenableJob would capture this exception and deliver it to sandbox code as an iterator result, bypassing existing sanitization mechanisms for exceptions and promise rejections.
Impact : An attacker could escape the vm2 sandbox, allowing them to execute arbitrary code in the host environment with the privileges of the Node.js process running the sandbox.
Diff
--- a/lib/setup-sandbox.js
+++ b/lib/setup-sandbox.js
@@ -983,6 +983,381 @@ if (typeof bridge.setHostPromiseSanitizers === 'function') {
bridge.setHostPromiseSanitizers(e => handleException(from(e)), from);
}
+// SECURITY (GHSA-248r-7h7q-cr24): Async generator yield*-return thenable
+// exception capture. When sandbox code calls i.return(thenable) on an
+// async generator that delegates via yield* to an inner async iterator
+// without a return method, V8's PromiseResolveThenableJob captures any
+// synchronous throw from the thenable's .then callback and the yield*
+// machinery delivers it to sandbox code as an iterator result
+// ({ value: thrown, done: false }). This bypasses (a) the transformer's
+// catch-block instrumentation (the catch is implicit in V8 internals)
+// and (b) the globalPromise.prototype.then rejection sanitizer above,
+// because internal Await uses PerformPromiseThen directly and never
+// invokes the user-visible .then override. Wrap
+// %AsyncGeneratorPrototype%.next / .return / .throw so every value
+// flowing out of an async generator into sandbox code is routed through
+// handleException — restoring the invariant that no host-realm value
+// can reach sandbox code without sanitization.
+let localAsyncGeneratorPrototype = null;Fix : The patch wraps the `%AsyncGeneratorPrototype%.next`, `.return`, and `.throw` methods. This ensures that all values flowing out of an async generator into sandbox code are routed through `handleException` for sanitization. It also introduces robust handling for thenables passed to these methods, preventing various bypasses related to synchronous throws, nested thenables, and Time-of-Check to Time-of-Use (TOCTOU) attacks on `.then` getters.
CRITICAL 9.8 · 2026-05-14 · C#
Marten · Pattern: UNSANITIZED_INPUT→SQL · 22x across ecosystem
Root cause : The application directly interpolated the 'regConfig' parameter into a SQL query without proper validation or sanitization. This allowed an attacker to inject arbitrary SQL commands by manipulating the 'regConfig' value.
Impact : An attacker could execute arbitrary SQL commands on the PostgreSQL database, potentially leading to data exfiltration, modification, or deletion, and even remote code execution depending on database privileges.
Diff
--- a/src/Marten/Linq/SqlGeneration/Filters/FullTextWhereFragment.cs
+++ b/src/Marten/Linq/SqlGeneration/Filters/FullTextWhereFragment.cs
@@ -18,6 +31,8 @@ internal class FullTextWhereFragment: ISqlFragment
public FullTextWhereFragment(DocumentMapping? mapping, FullTextSearchFunction searchFunction, string searchTerm,
string regConfig = FullTextIndexDefinition.DefaultRegConfig)
{
+ ValidateRegConfig(regConfig);
+
_regConfig = regConfig;
_dataConfig = GetDataConfig(mapping, regConfig).Replace("data", "d.data");</pre>
Fix : The patch introduces a regular expression to validate the 'regConfig' parameter. It ensures that 'regConfig' only contains characters valid for a PostgreSQL text-search configuration name, rejecting any input that could lead to SQL injection.
CRITICAL 9.8 · 2026-05-08 · PHP
snipe/snipe-it · Pattern: MISSING_AUTHZ→RESOURCE · 76x across ecosystem
Root cause : The application allowed users with 'view' permissions on an object to upload files associated with that object. This is a weaker permission than 'update', which should be required for file uploads, leading to an authorization bypass for file modification.
Impact : An attacker with only 'view' permissions on an object could upload arbitrary files, potentially leading to remote code execution if the uploaded file is a malicious script (e.g., PHP file) and the server is configured to execute it.
Diff
- $this->authorize('view', $object);
+ $this->authorize('update', $object);Fix : The patch changes the authorization check for file uploads from 'view' to 'update'. This ensures that only users with sufficient privileges to modify an object can upload files associated with it.
CRITICAL 9.8 · 2026-04-24 · JavaScript
electerm · Pattern: UNSANITIZED_INPUT→COMMAND · 56x across ecosystem
Root cause : The original `runLinux` function used `exec` from `shelljs` to execute shell commands, constructing parts of the command string directly from unsanitized version information (`ver`) and folder names (`folderName`). An attacker could manipulate these inputs to inject arbitrary shell commands.
Impact : An attacker could achieve arbitrary code execution on the system where the `electerm` package is being installed, potentially leading to full system compromise.
Diff
--- a/npm/install.js
+++ b/npm/install.js
@@ -100,9 +100,27 @@
}
async function runLinux (folderName, filePattern) {
const ver = await getVer()
const target = resolve(__dirname, ../electerm-${ver.replace('v', '')}-${folderName})
const targetNew = resolve(__dirname, '../electerm')
exec(`rm -rfFix : The patch introduces `sanitizeVersion` and `sanitizeFilename` functions to validate and clean inputs before they are used in shell commands. It also replaces `exec` with `execSync` for synchronous execution and `execFile` for safer execution of specific binaries, avoiding direct shell command construction with untrusted input.
CRITICAL 9.8 · 2026-04-24 · Go
github.com/woven-planet/go-zserio · Pattern: DOS→RESOURCE_EXHAUSTION · 104x across ecosystem
Root cause : The application did not limit the size of arrays, byte buffers, or strings when deserializing data from a zserio bitstream. An attacker could provide a crafted input with an extremely large declared size, causing the application to attempt to allocate an unbounded amount of memory.
Impact : An attacker could trigger a denial of service by causing the application to exhaust available memory, leading to crashes or system instability.
Diff
--- a/ztype/array_decode.go
+++ b/ztype/array_decode.go
arraySize := array.FixedSize
// Limit the initial capacity to a reasonable number to avoid excessive memory allocation.
// This is needed in case the input is untrusted could have an overly large value.
array.RawArray = make([]T, 0, arraySize)
if maxInitialArrayCapacityInt == 0 {
array.RawArray = make([]T, 0, arraySize)
} else {
array.RawArray = make([]T, 0, min(arraySize, maxInitialArrayCapacityInt))
}Fix : The patch introduces maximum initial capacity limits for arrays, byte buffers, and strings during deserialization. These limits are configurable via environment variables (ZSERIO_MAX_INITIAL_ARRAY_SIZE, ZSERIO_MAX_INITIAL_BLOB_SIZE, ZSERIO_MAX_INITIAL_STRING_SIZE) and prevent excessive memory allocation based on untrusted input.
CRITICAL 9.8 · 2026-04-17 · Python
praisonai · Pattern: UNSANITIZED_INPUT→COMMAND · 56x across ecosystem
Root cause : The code did not validate the executable part of the command input.
Impact : An attacker could execute arbitrary commands on the server if they could control the `--mcp` argument.
Diff
Before:
cmd = parts[0]
After:
basename = os.path.basename(cmd)
if basename not in ALLOWED_MCP_COMMANDS:
raise ValueError(...)Fix : The patch adds a whitelist of allowed MCP command executables and raises an error if the provided command is not in this list.
CRITICAL 9.8 · 2026-04-16 · Python
uefi-firmware · Pattern: BUFFER_OVERFLOW→STACK · 5x across ecosystem
Root cause : The `MakeTable` function, responsible for creating Huffman code mapping tables, did not adequately validate the `BitLen` array values. Specifically, it failed to check if `BitLen[Index]` exceeded 16 or if `Start[Len]` (calculated from `BitLen`) could lead to an out-of-bounds write when indexing the `Table` array, which is allocated on the stack.
Impact : An attacker providing specially crafted compressed data could cause a stack out-of-bounds write, potentially leading to arbitrary code execution or denial of service by corrupting stack data or control flow.
Diff
--- a/uefi_firmware/compression/Tiano/Decompress.c
+++ b/uefi_firmware/compression/Tiano/Decompress.c
@@ -208,14 +188,16 @@ Routine Description:
}
for (Index = 0; Index < NumOfChar; Index++) {
if (BitLen[Index] > 16) {
return (UINT16) BAD_TABLE;
}
Count[BitLen[Index]]++;
}
@@ -245,18 +227,20 @@ Routine Description:
if (Len <= TableBits) {
if (Start[Len] >= NextCode || NextCode > MaxTableLength) {
return (UINT16) BAD_TABLE;
}
for (Index = Start[Len]; Index < NextCode; Index++) {
if(Index >= TableSize)
{
Sd->mBadAlgorithm = 1;
return (UINT16) BAD_TABLE;
}
Table[Index] = Char;
}
+Fix : The patch adds checks within the `MakeTable` function to ensure that `BitLen[Index]` does not exceed 16 and that calculated table indices (`Start[Len]`) do not go out of bounds of the `Table` array. It also removes the `mBadAlgorithm` flag and replaces it with a direct return of `BAD_TABLE` upon detection of an invalid table.
CRITICAL 9.8 · 2026-04-16 · C#
Microsoft.Native.Quic.MsQuic.OpenSSL · Pattern: UNCLASSIFIED · 343x across ecosystem
Root cause : The code did not properly validate the count value before using it, allowing an attacker to potentially elevate privileges.
Impact : An attacker could exploit this vulnerability to perform actions that require higher privileges than intended.
Diff
Before:
Largest -= (Block.Gap + 1);
Count = Block.AckBlock + 1;
After:
if (Count > Largest + 1) {
*InvalidFrame = TRUE;
return FALSE;
}
Largest -= (Block.Gap + 1);
Count = Block.AckBlock + 1;Fix : The patch adds a validation check to ensure that Count is within a safe range before proceeding with further operations, preventing potential privilege escalation.
CRITICAL 9.8 · 2026-04-16 · Python
uefi-firmware · Pattern: BUFFER_OVERFLOW→HEAP · 32x across ecosystem
Root cause : The vulnerability existed in the `MakeTable` function within the Tiano decompressor. Specifically, the `Table` array, which is used to store Huffman code mappings, could be written to beyond its allocated bounds if the calculated `Index` or `NextCode` values exceeded the expected `TableSize` (or `MaxTableLength`). This was due to insufficient bounds checking on the `Index` variable before writing to `Table[Index]`, particularly when `Len` was less than or equal to `TableBits`.
Impact : An attacker could craft a malicious compressed UEFI firmware image that, when processed by the decompressor, would trigger a heap out-of-bounds write. This could lead to denial of service (crash), arbitrary code execution, or other memory corruption issues, compromising the integrity and security of the system's firmware.
Diff
--- a/uefi_firmware/compression/Tiano/Decompress.c
+++ b/uefi_firmware/compression/Tiano/Decompress.c
@@ -208,14 +188,16 @@ Routine Description:
}
for (Index = 0; Index < NumOfChar; Index++) {
if (BitLen[Index] > 16) {
return (UINT16) BAD_TABLE;
}
Count[BitLen[Index]]++;
}
// ... (lines omitted for brevity)
if (Len <= TableBits) {
if (Start[Len] >= NextCode || NextCode > MaxTableLength) {
return (UINT16) BAD_TABLE;
}
for (Index = Start[Len]; Index < NextCode; Index++) {
if(Index >= TableSize)
{
Sd->mBadAlgorithm = 1;
return (UINT16) BAD_TABLE;
}
Table[Index] = Char;
}
} else {Fix : The patch introduces explicit bounds checks within the `MakeTable` function. It now verifies that `BitLen[Index]` does not exceed 16 and that `Start[Len]` and `NextCode` remain within the `MaxTableLength` before writing to the `Table` array. Additionally, it removes the `mBadAlgorithm` flag and simplifies the `TableSize` calculation, ensuring that all writes to `Table` are within its allocated memory.
CRITICAL 9.8 · 2026-04-15 · Python
upsonic · Pattern: UNCLASSIFIED · 343x across ecosystem
Root cause : The code snippet provided does not contain any obvious security vulnerabilities.
Impact : No impact can be determined from the given code snippet.
Fix : No fix is applicable as there are no known issues in the provided code.
CRITICAL 9.8 · 2026-04-06 · Python
changedetection.io · Pattern: MISSING_AUTH→ENDPOINT · 45x across ecosystem
Root cause : The `login_optionally_required` decorator was moved above the route decorators, allowing unauthenticated access to routes that should be protected.
Impact : An attacker could bypass authentication and perform actions they are not authorized to do, such as downloading backups or removing backup files.
Diff
Before:
- @login_optionally_required
@backups_blueprint.route("/request-backup", methods=['GET'])
After:
+ @backups_blueprint.route("/request-backup", methods=['GET'])
+ @login_optionally_requiredFix : Moved the `login_optionally_required` decorator below all route decorators to ensure proper authentication checks.
CRITICAL 9.6 · 2026-07-24 · Java
org.openidentityplatform.opendj:opendj-server-legacy · Pattern: PRIVILEGE_ESCALATION→ROLE · 32x across ecosystem
Root cause : The OpenDJ SASL PLAIN mechanism handler did not properly enforce access control checks for authorization identities (authzId). Specifically, it failed to call the `checkProxyAccess` method, which verifies if the authenticated user has the necessary 'proxy' access rights to assume a different authorization identity. This omission allowed an authenticated user to bypass the intended ACI scope checks.
Impact : An attacker could authenticate as a legitimate user and then assume the identity of another user, including privileged accounts, without proper authorization. This leads to privilege escalation, allowing the attacker to perform actions with the assumed user's permissions.
Diff
--- a/opendj-server-legacy/src/main/java/org/opends/server/extensions/PlainSASLMechanismHandler.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/extensions/PlainSASLMechanismHandler.java
@@ -330,6 +331,11 @@ public void processSASLBind(BindOperation bindOperation)
return;
}
}
+
+ if (! checkProxyAccess(bindOperation, userEntry, authZEntry))
+ {
+ return;
+ }
}
}
elseFix : The patch introduces calls to a new `checkProxyAccess` method within the `processSASLBind` function of the `PlainSASLMechanismHandler`. This method delegates to `SASLContext.hasProxyAccess` to ensure that the authenticated user has the 'proxy' access control right for the target authorization identity, thus enforcing the ACI scope check.
CRITICAL 9.6 · 2026-07-21 · Go
code.gitea.io/gitea · Pattern: WEAK_CRYPTO→HASH · 3x across ecosystem
Root cause : The vulnerability stemmed from an ambiguity in how HMAC signatures were generated for Gitea Actions artifacts. The previous implementation concatenated string and integer values directly into the HMAC function without length-prefixing or clear delimiters. This allowed an attacker to craft inputs where different combinations of values (e.g., artifactName and taskID) could produce the same HMAC signature, leading to a collision.
Impact : An attacker could exploit this ambiguity to read artifacts from other repositories (cross-repository artifact read) or manipulate the upload state of artifacts in other tasks (cross-task upload-state write), bypassing intended access controls.
Diff
--- a/routers/api/actions/artifactsv4.go
+++ b/routers/api/actions/artifactsv4.go
@@ -161,13 +161,7 @@ func ArtifactsV4Routes(prefix string) *web.Router {
}
func (r *artifactV4Routes) buildSignature(endpoint, expires, artifactName string, taskID, artifactID int64) []byte {
mac := hmac.New(sha256.New, setting.GetGeneralTokenSigningSecret())
mac.Write([]byte(endpoint))
mac.Write([]byte(expires))
mac.Write([]byte(artifactName))
_, _ = fmt.Fprint(mac, taskID)
_, _ = fmt.Fprint(mac, artifactID)
return mac.Sum(nil)
return actions.BuildSignature("v4", endpoint, expires, artifactName, strconv.FormatInt(taskID, 10), strconv.FormatInt(artifactID, 10))
}Fix : The patch introduces a new `BuildSignature` helper function that explicitly length-prefixes all input values before feeding them into the HMAC algorithm. It also adds a 'tag' parameter to distinguish signatures for different purposes. This ensures that each component of the signed data is unambiguously separated, preventing collision attacks.
CRITICAL 9.6 · 2026-07-21 · JavaScript
@sigstore/oci · Pattern: CREDENTIAL_LEAK→LOG_EXPOSURE · 7x across ecosystem
Root cause : The vulnerability stemmed from an overly broad credential matching logic. The system used `key.includes(registry)` to find credentials, which meant that credentials for a registry like `myregistry.com` could be inadvertently sent to an attacker-controlled registry like `evilmyregistry.com` because the latter's name included the former.
Impact : An attacker could craft a malicious registry name that is a substring of a legitimate registry for which the user has credentials. When the user attempts to interact with the attacker's registry, their legitimate credentials for the intended registry would be leaked to the attacker.
Diff
- Object.keys(dockerConfig.auths || {}).find((key) =>
- key.includes(registry)
- ) || registry;
+ const target = canonicalizeRegistry(registry);
+ const credKey = Object.keys(dockerConfig.auths || {}).find(
+ (key) => canonicalizeRegistry(key) === target
+ );Fix : The patch introduces a `canonicalizeRegistry` function to normalize registry hostnames, including handling Docker Hub aliases. It then changes the credential lookup to use an exact match (`canonicalizeRegistry(key) === target`) instead of a substring match, ensuring credentials are only sent to the exact intended registry.
CRITICAL 9.6 · 2026-07-01 · Go
github.com/rancher/rancher · Pattern: UNCLASSIFIED · 343x across ecosystem
Root cause :
Impact :
Fix :
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 49 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 | 1253 |
| Unique patterns | 49 |
| Pending | 0 |
| Last updated | 2026-07-29 |
christbowel.com