Skip to content

Chocapikk/OSDC

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

93 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

🎣 Open Source Daily Catch

Automated Patch Intelligence for Security Engineers

Analysis Render Advisories Patterns

Live dashboard · How it works


GHSA-gph2-j4c9-vhhr

CRITICAL 10.0 · 2026-04-14 · PHP
wwbn/avideo · Pattern: UNSANITIZED_INPUT→XSS · 9x 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.

Advisory · Commit


GHSA-9cp7-j3f8-p5jx

CRITICAL 10.0 · 2026-04-10 · Go
github.com/daptin/daptin · Pattern: PATH_TRAVERSAL→FILE_WRITE · 10x 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.

Advisory · Commit


GHSA-fvcv-3m26-pcqx

CRITICAL 10.0 · 2026-04-10 · JavaScript
axios · Pattern: UNSANITIZED_INPUT→HEADER · 2x 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.

Advisory · Commit


GHSA-2689-5p89-6j3j

CRITICAL 9.8 · 2026-04-16 · Python
uefi-firmware · Pattern: BUFFER_OVERFLOW→STACK · 1x 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.

Advisory · Commit


GHSA-hm2w-vr2p-hq7w

CRITICAL 9.8 · 2026-04-16 · Python
uefi-firmware · Pattern: BUFFER_OVERFLOW→HEAP · 7x 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.

Advisory · Commit


GHSA-jmrh-xmgh-x9j4

CRITICAL 9.8 · 2026-04-06 · Python
changedetection.io · Pattern: MISSING_AUTH→ENDPOINT · 7x 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_required

Fix : Moved the `login_optionally_required` decorator below all route decorators to ensure proper authentication checks.

Advisory · Commit


GHSA-8wrq-fv5f-pfp2

CRITICAL 9.6 · 2026-04-10 · Python
lollms · Pattern: UNSANITIZED_INPUT→XSS · 9x across ecosystem

Root cause : The application did not properly sanitize user-supplied content before storing it in the database and later rendering it. This allowed attackers to inject malicious scripts into posts, comments, and direct messages.

Impact : An attacker could inject arbitrary client-side scripts, leading to session hijacking, defacement, redirection to malicious sites, or other client-side attacks against users viewing the compromised content.

Diff
--- a/backend/routers/social/__init__.py
+++ b/backend/routers/social/__init__.py
@@ -149,9 +176,12 @@ def create_post(
     moderation_enabled = settings.get("ai_bot_moderation_enabled", False)
     initial_status = "pending" if moderation_enabled else "validated"
 
+    # Sanitize content to prevent Stored XSS
+    clean_content = sanitize_content(post_data.content)
+
     new_post = DBPost(
         author_id=current_user.id,
-        content=post_data.content,
+        content=clean_content,
         visibility=post_data.visibility,

Fix : The patch introduces a `sanitize_content` function using the `bleach` library to clean user input. This function is applied to all user-generated content (posts, comments, direct messages, and group conversation names) before it is stored in the database, stripping or escaping disallowed HTML tags and attributes.

Advisory · Commit


GHSA-65w6-pf7x-5g85

CRITICAL 9.4 · 2026-04-08 · JavaScript
@delmaredigital/payload-puck · Pattern: MISSING_AUTH→ENDPOINT · 7x across ecosystem

Root cause : The endpoints were missing proper authorization checks, allowing unauthenticated access to CRUD operations on Puck-registered collections.

Impact : An attacker could perform any CRUD operation on the collections without authentication, potentially leading to data leakage or manipulation.

Diff
Before:
-      const body = await req.json?.()
-      const { _locale } = body || {}
-      const locale = resolveLocale(req, _locale)

After:
+      const locale = resolveLocale(req)
+
+      const result = await req.payload.find({
+        collection: collection as CollectionSlug,
+        req,
+        overrideAccess: false,

Fix : The patch adds access control by passing `overrideAccess: false` and `req` to Payload's local API, ensuring that collection-level access rules are enforced.

Advisory · Commit


GHSA-m5gr-86j6-99jp

CRITICAL 9.1 · 2026-04-10 · Python
gramps-webapi · Pattern: PATH_TRAVERSAL→FILE_WRITE · 10x across ecosystem

Root cause : The application extracted files from a user-provided zip archive without validating the paths of the entries within the archive. This allowed an attacker to craft a zip file containing entries with malicious paths (e.g., `../../../../etc/passwd`) that, when extracted, would write files outside the intended temporary directory.

Impact : An attacker could write arbitrary files to arbitrary locations on the server's filesystem, potentially leading to remote code execution, data corruption, or denial of service.

Diff
temp_dir_real = os.path.realpath(temp_dir)
for member in zip_file.namelist():
    member_path = os.path.realpath(os.path.join(temp_dir_real, member))
    if not member_path.startswith(temp_dir_real + os.sep):
        raise ValueError(f"Zip Slip path traversal detected: {member}")

Fix : The patch adds a validation step before extraction. It iterates through each member of the zip file, constructs its intended extraction path, and checks if the real path of the member remains within the designated temporary directory. If a path traversal attempt is detected, an error is raised.

Advisory · Commit


GHSA-wvhv-qcqf-f3cx

CRITICAL 0.0 · 2026-04-10 · Go
github.com/patrickhener/goshs · Pattern: MISSING_AUTHZ→RESOURCE · 11x across ecosystem

Root cause : The application's file-based Access Control List (ACL) mechanism, which uses '.goshs' files, was not consistently applied across all state-changing operations (delete, mkdir, put, upload). Specifically, the ACL check only looked for a '.goshs' file in the immediate directory, failing to consider ACLs defined in parent directories, and some operations lacked any ACL enforcement.

Impact : An attacker could bypass intended access restrictions to delete, create, or modify files and directories, including potentially sensitive ones, even if a parent directory's '.goshs' file explicitly denied such actions.

Diff
--- a/httpserver/handler.go
+++ b/httpserver/handler.go
@@ -83,8 +83,8 @@ func (fs *FileServer) doDir(file *os.File, w http.ResponseWriter, req *http.Requ
 		}
 	}
 
-	// Check if the dir has a .goshs ACL file
-	config, err := fs.findSpecialFile(file.Name())
+	// Check for effective .goshs ACL (walks up to webroot so parent configs apply recursively)
+	config, err := fs.findEffectiveACL(file.Name())
 	if err != nil
 		logger.Errorf("error reading file based access config: %+v", err)
 	}

Fix : The patch introduces a new `findEffectiveACL` function that recursively walks up the directory tree to find the nearest applicable '.goshs' ACL file. This function is now consistently used across all file and directory operations (doDir, doFile, deleteFile, handleMkdir, put, upload) to ensure proper authorization. Additionally, explicit checks were added to prevent the deletion or overwriting of '.goshs' ACL files themselves.

Advisory · Commit


GHSA-3p68-rc4w-qgx5

CRITICAL 0.0 · 2026-04-09 · JavaScript
axios · Pattern: SSRF→INTERNAL_ACCESS · 15x across ecosystem

Root cause : The code does not properly validate or sanitize the hostname in the `no_proxy` environment variable, allowing attackers to bypass proxy settings and potentially access internal services.

Impact : An attacker could use this vulnerability to perform SSRF attacks, accessing internal network resources without proper authorization.

Diff
- 
+ +const normalizeNoProxyHost = (hostname) => {
+  if (!hostname) {
+    return hostname;
+  }
+
+  if (hostname.charAt(0) === '[' && hostname.charAt(hostname.length - 1) === ']') {
+    hostname = hostname.slice(1, -1);
+  }
+
+  return hostname.replace(/\.+$/, '');
+};

Fix : The patch introduces a function to normalize and parse the `no_proxy` entries, ensuring that only valid hostnames are considered for bypassing proxy settings.

Advisory · Commit


GHSA-2679-6mx9-h9xc

CRITICAL 0.0 · 2026-04-08 · Python
marimo · Pattern: MISSING_AUTH→ENDPOINT · 7x across ecosystem

Root cause : The WebSocket endpoint was not properly authenticated before processing requests.

Impact : An attacker could bypass authentication and execute arbitrary code on the server.

Diff
Before:
    await websocket.close(
        code=1008, reason="Terminal only available in edit mode"
    )
After:
    if app_state.enable_auth and not validate_auth(websocket):
        await websocket.close(
            WebSocketCodes.UNAUTHORIZED, "MARIMO_UNAUTHORIZED"
        )
        return

Fix : Added a validation step to check for proper authentication before allowing WebSocket connections.

Advisory · Commit


GHSA-2cqq-rpvq-g5qj

CRITICAL 0.0 · 2026-04-07 · Java
org.openidentityplatform.openam:openam · Pattern: DESERIALIZATION→RCE · 2x across ecosystem

Root cause : The code uses `ObjectInputStream` to deserialize data without proper validation or sanitization, allowing an attacker to execute arbitrary code.

Impact : An attacker could exploit this vulnerability to execute arbitrary code on the server, potentially leading to full control of the system.

Diff
Before:
- ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(data));
After:
+ if (data.startsWith("com.sun.identity")) {
+     ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(data));
+ } else {
+     throw new SecurityException("Invalid class name in deserialized data");
+ }

