A control-panel user who holds only the viewCategories permission for a category group (and not saveCategories) can permanently modify that group's category structure — reordering and re-parenting categories via the structures/move-element action. A read-time authorization grant that a write endpoint later trusts. For categories, the structureEditable flag is computed from the view permission (`src/elements/Category.php:205`) instead of the save permission (entries correctly use saveEntries — `
`ChartsController::actionGetNewUsersData()` at `/actions/charts/get-new-users-data` is missing a `requirePermission('viewUsers')` authorization check. Any authenticated control panel user, regardless of permissions beyond `accessCp`, can POST to this endpoint to receive time-series user registration counts for the entire site or for an arbitrary user group ID. The `viewUsers` permission is consistently required throughout the control panel before exposing user-related data, but this action enfo
The `ensurePathIsContained` function of the `Local` file system class is theoretically vulnerable to path traversal, although no exploitable scenario has been discovered. When a file is read, an `Asset` object uses the `getFileStream` method of the `Volume` where the asset file is stored, which in turn uses the `getFileStream` method of the file system class used by that `Volume`. For the `Local` file system, this function returns a stream to a file on the local disk after verifying and creatin
The control-panel helper that renders element chip/card labels writes an element's `draftName` into the page without HTML-encoding it, while the surrounding path segments are encoded. A low-privilege control-panel user who can create a draft of an element (for example, an entry) controls the draft name, so they can store an XSS payload that executes in the browser of any other control-panel user who is shown that element’s chip or card (element indexes with drafts visible, relation and element-
ngx-extended-pdf-viewer embeds a fork of Mozilla's pdf.js rather than depending on pdfjs-dist, so this vulnerability is not visible to dependency scanners through package.json. ### Impact Opening a malicious PDF can execute attacker-controlled JavaScript in the context of the hosting page. Upstream advisory: GHSA-hq66-cqwq-w95j / CVE-2026-16633. ### Exposure. The sandbox half of the issue requires enableScripting, which pdf.js enables by default but this library does not — so the default conf
### Impact If PDF.js is used to load a malicious PDF, and PDF.js is configured with `enableScripting` set to true (which is the default value) and no CSP for disallowing script-src, unrestricted attacker-controlled JavaScript will be executed in the context of the hosting domain. ### Patches ### Workarounds Set `enableScripting` to `false` or set a CSP.
The vulnerability allows any authenticated user to change their own password without providing the current password or having an active elevated session. It also allows the attacker to change other users’ passwords if the attacker’s account has `edit users` permission (which doesn’t allow changing others’ passwords) and lacks `Administrate users` permission (which is required to change others’ passwords). The vulnerability exists in the `elements/save` action when saving a User element. The `Us
The Twig sandbox mechanism in Craft CMS is configured to allow dangerous functionality from the Yii framework, leading to authenticated RCE in a manner similar to previously disclosed vulnerabilities. The Twig sandbox in Craft CMS works by implementing Twig's `SecurityPolicyInterface`. The resulting `SecurityPolicy` class implements the `checkMethodAllowed` and `checkPropertyAllowed` methods of the interface. The implementations compare whether the called method or property is in a configured a
Craft CMS has an authenticated remote code execution issue in the control panel element-search condition handling. Craft cleans the outer request-controlled condition array with `Component::cleanseConfig()`, but `Conditions::createCondition()` later decodes and merges the JSON string in `condition.config` without re-running `cleanseConfig()` on the decoded/merged configuration. Because `condition.config` is a JSON string during the first cleanse, Yii special config keys such as `as` ... and `o
### Impact `XmlRenderer` pretty-prints XML by emitting depth-proportional indentation whitespace for **every** opening and closing tag. For a tree of depth n, the indentation alone sums to **O(n²)** bytes of output (and corresponding memory), reachable through `MarkdownToXmlConverter` — e.g. `str_repeat('> ', $depth) . "x\n"`, a single line of nested blockquotes — or through a direct `XmlRenderer::renderDocument()` call on an attacker-influenced AST. This affects applications that convert untr
### Impact `UniqueSlugNormalizer::normalize()` makes each slug document-unique by searching for an unused numeric suffix, but **restarts that search from `1` on every collision**. The k-th heading that collapses to the same base slug performs k−1 array lookups, so K colliding slugs cost Σ(k−1) = **O(K²)**. An attacker can force every heading onto a single base slug trivially — many empty ATX headings, identical heading text, or punctuation-only headings that normalize to the empty string. The
### Impact The Footnote extension records one backref per footnote *reference* and then appends the **entire** backref list for **every** footnote *definition* block in the document, without ever de-duplicating or removing repeated definitions of the same label (`GatherFootnotesListener`, populated by `NumberFootnotesListener`). A document that references a single label N times and also supplies N duplicate `[^a]:` definitions of that label therefore produces **N × N** `FootnoteBackref` nodes,
### Impact With the Attributes extension enabled, `AttributesListener::findTargetAndDirection()` resolves each attribute node's target by walking outward through its siblings. For a run of N adjacent inline attribute blocks placed at the start of a block (with nothing to their left), each node scans the **entire** sibling list to the far-right end before giving up and falling back to the parent. Each resolution is therefore Θ(N) and the whole run is **Θ(N²)**. Reaching the path requires `Attri
Netty is an asynchronous, event-driven network application framework. Prior to versions 4.1.136.Final and 4.2.16.Final, ab attacker can force WebSocket upgrade via the lax V07 (or V08) handshaker by sending `Sec-WebSocket-Version: 7` and omitting `Connection: Upgrade` / `Upgrade: websocket` headers, completing a protocol switch that a proxy would not recognize as an Upgrade request and enabling HTTP request smuggling / protocol-confusion attacks. This issue has been fixed in versions 4.1.136.Fi
Netty is an asynchronous, event-driven network application framework. In versions prior to 4.1.136.Final and 4.2.16.Final, Netty's STOMP encoder ( StompSubframeEncoder ) does not escape or validate header values in CONNECT and CONNECTED frames, so raw newline ( \n ) characters in a header value are written directly to the wire, allowing an attacker who controls a header value to inject additional STOMP headers. This happens because the encoder intentionally skips escaping for CONNECT/CONNECT
Netty is an asynchronous, event-driven network application framework. In versions prior to 4.1.136.Final and 4.2.16.Final, Netty's HAProxy encoder ( HAProxyMessageEncoder ) writes AF_UNIX source and destination socket addresses into the HAProxy V1 text protocol without validating them for CRLF characters, so an attacker who controls an AF_UNIX address can inject \r\n sequences and split the single PROXY header into multiple lines. This is possible because the V1 protocol uses CRLF as its line
Netty is an asynchronous, event-driven network application framework. Prior to versions 4.1.136.Final and 4.2.16.Final, the `Bzip2Decoder` handler in Netty's compression codec pipeline is vulnerable to a denial-of-service attack through a malformed bzip2 stream that permanently captures the event-loop thread in an infinite loop. The vulnerability exists in the run-length encoding (RLE) state machine within [`Bzip2BlockDecompressor.read()`]. This issue has been fixed in versions 4.1.136.Final and
Netty is an asynchronous, event-driven network application framework. Prior to versions 4.1.136.Final and 4.2.16.Final, Netty's HTTP/2-to-HTTP/1.x translation layer (`Http2StreamFrameToHttpObjectCodec` and `InboundHttp2ToHttpAdapter`) fails to deduplicate or validate `Host` headers when an HTTP/2 client supplies both the `:authority` pseudo-header and a literal `host` header in a single HEADERS frame. The translator maps `:authority` to `Host` and separately copies the literal `host` header, pro
# Quadratic CPU consumption in `!!omap` resolution (js-yaml 3.x and 4.x) ## Summary `resolveYamlOmap()` enforces key uniqueness for `!!omap` sequences with a linear scan (`objectKeys.indexOf(...)`) inside the per-element loop, making resolution **O(n²)** in the number of entries. A modestly sized YAML document therefore consumes disproportionate CPU inside `yaml.load()`, giving a denial of service against any consumer that parses untrusted YAML. `!!omap` is registered in the **default schema*
Netty is an asynchronous, event-driven network application framework. Prior to versions 4.1.136.Final and 4.2.16.Final, `HttpContentEncoder` (the superclass of the production handler `HttpContentCompressor`) maintains a per-channel `ArrayDeque<CharSequence>` named `acceptEncodingQueue` that accumulates attacker-controlled data without any size limit. The queue is filled on the I/O thread for every inbound HTTP request and drained only when the application later writes a non-1xx response. This cr