Fix : The patch adds a check for the class name during deserialization to prevent untrusted objects from being deserialized.

Advisory · Commit


GHSA-66hx-chf7-3332

HIGH 8.8 · 2026-04-14 · Python
pyload-ng · Pattern: PRIVILEGE_ESCALATION→ROLE · 2x across ecosystem

Root cause : The application did not invalidate user sessions when a user's password, role, or permissions were changed. This allowed users to retain their old privileges until their session naturally expired or they manually logged out, even after an administrator had downgraded their access.

Impact : An attacker or a malicious insider could maintain elevated privileges or access to resources that should have been revoked, potentially leading to unauthorized actions or data access.

Diff
--- a/src/pyload/webui/app/blueprints/json_blueprint.py
+++ b/src/pyload/webui/app/blueprints/json_blueprint.py
@@ -9,7 +9,7 @@
 from pyload.core.api import Role
 from pyload.core.utils import format, fs
 
-from ..helpers import get_permission, login_required, permlist, render_template, set_permission
+from ..helpers import clear_all_user_sessions, get_permission, login_required, permlist, render_template, set_permission
 
 bp = flask.Blueprint("json", __name__)
 
@@ -360,6 +360,7 @@ def change_password(user_login, user_curpw, user_newpw):
     if not done:
         return jsonify(False), 403  #: Wrong password
 
+    clear_all_user_sessions(user_login)
     return jsonify(True)

Fix : The patch introduces a `clear_all_user_sessions` function and calls it whenever a user's password is changed, or their role or permissions are updated. This ensures that any active sessions for the affected user are immediately invalidated, forcing them to re-authenticate with their new, updated privileges.

Advisory · Commit


GHSA-3p24-9x7v-7789

HIGH 8.8 · 2026-04-13 · Java
gov.nsa.emissary:emissary · Pattern: UNSANITIZED_INPUT→COMMAND · 13x across ecosystem

Root cause : The application allowed user-controlled input for IN_FILE_ENDING and OUT_FILE_ENDING configuration parameters to be used directly in shell commands without proper sanitization. This enabled attackers to inject arbitrary shell commands by crafting malicious file ending values.

Impact : An attacker could execute arbitrary operating system commands on the server, potentially leading to full system compromise, data exfiltration, or denial of service.

Diff
--- this.inFileEnding = configG.findStringEntry("IN_FILE_ENDING", "");
+++ this.inFileEnding = cleanFileEnding(configG.findStringEntry("IN_FILE_ENDING", ""));
--- this.outFileEnding = configG.findStringEntry("OUT_FILE_ENDING", this.inFileEnding.isEmpty() ? ".out" : "");
+++ this.outFileEnding = cleanFileEnding(configG.findStringEntry("OUT_FILE_ENDING", this.inFileEnding.isEmpty() ? ".out" : ""));

Fix : The patch introduces a new `cleanFileEnding` method that sanitizes the `IN_FILE_ENDING` and `OUT_FILE_ENDING` parameters. This method uses a regular expression to remove any characters that are not alphanumeric, underscore, hyphen, or a leading dot, preventing command injection.

Advisory · Commit


GHSA-jvff-x2qm-6286

HIGH 8.8 · 2026-04-10 · JavaScript
mathjs · Pattern: UNCLASSIFIED · 32x across ecosystem

Root cause : The code did not validate that the index parameter was an array, allowing attackers to manipulate object attributes improperly.

Impact : An attacker could potentially modify or delete arbitrary properties of objects, leading to unauthorized data manipulation or loss.

Diff
Before:
if (!Array.isArray(array)) { throw new Error('Array expected') }

After:
if (!Array.isArray(index)) {
  throw new Error('Array expected for index')
}

Fix : The patch ensures that the index parameter is always treated as an array, preventing improper modifications of object attributes.

Advisory · Commit


GHSA-5gfj-64gh-mgmw

HIGH 8.8 · 2026-04-08 · Python
agixt · Pattern: PATH_TRAVERSAL→FILE_READ · 10x across ecosystem

Root cause : The `safe_join` function did not properly validate the resolved path to ensure it stayed within the agent's WORKING_DIRECTORY.

Impact : An attacker could exploit this vulnerability to read or write files outside of the intended directory, potentially leading to unauthorized access or data corruption.

Diff
Before:
new_path = os.path.normpath(
    os.path.join(self.WORKING_DIRECTORY, *paths.split("/"))
)

After:
base = os.path.realpath(self.WORKING_DIRECTORY)
new_path = os.path.realpath(
    os.path.normpath(os.path.join(self.WORKING_DIRECTORY, *paths.split("/")))
)
if not (new_path.startswith(base + os.sep) or new_path == base):
    raise PermissionError(
        f"Path traversal detected: refusing to access path outside workspace"
    )

Fix : The patch uses `os.path.realpath` to resolve symlinks and relative paths, and then checks if the resolved path is within the agent's WORKING_DIRECTORY. If not, it raises a `PermissionError`.

Advisory · Commit


GHSA-qxpc-96fq-wwmg

HIGH 8.8 · 2026-04-07 · Java
org.apache.cassandra:cassandra-all · Pattern: PRIVILEGE_ESCALATION→ROLE · 2x across ecosystem

Root cause : The patch fails to properly validate the user's permissions before allowing them to drop an identity, potentially escalating their privileges.

Impact : An attacker could exploit this vulnerability to escalate their privileges within the Cassandra environment by dropping identities and assuming roles they are not authorized to.

Diff
Before:
checkPermission(state, Permission.DROP, state.getUser().getPrimaryRole());

After:
String roleForIdentity = DatabaseDescriptor.getRoleManager().roleForIdentity(identity);
if (roleForIdentity == null)
{
    checkPermission(state, Permission.DROP, RoleResource.root());
}
else
{
    checkPermission(state, Permission.DROP, RoleResource.role(roleForIdentity));
}

Fix : The patch adds checks to ensure that only users with appropriate permissions can drop identities. It verifies that the user has permission to drop the target role before allowing the operation.

Advisory · Commit


GHSA-9pr4-rf97-79qh

HIGH 8.7 · 2026-04-13 · Go
github.com/enchant97/note-mark/backend · Pattern: UNSANITIZED_INPUT→XSS · 9x across ecosystem

Root cause : The application allowed unrestricted upload of assets and served them with their original Content-Type, including 'text/html' and 'image/svg+xml'. This enabled an attacker to upload malicious HTML or SVG files containing JavaScript, which would then execute in the victim's browser when the asset was viewed.

Impact : An attacker could execute arbitrary JavaScript in the context of the victim's browser, leading to session hijacking, defacement, or redirection to malicious sites.

Diff
- ctx.SetHeader("Content-Type", info.MimeType)
+ if info.MimeType == "" || info.MimeType == "text/html" || info.MimeType == "image/svg+xml" {
+ 	ctx.SetHeader("Content-Type", "application/octet-stream")
+ } else {
+ 	ctx.SetHeader("Content-Type", info.MimeType)

Fix : The patch introduces a check for 'text/html' and 'image/svg+xml' MIME types. If an uploaded asset matches these types or has an empty MIME type, it is now served with 'application/octet-stream' and 'Content-Disposition: attachment' to force a download instead of inline rendering, mitigating the XSS risk. It also adds 'X-Content-Type-Options: nosniff'.

Advisory · Commit


GHSA-chqc-8p9q-pq6q

HIGH 8.6 · 2026-04-08 · JavaScript
basic-ftp · Pattern: UNSANITIZED_INPUT→COMMAND · 13x across ecosystem

Root cause : The code did not sanitize input for control characters, allowing attackers to inject CRLF sequences that could manipulate FTP commands.

Impact : An attacker could use this vulnerability to execute arbitrary FTP commands on the server, potentially leading to unauthorized access or data manipulation.

Diff
Before:
if (!path.startsWith(" ")) {
    return path
}
After:
if (/[\r\n\0]/.test(path)) {
    throw new Error("Invalid path: Contains control characters");
}

Fix : The patch adds a regex check to reject paths containing control characters, preventing command injection attacks.

Advisory · Commit


GHSA-4ggg-h7ph-26qr

HIGH 8.5 · 2026-04-08 · JavaScript
n8n-mcp · Pattern: SSRF→INTERNAL_ACCESS · 15x across ecosystem

Root cause : The code did not properly sanitize the `instance-URL` header, allowing attackers to perform SSRF attacks.

Impact : An attacker could use this vulnerability to access internal resources or perform actions on behalf of other users within the same network.

Diff
- this.baseUrl = baseUrl;
+ let normalizedBase: string;
try {
  const parsed = new URL(baseUrl);
  parsed.hash = '';
  parsed.username = '';
  parsed.password = '';
  normalizedBase = parsed.toString().replace(//$/, '');
} catch {
  // Unparseable input falls through to raw; downstream axios call will
  // fail cleanly. Preserves backward compat for tests that pass
  // placeholder strings.
  normalizedBase = baseUrl;
}
this.baseUrl = normalizedBase;

Fix : The patch normalizes the `baseUrl` by removing any embedded credentials and ensuring it does not end with a trailing slash, enhancing defense-in-depth against SSRF attacks.

Advisory · Commit


GHSA-vvfw-4m39-fjqf

HIGH 8.3 · 2026-04-14 · PHP
wwbn/avideo · Pattern: CSRF→STATE_CHANGE · 2x across ecosystem

Root cause : The application's configuration update endpoint (configurationUpdate.json.php) lacked proper CSRF protection. This allowed an attacker to craft a malicious request that, when triggered by an authenticated administrator, would modify the site's configuration without the administrator's explicit consent.

Impact : An attacker could trick an administrator into changing critical site configurations, including the encoder URL and SMTP credentials, potentially leading to further compromise like arbitrary code execution or email spoofing.

Diff
--- a/objects/configurationUpdate.json.php
+++ b/objects/configurationUpdate.json.php
@@ -15,6 +15,8 @@
 require_once $global['systemRootPath'] . 'objects/configuration.php';
 require_once $global['systemRootPath'] . 'objects/functions.php';
 
+forbidIfIsUntrustedRequest('configurationUpdate');
+
 _error_log("save configuration {$_POST['language']}");

Fix : The patch introduces a call to `forbidIfIsUntrustedRequest('configurationUpdate');` at the beginning of the `configurationUpdate.json.php` script. This function likely implements a mechanism to verify the legitimacy of the request, such as checking for a valid CSRF token, thereby preventing unauthorized state changes.

Advisory · Commit


GHSA-6v7q-wjvx-w8wg

HIGH 8.2 · 2026-04-10 · JavaScript
basic-ftp · Pattern: UNSANITIZED_INPUT→COMMAND · 13x across ecosystem

Root cause : The code did not properly sanitize input for FTP commands, allowing control characters to be injected.

Impact : An attacker could execute arbitrary FTP commands using credentials and MKD commands due to the lack of proper input validation.

Diff
Before:
-        // Reject CRLF injection attempts
-        if (/[
\]/.test(path)) {
-            throw new Error("Invalid path: Contains control characters");
-        }
After:
+        // Reject control character injection attempts.
+        if (/[
\u0000]/.test(command)) {
+            throw new Error(`Invalid command: Contains control characters. (${command})`);
+        }

Fix : The patch added a regex check to reject any command containing control characters, preventing injection attacks.

Advisory · Commit


GHSA-75hx-xj24-mqrw

HIGH 8.2 · 2026-04-10 · JavaScript
n8n-mcp · Pattern: MISSING_AUTH→ENDPOINT · 7x across ecosystem

Root cause : The code did not handle authentication errors securely, potentially revealing sensitive information in error messages.

Impact : An attacker could exploit this vulnerability to gain insights into the system's internal workings and potentially identify valid usernames or other sensitive data.

Diff
Before:
-    next();

After:
+    const authLimiter = rateLimit({ ... });
+    app.use(authLimiter);
+    // Root endpoint with API information
+    app.get('/', (req, res) => { ... };

Fix : The patch introduces rate limiting for authentication endpoints to prevent brute force attacks and DoS. It also enhances error handling to avoid revealing sensitive information in error messages.

Advisory · Commit


GHSA-ccq9-r5cw-5hwq

HIGH 8.1 · 2026-04-14 · PHP
wwbn/avideo · Pattern: CORS_MISCONFIGURATION→ORIGIN · 2x across ecosystem

Root cause : The application's CORS policy, specifically in the `allowOrigin` function when `allowAll` was true, would reflect the `Origin` header from the request and set `Access-Control-Allow-Credentials: true`. This was intended for public resources but was applied to sensitive API endpoints, allowing any origin to make credentialed requests.

Impact : An attacker could craft a malicious webpage to make cross-origin requests to sensitive API endpoints on the vulnerable AVideo instance. Since `Access-Control-Allow-Credentials: true` was set, the victim's browser would include session cookies, enabling the attacker to read session-authenticated API responses and potentially achieve account takeover.

Diff
-        if (!empty($requestOrigin)) {
-            header('Access-Control-Allow-Origin: ' . $requestOrigin);
-            header('Access-Control-Allow-Credentials: true');
-        } else {
-            header('Access-Control-Allow-Origin: *');
+        if (!empty($requestOrigin) && !empty($siteOriginForAllowAll) && $requestOrigin === $siteOriginForAllowAll) {
+            header('Access-Control-Allow-Origin: ' . $requestOrigin);
+            header('Access-Control-Allow-Credentials: true');
+        } else {
+            header('Access-Control-Allow-Origin: *');

Fix : The patch modifies the `allowOrigin` function to explicitly check if the `requestOrigin` matches the `siteOriginForAllowAll` when `allowAll` is true. If they match, the origin is reflected with credentials. Otherwise, a wildcard origin (`*`) is used without credentials, preventing third-party origins from making credentialed requests.

Advisory · Commit


GHSA-hc36-c89j-5f4j

HIGH 8.1 · 2026-04-09 · Ruby
bsv-wallet · Pattern: MISSING_VERIFICATION→SIGNATURE · 5x across ecosystem

Root cause : The code did not verify the certifier signatures before persisting them.

Impact : An attacker could potentially bypass security checks by providing unverified signatures, leading to unauthorized access or manipulation of data.

Diff
Before:
-      REJECTED_STATUSES = %w[REJECTED DOUBLE_SPEND_ATTEMPTED].freeze
After:
+      REJECTED_STATUSES = %w[
+        REJECTED
+        DOUBLE_SPEND_ATTEMPTED
+        INVALID
+        MALFORMED
+        MINED_IN_STALE_BLOCK
+      ].freeze

Fix : The patch adds verification for certifier signatures, ensuring that only valid signatures are persisted.

Advisory · Commit


GHSA-2943-crp8-38xx

HIGH 7.7 · 2026-04-10 · Go
github.com/patrickhener/goshs · Pattern: PATH_TRAVERSAL→FILE_WRITE · 10x across ecosystem

Root cause : The code directly used the target path from the SFTP request without sanitization, allowing attackers to write files in arbitrary locations on the server.

Impact : An attacker could use this vulnerability to overwrite or create files on the server, potentially leading to data loss, unauthorized access, or further exploitation of the system.

Diff
Before:
err := os.Rename(fullPath, r.Target)

After:
targetPath, err := sanitizePath(r.Target, root)
if err != nil {
	logger.LogSFTPRequestBlocked(r, ip, err)
	sftpServer.HandleWebhookSend("sftp", r, ip, true)
	return err
}
err = os.Rename(fullPath, targetPath)

Fix : The patch introduced a path sanitization function `sanitizePath` to ensure that only valid paths are used for file operations, preventing directory traversal attacks.

Advisory · Commit


GHSA-247c-9743-5963

HIGH 7.5 · 2026-04-15 · JavaScript
fastify · Pattern: UNSANITIZED_INPUT→HEADER · 2x across ecosystem

Root cause : The vulnerability existed because the `getEssenceMediaType` function, responsible for extracting the media type from the 'Content-Type' header, only split the header string by the semicolon character. This allowed an attacker to prepend a space before the semicolon (e.g., ' application/json;charset=utf-8') to bypass the schema validation logic, as the leading space was not considered a delimiter.

Impact : An attacker could bypass the body schema validation, potentially sending malformed or unexpected data to the application. This could lead to various issues depending on how the application processes the unvalidated data, such as data corruption, unexpected application behavior, or further exploitation if the application is not robust against invalid input.

Diff
--- a/lib/validation.js
+++ b/lib/validation.js
@@ -261,7 +261,7 @@ function wrapValidationError (result, dataVar, schemaErrorFormatter) {
  */
 function getEssenceMediaType (header) {
   if (!header) return ''
-  return header.split(';', 1)[0].trim().toLowerCase()
+  return header.split(/[ ;]/, 1)[0].trim().toLowerCase()
 }
 
 module.exports = {

Fix : The patch modifies the `getEssenceMediaType` function to correctly parse the 'Content-Type' header. It changes the split delimiter from just a semicolon to include both space and semicolon characters. This ensures that any leading space before the media type parameters is also considered a delimiter, preventing the validation bypass.

Advisory · Commit


GHSA-77fj-vx54-gvh7

HIGH 7.5 · 2026-04-14 · Go
github.com/gomarkdown/markdown · Pattern: BUFFER_OVERFLOW→HEAP · 7x across ecosystem

Root cause : The `smartLeftAngle` function in the SmartypantsRenderer processed text to find the closing angle bracket '>'. If no closing bracket was found, the loop would iterate until `i` equaled `len(text)`. Subsequently, `text[:i+1]` would attempt to access an index beyond the buffer's bounds, leading to an out-of-bounds read.

Impact : An attacker could provide specially crafted input that causes the application to crash due to an out-of-bounds read, leading to a denial of service. In some scenarios, this could potentially lead to information disclosure or arbitrary code execution, though the immediate impact is a crash.

Diff
--- a/html/smartypants.go
+++ b/html/smartypants.go
@@ -371,7 +371,10 @@ func (r *SPRenderer) smartLeftAngle(out *bytes.Buffer, previousChar byte, text [
 		i++
 	}
 
-	out.Write(text[:i+1])
+	if i == len(text) { // No > found until the end of the text
+		return i
+	}
+	out.Write(text[:i+1]) // include the '>'
 	return i
 }

Fix : The patch adds a check to ensure that `i` does not exceed `len(text)` before attempting to slice `text[:i+1]`. If `i` reaches `len(text)`, it means no closing angle bracket was found, and the function returns early to prevent the out-of-bounds access.

Advisory · Commit


GHSA-w5xj-99cg-rccm

HIGH 7.5 · 2026-04-14 · Ruby
decidim-core · Pattern: MISSING_AUTHZ→RESOURCE · 11x across ecosystem

Root cause : The application logic for handling amendments (accepting, rejecting, reacting, promoting) did not properly check the component's settings. Specifically, the `can_react_to_emendation?` and `allowed_to_promote?` methods in `AmendmentsHelper` lacked checks against the `amendment_reaction_enabled` and `amendment_promotion_enabled` component settings, respectively. This allowed any authenticated user to perform these actions regardless of the component's configuration.

Impact : An attacker could accept or reject amendments, react to them, or promote rejected amendments, even if the component's settings explicitly disabled these functionalities. This could lead to unauthorized manipulation of the amendment process and undermine the integrity of the platform's participatory features.

Diff
--- a/decidim-core/app/helpers/decidim/amendments_helper.rb
+++ b/decidim-core/app/helpers/decidim/amendments_helper.rb
@@ -41,7 +41,7 @@ def emendation_announcement_for(emendation)
     def can_react_to_emendation?(emendation)
       return unless current_user && emendation.emendation?
 
-      true
+      current_component.current_settings.amendment_reaction_enabled
     end
 
     # Checks if the user can accept and reject the emendation
@@ -54,18 +54,9 @@ def allowed_to_accept_and_reject?(emendation)
     # Checks if the user can promote the emendation
     def allowed_to_promote?(emendation)
       return unless emendation.amendment.rejected? && emendation.created_by?(current_user)
-      return if promoted?(emendation)
+      return if emendation.amendment.promoted?
 
-      true
-    end
-
-    # Checks if the unique ActionLog created in the promote command exists.
-    def promoted?(emendation)
-      logs = Decidim::ActionLog.where(decidim_component_id: emendation.component)
-                               .where(decidim_user_id: emendation.creator_author)
-                               .where(action: "promote")
-
-      logs.select { |log| log.extra["promoted_from"] == emendation.id }.present?
+      current_component.current_settings.amendment_promotion_enabled
     end
 
     # Renders a UserGroup select field in a form.

Fix : The patch introduces checks against the component's current settings for amendment-related actions. Specifically, `amend_button_for` now checks `amendment_creation_enabled`, `can_react_to_emendation?` checks `amendment_reaction_enabled`, and `allowed_to_promote?` checks `amendment_promotion_enabled`. This ensures that these actions are only possible when explicitly enabled in the component's configuration.

Advisory · Commit


GHSA-hwqh-2684-54fc

HIGH 7.5 · 2026-04-10 · Java
org.springframework.cloud:spring-cloud-gateway · Pattern: UNCLASSIFIED · 32x across ecosystem

Root cause : The original code did not properly validate the length of the SSL bundle string before checking if it exists in the bundles list.

Impact : An attacker could provide a maliciously crafted SSL bundle name that bypasses the validation, potentially leading to unauthorized access or other security issues.

Diff
Before:
- if (ssl.getSslBundle() == null || ssl.getSslBundle().length() > 0) {
-     return null;
}
After:
+ if (ssl.getSslBundle() != null && ssl.getSslBundle().length() > 0 && bundles.getBundleNames().contains(ssl.getSslBundle())) {

Fix : The patch ensures that the SSL bundle name is not empty and is present in the bundles list before returning it.

Advisory · Commit


GHSA-9hfr-gw99-8rhx

HIGH 7.5 · 2026-04-09 · Ruby
bsv-sdk · Pattern: MISSING_AUTHZ→RESOURCE · 11x across ecosystem

Root cause : The code did not properly handle responses indicating that a transaction was not accepted, leading to the treatment of INVALID/MALFORMED/ORPHAN responses as successful broadcasts.

Impact : An attacker could potentially treat invalid or malformed transactions as successful, allowing for unauthorized use of resources or manipulation of the system.

Diff
Before:
-      REJECTED_STATUSES = %w[REJECTED DOUBLE_SPEND_ATTEMPTED].freeze
After:
+      REJECTED_STATUSES = %w[
+        REJECTED
+        DOUBLE_SPEND_ATTEMPTED
+        INVALID
+        MALFORMED
+        MINED_IN_STALE_BLOCK
+      ].freeze

Fix : The patch adds support for additional rejected statuses and includes a substring match for orphan detection in txStatus or extraInfo fields. It also introduces optional parameters for deployment ID, callback URL, and callback token to enhance security.

Advisory · Commit


GHSA-mh2q-q3fh-2475

HIGH 7.5 · 2026-04-07 · Go
go.opentelemetry.io/otel/propagation · Pattern: UNCLASSIFIED · 32x across ecosystem

Root cause : The code did not properly limit the number of members or bytes in the baggage header, leading to excessive allocations and potential denial-of-service amplification.

Impact : An attacker could cause the application to allocate an excessive amount of memory by sending a large number of small baggage headers. This could lead to resource exhaustion and potentially crash the application.

Diff
Before:
- maxMembers = 180
- maxBytesPerMembers = 4096
After:
+ maxMembers = 64

Fix : The patch limits the maximum number of members in the baggage header to 64, reducing the risk of excessive allocations and potential denial-of-service amplification.

Advisory · Commit


GHSA-3p65-76g6-3w7r

HIGH 7.5 · 2026-04-06 · Go
github.com/distribution/distribution · Pattern: SSRF→INTERNAL_ACCESS · 15x across ecosystem

Root cause : The code did not validate the 'realm' parameter in the 'WWW-Authenticate' header, allowing attackers to perform SSRF attacks by manipulating the realm value.

Impact : An attacker could use this vulnerability to access internal resources or services that are not supposed to be accessible from outside the network.

Diff
Before:
	if strings.EqualFold(c.Scheme, "bearer") {
After:
	if strings.EqualFold(c.Scheme, "bearer") && realmAllowed(remote, c.Parameters["realm"]) {

Fix : The patch introduces a function `realmAllowed` that checks if the 'realm' parameter is allowed based on the remote URL, preventing attackers from manipulating the realm value for SSRF attacks.

Advisory · Commit


GHSA-f2g3-hh2r-cwgc

HIGH 7.5 · 2026-04-06 · Go
github.com/distribution/distribution · Pattern: UNCLASSIFIED · 32x across ecosystem

Root cause : The code did not properly validate or sanitize input when interacting with the Redis cache.

Impact : An attacker could potentially manipulate the Redis cache to access stale blob data, leading to unauthorized access or data corruption.

Diff
Before:
- member, err := rsrbds.upstream.pool.SIsMember(ctx, rsrbds.repositoryBlobSetKey(rsrbds.repo), dgst.String()).Result()
After:
+ pool := rsrbds.upstream.pool
+ member, err := pool.SIsMember(ctx, rsrbds.repositoryBlobSetKey(rsrbds.repo), dgst.String()).Result()

Fix : The patch ensures that the Redis pool is used consistently and correctly for all operations, preventing potential misuse of the cache.

Advisory · Commit


GHSA-h6rj-3m53-887h

HIGH 7.5 · 2026-04-06 · PHP
pocketmine/pocketmine-mp · Pattern: UNCLASSIFIED · 32x across ecosystem

Root cause : The code directly logs the value of an unknown property without sanitizing it.

Impact : An attacker could potentially log sensitive information or cause a denial of service by crafting a malicious packet with large complex properties.

Diff
Before:
- var_export($value, return: true)
After:
+ Utils::printable(substr($name, 0, 80))

Fix : The patch uses a utility function to print only a portion of the property name, preventing potential log injection and excessive logging.

Advisory · Commit


GHSA-hv3w-m4g2-5x77

HIGH 7.5 · 2026-04-06 · Python
strawberry-graphql · Pattern: DOS→RESOURCE_EXHAUSTION · 5x across ecosystem

Root cause : The code did not limit the number of WebSocket subscriptions per connection, allowing an attacker to create an unbounded number of subscriptions.

Impact : An attacker could cause a denial of service by establishing an excessive number of WebSocket connections and subscriptions, exhausting server resources.

Diff
Added `max_subscriptions_per_connection: int | None = None` in the constructor.

Added check `if not self.connection_acknowledged:` before handling a subscription to ensure the connection is authorized.

Added logic to clean up existing operations with the same ID to prevent task leaks.

Fix : The patch introduces a `max_subscriptions_per_connection` parameter to limit the number of subscriptions per connection, preventing resource exhaustion.

Advisory · Commit


GHSA-vpwc-v33q-mq89

HIGH 7.5 · 2026-04-06 · Python
strawberry-graphql · Pattern: UNCLASSIFIED · 32x across ecosystem

Root cause : The patch adds a new parameter `max_subscriptions_per_connection` but does not enforce any authentication or authorization checks.

Impact : An attacker could bypass the authentication mechanism and establish multiple subscriptions on a single connection, potentially leading to resource exhaustion or other unauthorized access issues.

Diff
diff --git a/strawberry/subscriptions/protocols/graphql_ws/handlers.py b/strawberry/subscriptions/protocols/graphql_ws/handlers.py
index 21979ff23d..e0bbc18052 100644
--- a/strawberry/subscriptions/protocols/graphql_ws/handlers.py
+++ b/strawberry/subscriptions/protocols/graphql_ws/handlers.py
@@ -119,6 +122,8 @@ async def handle_connection_init(self, message: ConnectionInitMessage) -> None:
                 {

Fix : The patch should include proper authentication and authorization checks to ensure that only authenticated users can initiate connections and handle subscriptions.

Advisory · Commit


GHSA-8jvc-mcx6-r4cg

HIGH 7.4 · 2026-04-10 · Go
code.vikunja.io/api · Pattern: UNCLASSIFIED · 32x across ecosystem

Root cause : The OIDC login path did not enforce TOTP Two-Factor Authentication for all users, allowing bypass of the authentication mechanism.

Impact : An attacker could log in to the system without providing a valid TOTP passcode, potentially gaining unauthorized access to user accounts.

Diff
Before:
- <Message v-if="loading">
+ <Message v-if="loading && !needsTotp">

After:
+ <form
+   v-if="needsTotp"
+   @submit.prevent="submitTotpAndRestart"
+ >
+   <FormField
+     id="openIdTotpPasscode"
+     ref="totpInput"
+     v-model="totpPasscode"
+     v-focus
+     :label="$t('user.auth.totpTitle')"
+     autocomplete="one-time-code"
+     :placeholder="$t('user.auth.totpPlaceholder')"
+     required
+     type="text"
+     inputmode="numeric"
+   />
+   <XButton
+     :loading="loading"
+     :disabled="!totpPasscode"
+     class="mbs-2"
+     @click="submitTotpAndRestart"
+   >
+     {{ $t('user.auth.openIdTotpSubmit') }}
+   </XButton>
+ </form>

Fix : The patch adds a form that requires users to provide a TOTP passcode before being authenticated via OIDC. This ensures that TOTP Two-Factor Authentication is enforced for all users attempting to log in through the OIDC path.

Advisory · Commit


GHSA-jfwg-rxf3-p7r9

HIGH 7.3 · 2026-04-06 · Go
github.com/authorizerdev/authorizer · Pattern: UNSANITIZED_INPUT→NOSQL · 1x across ecosystem

Root cause : The code uses `fmt.Sprintf` for string interpolation to construct SQL queries, which can lead to CQL/N1QL injection if user input is not properly sanitized.

Impact : An attacker could execute arbitrary CQL/N1QL commands on the database, potentially leading to data theft, unauthorized access, or other malicious activities.

Diff
Before:
values := fmt.Sprintf("'%s',", value.(string))

After:
placeholders += "?,"
insertValues = append(insertValues, value)

Fix : The patch converts map values to appropriate types and uses parameterized queries with placeholders to prevent SQL injection.

Advisory · Commit


GHSA-ff5q-cc22-fgp4

HIGH 7.1 · 2026-04-14 · PHP
wwbn/avideo · Pattern: CORS_MISCONFIGURATION→ORIGIN · 2x across ecosystem

Root cause : The application reflected the `HTTP_ORIGIN` header directly into the `Access-Control-Allow-Origin` header for all API requests, including authenticated ones. This allowed an attacker to bypass the Same-Origin Policy.

Impact : An attacker could make authenticated cross-origin requests to the API from a malicious domain, potentially accessing sensitive user data or performing actions on behalf of the victim, despite the browser's Same-Origin Policy.

Diff
--- plugin/API/router.php
+++ plugin/API/router.php
-    header("Access-Control-Allow-Origin: " . $HTTP_ORIGIN);
-header("Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS, HEAD");
-header("Access-Control-Allow-Headers: Content-Type, Authorization, X-Requested-With, ua-resolution, APISecret, Origin, Accept, Access-Control-Request-Method, Access-Control-Request-Headers");
-header('Access-Control-Allow-Private-Network: true');
+
+// CORS preflight handling.
+// OPTIONS preflights are cross-origin by definition (same-origin requests are never
+// preflighted by browsers). Returning Access-Control-Allow-Origin: * without
+// Access-Control-Allow-Credentials is safe:
+//   - External API clients using APISecret (non-credentialed) proceed normally.
+//   - Credentialed attacker requests are blocked: the browser sees no
+//     Allow-Credentials:true in the preflight and aborts the actual request,
+//     so session cookies are never sent.
+// Actual GET/POST responses are handled by allowOrigin(true) in get/set.json.php
+// which enforces same-origin-only credentials (fixed in commit 986e64aad).
 if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
-    header("Access-Control-Max-Age: 86400"); // Cache preflight for 24 hours
-    http_response_code(200);
+    header('Access-Control-Allow-Origin: *');
+    header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS, HEAD');
+    header('Access-Control-Allow-Headers: Content-Type, Authorization, X-Requested-With, ua-resolution, APISecret, Origin, Accept, Access-Control-Request-Method, Access-Control-Request-Headers');
+    header('Access-Control-Allow-Private-Network: true');
+    header('Access-Control-Max-Age: 86400');
+    http_response_code(204);
     exit;
 }

Fix : The patch removes the dynamic reflection of the `HTTP_ORIGIN` header for all requests. For preflight OPTIONS requests, it now explicitly sets `Access-Control-Allow-Origin: *` without `Access-Control-Allow-Credentials`, which is safe. The handling of actual GET/POST responses for credentialed requests is deferred to `allowOrigin(true)` in other files, which is expected to enforce same-origin-only credentials.

Advisory · Commit


GHSA-ffw8-fwxp-h64w

HIGH 7.1 · 2026-04-14 · PHP
wwbn/avideo · Pattern: CSRF→STATE_CHANGE · 2x across ecosystem

Root cause : The application's administrative JSON endpoints lacked proper CSRF protection. This allowed an attacker to craft malicious requests that, when executed by an authenticated administrator, would perform actions without the administrator's explicit consent.

Impact : An attacker could trick an authenticated administrator into performing unintended actions, such as adding new categories, clearing cache, refreshing videos, or swapping videos, by simply visiting a malicious webpage.

Diff
--- a/objects/categoryAddNew.json.php
+++ b/objects/categoryAddNew.json.php
@@ -19,6 +19,7 @@
     $obj->msg = __("Permission denied");
     die(json_encode($obj));
 }
+forbidIfIsUntrustedRequest('categoryAddNew');
 
 $objCat = new Category(intval(@$_POST['id']));
 $objCat->setName($_POST['name']);

Fix : The patch introduces a call to `forbidIfIsUntrustedRequest()` at the beginning of several administrative JSON endpoints. This function likely implements a CSRF token check or similar mechanism to ensure that requests originate from trusted sources and are not forged.

Advisory · Commit


GHSA-pg8g-f2hf-x82m

HIGH 6.5 · 2026-04-09 · JavaScript
openclaw · Pattern: SSRF→INTERNAL_ACCESS · 15x across ecosystem

Root cause : The original code did not properly sanitize or validate the request body before sending it across cross-origin redirects.

Impact : An attacker could exploit this vulnerability to perform SSRF attacks, potentially gaining access to internal resources or leaking sensitive information.

Diff
Before:
-      const pinned = await resolvePinnedHostnameWithPolicy(parsedUrl.hostname, {
-        lookupFn: params.lookupFn,
-        policy: params.policy,
-      });
After:
+        const pinned = await resolvePinnedHostnameWithPolicy(parsedUrl.hostname, {
+          lookupFn: params.lookupFn,
+          policy: params.policy,
+        });

Fix : The patch ensures that the request body is sanitized and validated before being sent across cross-origin redirects, mitigating the risk of SSRF vulnerabilities.

Advisory · Commit


GHSA-4x48-cgf9-q33f

HIGH 0.0 · 2026-04-14 · JavaScript
@novu/api · Pattern: SSRF→INTERNAL_ACCESS · 15x across ecosystem

Root cause : The application allowed users to specify webhook URLs in conditions filters. While a `validateUrlSsrf()` function existed, it was not being called for webhook URLs within the conditions filter logic, allowing an attacker to bypass existing SSRF protection and make requests to internal resources.

Impact : An attacker could craft a malicious webhook URL to make the server-side application send requests to internal network resources, potentially accessing sensitive data, internal services, or cloud metadata endpoints.

Diff
--- a/libs/application-generic/src/usecases/conditions-filter/conditions-filter.usecase.ts
+++ b/libs/application-generic/src/usecases/conditions-filter/conditions-filter.usecase.ts
@@ -257,6 +264,17 @@ export class ConditionsFilter extends Filter {
       config.headers['nv-hmac-256'] = hmac;
     }
 
+    const ssrfError = await validateUrlSsrf(child.webhookUrl);
+
+    if (ssrfError) {
+      throw new Error(
+        JSON.stringify({
+          message: ssrfError,
+          data: 'Webhook URL blocked by SSRF protection.',
+        })
+      );
+    }
+
     try {
       return await axios.post(child.webhookUrl, payload, config).then((response) => {

Fix : The `validateUrlSsrf()` function was moved to a shared utility library and is now explicitly called to validate webhook URLs within the `ConditionsFilter` use case before any HTTP request is made. Additionally, the `isPrivateIp` function was updated to include `0.0.0.0` and IPv6 mapped IPv4 private ranges for more comprehensive protection.

Advisory · Commit


GHSA-hv4r-mvr4-25vw

HIGH 0.0 · 2026-04-14 · Go
github.com/minio/minio · Pattern: MISSING_AUTH→ENDPOINT · 7x across ecosystem

Root cause : The vulnerability stemmed from a bypass in the query-string credential signature validation for unsigned-trailer uploads. MinIO failed to properly authenticate requests when specific conditions related to unsigned trailers were met, allowing an attacker to write objects without valid credentials.

Impact : An unauthenticated attacker could upload arbitrary objects to MinIO, potentially leading to data compromise, unauthorized data storage, or denial of service by filling up storage space.

Diff
--- a/cmd/apierrorcode_string.go
+++ b/cmd/apierrorcode_string.go
@@ -131,197 +131,198 @@ func _() {
 	_ = x[ErrInvalidTagDirective-120]
 	_ = x[ErrPolicyAlreadyAttached-121]
 	_ = x[ErrPolicyNotAttached-122]
-	_ = x[ErrInvalidEncryptionMethod-123]
+	_ = x[ErrExcessData-123]
 	_ = x[ErrInvalidEncryptionKeyID-124]
 	_ = x[ErrInsecureSSECustomerRequest-125]

Fix : The patch introduces a new error code, `ErrExcessData`, and re-indexes subsequent error codes. While this specific diff doesn't show the direct fix logic, it indicates a change in error handling, likely related to how MinIO processes and validates request data, including headers and trailers, to prevent the signature bypass.

Advisory · Commit


GHSA-pm7q-rjjx-979p

HIGH 0.0 · 2026-04-14 · Go
github.com/oxia-db/oxia · Pattern: CREDENTIAL_LEAK→LOG_EXPOSURE · 2x across ecosystem

Root cause : The application was logging the full bearer token in debug messages when an authentication failure occurred. This meant that if debug logging was enabled, the sensitive authentication token could be exposed in logs, making it accessible to anyone with access to the log files.

Impact : An attacker with access to the system's log files could retrieve full bearer tokens, potentially allowing them to impersonate users or gain unauthorized access to the system.

Diff
--- a/oxiad/common/rpc/auth/interceptor.go
+++ b/oxiad/common/rpc/auth/interceptor.go
@@ -98,8 +98,21 @@ func validateTokenWithContext(ctx context.Context, provider AuthenticationProvid
 	if userName, err = provider.Authenticate(ctx, token); err != nil {
 		slog.Debug("Failed to authenticate token",
 			slog.String("peer", peerMeta.Addr.String()),
-			slog.String("token", token))
+			slog.String("token", redactToken(token)))
 		return "", err
 	}
 	return userName, nil
 }
+
+// redactToken returns a redacted version of a token for safe logging.
+// For tokens longer than 8 characters, at most the last 8 characters are
+// preserved and the rest is replaced with "[REDACTED]". Tokens of 8 characters
+// or fewer are fully redacted to "[REDACTED]".
+func redactToken(token string) string {
+	const suffixLen = 8
+	const prefix = "[REDACTED]"
+	if len(token) <= suffixLen {
+		return prefix
+	}
+	return prefix + token[len(token)-suffixLen:]
+}

Fix : The patch introduces a `redactToken` function that masks the bearer token before it is logged. Instead of logging the full token, it now logs a redacted version, preserving only the last 8 characters for longer tokens and fully redacting shorter ones, prefixed with "[REDACTED]".

Advisory · Commit


GHSA-pq8p-wc4f-vg7j

HIGH 0.0 · 2026-04-14 · PHP
wwbn/avideo · Pattern: MISSING_AUTH→ENDPOINT · 7x across ecosystem

Root cause : The application previously had a command injection vulnerability (CVE-2026-33502) in the `wget` function, which was used to fetch content from a URL provided by user input. The original fix was incomplete, as it did not restrict access to the `test.php` endpoint, allowing unauthenticated attackers to still trigger the vulnerable `wget` function.

Impact : An unauthenticated attacker could execute arbitrary commands on the server by manipulating the `statsURL` parameter, leading to full system compromise.

Diff
--- a/plugin/Live/test.php
+++ b/plugin/Live/test.php
@@ -1,3 +1,8 @@
 <?php
+
+require_once dirname(__FILE__) . '/../../videos/configuration.php';
+
+if (!User::isAdmin()) {
+    http_response_code(403);
+    exit('Forbidden');
+}
 
 $timeStarted = microtime(true);

Fix : The patch introduces an authentication check at the beginning of the `test.php` file, requiring the user to be an administrator. If the user is not an admin, access is denied with a 403 Forbidden status code.

Advisory · Commit


GHSA-r2pg-r6h7-crf3

HIGH 0.0 · 2026-04-13 · Go
github.com/external-secrets/external-secrets · Pattern: SSRF→INTERNAL_ACCESS · 15x across ecosystem

Root cause : The External Secrets Operator's v2 template engine included the `getHostByName` function from the Sprig library. This function allowed templates to perform DNS lookups, which could be abused to exfiltrate sensitive information (secrets) by encoding them into DNS queries to an attacker-controlled domain.

Impact : An attacker with control over the template content could exfiltrate secrets stored in the External Secrets Operator by encoding them into DNS queries and sending them to a domain they control.

Diff
--- a/runtime/template/v2/template.go
+++ b/runtime/template/v2/template.go
@@ -87,7 +87,7 @@ func init() {
 	sprigFuncs := sprig.TxtFuncMap()
 	delete(sprigFuncs, "env")
 	delete(sprigFuncs, "expandenv")
-
+	delete(sprigFuncs, "getHostByName")
 	maps.Copy(tplFuncs, sprigFuncs)

Fix : The patch removes the `getHostByName` function from the list of available functions in the v2 template engine. This prevents templates from performing DNS lookups, thereby mitigating the risk of DNS-based secret exfiltration.

Advisory · Commit


GHSA-whj4-6x5x-4v2j

HIGH 0.0 · 2026-04-13 · Python
pillow · Pattern: DOS→RESOURCE_EXHAUSTION · 5x across ecosystem

Root cause : The application used `gzip.decompress` on the entire input stream without any size limits. An attacker could craft a compressed FITS file that, when decompressed, expands to an extremely large size, consuming excessive memory and CPU resources.

Impact : An attacker could cause a denial of service by providing a specially crafted FITS GZIP file, leading to resource exhaustion (memory and CPU) and potentially crashing the application or making it unresponsive.

Diff
--- a/src/PIL/FitsImagePlugin.py
+++ b/src/PIL/FitsImagePlugin.py
@@ -128,8 +128,9 @@ class FitsGzipDecoder(ImageFile.PyDecoder):
 
     def decode(self, buffer: bytes | Image.SupportsArrayInterface) -> tuple[int, int]:
         assert self.fd is not None
-        value = gzip.decompress(self.fd.read())
-
-        rows = []
-        offset = 0
-        number_of_bits = min(self.args[0] // 8, 4)
-        for y in range(self.state.ysize):
-            row = bytearray()
-            for x in range(self.state.xsize):
-                row += value[offset + (4 - number_of_bits) : offset + 4]
-                offset += 4
-            rows.append(row)
+        with gzip.open(self.fd) as fp:
+            value = fp.read(self.state.xsize * self.state.ysize * 4)
+
+            rows = []
+            offset = 0
+            number_of_bits = min(self.args[0] // 8, 4)
+            for y in range(self.state.ysize):
+                row = bytearray()
+                for x in range(self.state.xsize):
+                    row += value[offset + (4 - number_of_bits) : offset + 4]
+                    offset += 4
+                rows.append(row)

Fix : The patch replaces `gzip.decompress(self.fd.read())` with `gzip.open(self.fd) as fp: value = fp.read(self.state.xsize * self.state.ysize * 4)`. This change limits the amount of data read from the decompressed stream to a size calculated based on the image dimensions, preventing excessive memory allocation.

Advisory · Commit


GHSA-q5jf-9vfq-h4h7

HIGH 0.0 · 2026-04-10 · Go
helm.sh/helm/v4 · Pattern: MISSING_VERIFICATION→SIGNATURE · 5x across ecosystem

Root cause : The plugin installation process did not check for the presence of a .prov file, allowing unsigned plugins to be installed without verification.

Impact : An attacker could install and execute unsigned plugins, potentially gaining unauthorized access or executing malicious code on the system.

Diff
Before:
- fmt.Fprintf(os.Stderr, "WARNING: No provenance file found for plugin. Plugin is not signed and cannot be verified.\n")
After:
+ return nil, fmt.Errorf("plugin verification failed: no provenance file (.prov) found")

Fix : The patch ensures that an error is returned if no .prov file is found during plugin installation, preventing the installation of unsigned plugins.

Advisory · Commit


How it works

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 34 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
ComponentTechNotes
AutomationGitHub Actions cronZero infra
Data sourceGitHub Advisory DBGraphQL, filtered on patch commits
LLMGemini 2.5 FlashFree tier, JSON-only output
DBSQLite rebuilt from JSONLGit-friendly, versioned
FrontendStatic HTMLClient-side search, zero build step
ScriptingPython 3.11requests, jinja2, sqlite3
Stats
MetricValue
Total advisories165
Unique patterns34
Pending0
Last updated2026-04-16

christbowel.com

About

Automated patch intelligence - tracks what gets fixed in open source daily, extracts vulnerability patterns, and detects recurring antipatterns across languages and ecosystems. Powered by GitHub Advisory DB + Gemini.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages

  • Python 76.0%
  • Jinja 24.0%