Common Weakness Enumeration

CWE-73

Allowed

External Control of File Name or Path

Abstraction: Base · Status: Draft

The product allows user input to control or influence paths or file names that are used in filesystem operations.

1266 vulnerabilities reference this CWE, most recent first.

GHSA-8757-69J2-HX56

Vulnerability from github – Published: 2026-05-05 21:16 – Updated: 2026-06-05 14:31
VLAI
Summary
changedetection.io has an Arbitrary Local File Read via a crafted backup restore
Details

Details

The vulnerability is caused by trusting attacker-controlled snapshot paths restored from backup files.

The vulnerable flow starts in the backup restore logic. When a backup ZIP is restored, the application extracts the archive and copies each restored watch UUID directory directly into the live datastore using shutil.copytree(entry.path, dst_dir). This preserves attacker-controlled files inside the restored watch directory, including history.txt.

Relevant code: - changedetectionio/blueprint/backups/restore.py - changedetectionio/blueprint/backups/restore.py

After restore, the application parses history.txt in the watch history property. This is the core trust-boundary issue.

Relevant code: - changedetectionio/model/Watch.py - changedetectionio/model/Watch.py - changedetectionio/model/Watch.py

The relevant logic is effectively:

if os.sep not in v and '/' not in v and '\\' not in v:
    v = os.path.join(self.data_dir, v)
else:
    snapshot_fname = os.path.basename(v)
    proposed_new_path = os.path.join(self.data_dir, snapshot_fname)
    if not os.path.exists(v) and os.path.exists(proposed_new_path):
        v = proposed_new_path

This has the following security consequence:

  • If the history.txt value is only a filename, it is resolved safely under self.data_dir.
  • If the value contains path separators, it is treated as a path reference rather than a watch-local snapshot name.
  • If that external path already exists, it is preserved unchanged.

As a result, a malicious restored history.txt entry such as:

1776969105,/etc/passwd

will be accepted if the referenced file exists and is readable by the application process.

The second vulnerable step is in get_history_snapshot(). Once the untrusted path has been accepted into the watch history, the application reads the resolved path directly without enforcing that it remains inside the watch directory.

Relevant code: - changedetectionio/model/Watch.py

That function eventually performs direct file reads such as:

with open(filepath, 'r', encoding='utf-8', errors='ignore') as f:
    return f.read()

The third step is reachability. The trusted history entry is consumed by both the Preview UI and the watch history API.

Relevant code: - changedetectionio/blueprint/ui/preview.py - changedetectionio/api/Watch.py

In the Preview flow, the application selects the latest history timestamp and calls:

content = watch.get_history_snapshot(timestamp=timestamp)

In the API flow, the application also calls:

content = watch.get_history_snapshot(timestamp=timestamp)

This creates the following end-to-end exploit chain:

  1. An attacker supplies a crafted backup ZIP.
  2. The restore process preserves attacker-controlled history.txt.
  3. The history.txt parser accepts an absolute or out-of-directory path if that path exists.
  4. Preview or the history API dereferences the stored path directly.
  5. The application returns the contents of the targeted local file.

The root cause is that imported history entries are treated as trusted filesystem paths instead of being restricted to safe basenames under watch.data_dir.

PoC

The following proof of concept demonstrates the end-to-end exploit chain. It assumes the attacker has gained access to the backup restore functionality to upload the crafted archive.

  1. Create a normal watch in the UI, for example:
https://example.com
  1. Trigger at least one successful check so the watch generates a valid history entry and can later be included in a backup.

image

  1. Go to the Backups section and create a backup archive.

image

  1. Extract the backup archive and identify the watch UUID directory that contains the target watch's watch.json. For example:
5db3d3d8-71e6-4db2-a81e-e1f0445c3e47
  1. Open that watch directory and edit history.txt.

  2. Replace the latest history entry with a path to an existing local file that is readable by the application process. For example:

1776969188,/etc/passwd

If the timestamp differs in the extracted backup, keep the original latest timestamp and only replace the filename/path portion.

Example:

1776969188,742215043ff9be7e635f05e680ff9b11.txt

becomes:

1776969188,/etc/passwd

image

  1. Repack the backup so that the UUID directories are located at the root of the ZIP archive.

Important: - Do not add an extra parent directory layer when repacking. - The archive root should contain directories such as:

<watch-uuid>/
<group-uuid>/
changedetection.json
url-list.txt

image

  1. In the UI, restore the modified backup and enable replacement of existing watches with the same UUID.

image

  1. After restore completes, open Preview for the restored watch.

  2. The application will read the attacker-controlled path from history.txt and display the contents of the referenced local file instead of the original watch snapshot.

Observed result: - The Preview page returns the content of the attacker-selected local file.

Expected result: - The application should reject absolute paths or out-of-directory paths restored from history.txt. - Snapshot history should be restricted to files within the watch's own data directory.

Optional API verification: - The same issue can also be confirmed through the watch history API by requesting the modified timestamp after restore. - The API returns the same file content because it also calls watch.get_history_snapshot(timestamp=timestamp) on the trusted history entry.

image

Impact

This is an arbitrary local file disclosure vulnerability reachable through malicious backup restore content.

Who is impacted: - Deployments where the application process has read access to sensitive local system files. - Docker or host-mounted environments where secrets, config files, or operational artifacts are explicitly readable by the service.

What can be exposed: - Arbitrary System Files: Core operating system files (e.g., /etc/passwd, /proc/self/environ), system-level configurations, and host metrics. - Application Data: Internal records and files residing under the /datastore directory. - Secrets & Artifacts: Application-local configuration files, API tokens, database credentials, and other sensitive artifacts accessible to the application process.

By accessing the backup restore functionality and importing a crafted archive, an attacker can exploit the application's fail-open path validation. The confidentiality impact is exceptionally high because, once the payload is ingested, the application can be manipulated to disclose arbitrary local system files and highly sensitive environment variables directly through standard UI or API responses.

Recommendation

The application should treat all paths restored from history.txt as untrusted input.

The root cause is in changedetectionio/model/Watch.py, where values containing path separators are currently accepted as filesystem paths and preserved if the referenced file already exists.

The fix should be:

  1. Never trust absolute or external paths from history.txt.
  2. Normalize every history entry to os.path.basename(v).
  3. Join the normalized filename to self.data_dir.
  4. Skip the entry if the resolved file does not exist inside the watch directory.

Suggested code change:

snapshot_fname = os.path.basename(v.strip())
resolved_path = os.path.join(self.data_dir, snapshot_fname)

if not os.path.exists(resolved_path):
    logger.warning(
        f"Skipping unsafe or missing history entry for {self.get('uuid')}: {v!r}"
    )
    continue

tmp_history[k] = resolved_path

This ensures restored history entries can only reference files inside the watch's own data directory and prevents arbitrary local file reads through Preview or the history API.

Show details on source website

{
  "affected": [
    {
      "database_specific": {
        "last_known_affected_version_range": "\u003c= 0.54.10"
      },
      "package": {
        "ecosystem": "PyPI",
        "name": "changedetection.io"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "0.55.1"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-43891"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-73"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-05-05T21:16:21Z",
    "nvd_published_at": "2026-05-12T18:17:28Z",
    "severity": "HIGH"
  },
  "details": "### Details\nThe vulnerability is caused by trusting attacker-controlled snapshot paths restored from backup files.\n\nThe vulnerable flow starts in the backup restore logic. When a backup ZIP is restored, the application extracts the archive and copies each restored watch UUID directory directly into the live datastore using `shutil.copytree(entry.path, dst_dir)`. This preserves attacker-controlled files inside the restored watch directory, including `history.txt`.\n\nRelevant code:\n- [changedetectionio/blueprint/backups/restore.py](https://github.com/dgtlmoon/changedetection.io/blob/master/changedetectionio/blueprint/backups/restore.py#L132)\n- [changedetectionio/blueprint/backups/restore.py](https://github.com/dgtlmoon/changedetection.io/blob/master/changedetectionio/blueprint/backups/restore.py#L141)\n\nAfter restore, the application parses `history.txt` in the watch `history` property. This is the core trust-boundary issue.\n\nRelevant code:\n- [changedetectionio/model/Watch.py](https://github.com/dgtlmoon/changedetection.io/blob/master/changedetectionio/model/Watch.py#L460)\n- [changedetectionio/model/Watch.py](https://github.com/dgtlmoon/changedetection.io/blob/master/changedetectionio/model/Watch.py#L471)\n- [changedetectionio/model/Watch.py](https://github.com/dgtlmoon/changedetection.io/blob/master/changedetectionio/model/Watch.py#L478)\n\nThe relevant logic is effectively:\n\n```python\nif os.sep not in v and \u0027/\u0027 not in v and \u0027\\\\\u0027 not in v:\n    v = os.path.join(self.data_dir, v)\nelse:\n    snapshot_fname = os.path.basename(v)\n    proposed_new_path = os.path.join(self.data_dir, snapshot_fname)\n    if not os.path.exists(v) and os.path.exists(proposed_new_path):\n        v = proposed_new_path\n```\n\nThis has the following security consequence:\n\n- If the `history.txt` value is only a filename, it is resolved safely under `self.data_dir`.\n- If the value contains path separators, it is treated as a path reference rather than a watch-local snapshot name.\n- If that external path already exists, it is preserved unchanged.\n\nAs a result, a malicious restored `history.txt` entry such as:\n\n`1776969105,/etc/passwd`\n\nwill be accepted if the referenced file exists and is readable by the application process.\n\nThe second vulnerable step is in `get_history_snapshot()`. Once the untrusted path has been accepted into the watch history, the application reads the resolved path directly without enforcing that it remains inside the watch directory.\n\nRelevant code:\n- [changedetectionio/model/Watch.py](https://github.com/dgtlmoon/changedetection.io/blob/master/changedetectionio/model/Watch.py#L554)\n\nThat function eventually performs direct file reads such as:\n\n```python\nwith open(filepath, \u0027r\u0027, encoding=\u0027utf-8\u0027, errors=\u0027ignore\u0027) as f:\n    return f.read()\n```\n\nThe third step is reachability. The trusted history entry is consumed by both the Preview UI and the watch history API.\n\nRelevant code:\n- [changedetectionio/blueprint/ui/preview.py](https://github.com/dgtlmoon/changedetection.io/blob/master/changedetectionio/blueprint/ui/preview.py#L77)\n- [changedetectionio/api/Watch.py](https://github.com/dgtlmoon/changedetection.io/blob/master/changedetectionio/api/Watch.py#L263)\n\nIn the Preview flow, the application selects the latest history timestamp and calls:\n\n```python\ncontent = watch.get_history_snapshot(timestamp=timestamp)\n```\n\nIn the API flow, the application also calls:\n\n```python\ncontent = watch.get_history_snapshot(timestamp=timestamp)\n```\n\nThis creates the following end-to-end exploit chain:\n\n1. An attacker supplies a crafted backup ZIP.\n2. The restore process preserves attacker-controlled `history.txt`.\n3. The `history.txt` parser accepts an absolute or out-of-directory path if that path exists.\n4. Preview or the history API dereferences the stored path directly.\n5. The application returns the contents of the targeted local file.\n\nThe root cause is that imported history entries are treated as trusted filesystem paths instead of being restricted to safe basenames under `watch.data_dir`.\n\n\n### PoC\nThe following proof of concept demonstrates the end-to-end exploit chain. It assumes the attacker has gained access to the backup restore functionality to upload the crafted archive.\n\n1. Create a normal watch in the UI, for example:\n```text\nhttps://example.com\n```\n\n2. Trigger at least one successful check so the watch generates a valid history entry and can later be included in a backup.\n\n\u003cimg width=\"1230\" height=\"587\" alt=\"image\" src=\"https://github.com/user-attachments/assets/a76302c9-48d6-4aa3-9bfc-0ba2fdb31156\" /\u003e\n\n3. Go to the `Backups` section and create a backup archive.\n\n\u003cimg width=\"1232\" height=\"390\" alt=\"image\" src=\"https://github.com/user-attachments/assets/8fef0444-d8f0-4db6-be75-04fa7db2fec8\" /\u003e\n\n4. Extract the backup archive and identify the watch UUID directory that contains the target watch\u0027s `watch.json`. For example:\n```text\n5db3d3d8-71e6-4db2-a81e-e1f0445c3e47\n```\n\n5. Open that watch directory and edit `history.txt`.\n\n6. Replace the latest history entry with a path to an existing local file that is readable by the application process. For example:\n```text\n1776969188,/etc/passwd\n```\n\nIf the timestamp differs in the extracted backup, keep the original latest timestamp and only replace the filename/path portion.\n\nExample:\n```text\n1776969188,742215043ff9be7e635f05e680ff9b11.txt\n```\n\nbecomes:\n\n```text\n1776969188,/etc/passwd\n```\n\n\u003cimg width=\"1139\" height=\"366\" alt=\"image\" src=\"https://github.com/user-attachments/assets/07277b36-4747-4181-82d1-523385b40de3\" /\u003e\n\n7. Repack the backup so that the UUID directories are located at the root of the ZIP archive.\n\nImportant:\n- Do not add an extra parent directory layer when repacking.\n- The archive root should contain directories such as:\n```text\n\u003cwatch-uuid\u003e/\n\u003cgroup-uuid\u003e/\nchangedetection.json\nurl-list.txt\n```\n\n\u003cimg width=\"986\" height=\"353\" alt=\"image\" src=\"https://github.com/user-attachments/assets/21b30368-2cb5-4b88-9055-79d5bf06ad48\" /\u003e\n\n8. In the UI, restore the modified backup and enable replacement of existing watches with the same UUID.\n\n\u003cimg width=\"1229\" height=\"700\" alt=\"image\" src=\"https://github.com/user-attachments/assets/79abd9d2-8b2d-4e08-abf3-3b63238a8055\" /\u003e\n\n9. After restore completes, open `Preview` for the restored watch.\n\n10. The application will read the attacker-controlled path from `history.txt` and display the contents of the referenced local file instead of the original watch snapshot.\n\nObserved result:\n- The Preview page returns the content of the attacker-selected local file.\n\nExpected result:\n- The application should reject absolute paths or out-of-directory paths restored from `history.txt`.\n- Snapshot history should be restricted to files within the watch\u0027s own data directory.\n\nOptional API verification:\n- The same issue can also be confirmed through the watch history API by requesting the modified timestamp after restore.\n- The API returns the same file content because it also calls `watch.get_history_snapshot(timestamp=timestamp)` on the trusted history entry.\n\n\u003cimg width=\"1233\" height=\"545\" alt=\"image\" src=\"https://github.com/user-attachments/assets/a2814a5a-2cdd-49a1-916b-c956dd5fda1f\" /\u003e\n\n### Impact\nThis is an arbitrary local file disclosure vulnerability reachable through malicious backup restore content.\n\nWho is impacted:\n- Deployments where the application process has read access to sensitive local system files.\n- Docker or host-mounted environments where secrets, config files, or operational artifacts are explicitly readable by the service.\n\nWhat can be exposed:\n- **Arbitrary System Files:** Core operating system files (e.g., `/etc/passwd`, `/proc/self/environ`), system-level configurations, and host metrics.\n- **Application Data:** Internal records and files residing under the /datastore directory.\n- **Secrets \u0026 Artifacts:** Application-local configuration files, API tokens, database credentials, and other sensitive artifacts accessible to the application process.\n\nBy accessing the backup restore functionality and importing a crafted archive, an attacker can exploit the application\u0027s fail-open path validation. The confidentiality impact is exceptionally high because, once the payload is ingested, the application can be manipulated to disclose arbitrary local system files and highly sensitive environment variables directly through standard UI or API responses.\n\n### Recommendation\nThe application should treat all paths restored from `history.txt` as untrusted input.\n\nThe root cause is in [changedetectionio/model/Watch.py](https://github.com/dgtlmoon/changedetection.io/blob/master/changedetectionio/model/Watch.py#L460), where values containing path separators are currently accepted as filesystem paths and preserved if the referenced file already exists.\n\nThe fix should be:\n\n1. Never trust absolute or external paths from `history.txt`.\n2. Normalize every history entry to `os.path.basename(v)`.\n3. Join the normalized filename to `self.data_dir`.\n4. Skip the entry if the resolved file does not exist inside the watch directory.\n\nSuggested code change:\n\n```python\nsnapshot_fname = os.path.basename(v.strip())\nresolved_path = os.path.join(self.data_dir, snapshot_fname)\n\nif not os.path.exists(resolved_path):\n    logger.warning(\n        f\"Skipping unsafe or missing history entry for {self.get(\u0027uuid\u0027)}: {v!r}\"\n    )\n    continue\n\ntmp_history[k] = resolved_path\n```\n\nThis ensures restored history entries can only reference files inside the watch\u0027s own data directory and prevents arbitrary local file reads through Preview or the history API.",
  "id": "GHSA-8757-69j2-hx56",
  "modified": "2026-06-05T14:31:27Z",
  "published": "2026-05-05T21:16:21Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/dgtlmoon/changedetection.io/security/advisories/GHSA-8757-69j2-hx56"
    },
    {
      "type": "WEB",
      "url": "https://github.com/pocket-id/pocket-id/security/advisories/GHSA-w6p7-2fxx-4f44"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-43891"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/dgtlmoon/changedetection.io"
    },
    {
      "type": "WEB",
      "url": "https://github.com/pypa/advisory-database/tree/main/vulns/changedetection-io/PYSEC-2026-30.yaml"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N",
      "type": "CVSS_V3"
    }
  ],
  "summary": "changedetection.io has an Arbitrary Local File Read via a crafted backup restore"
}

GHSA-8847-338W-5HCJ

Vulnerability from github – Published: 2026-04-22 17:43 – Updated: 2026-05-13 13:30
VLAI
Summary
i18next-fs-backend: Path traversal via unsanitised lng/ns allows arbitrary file read/overwrite
Details

Summary

Versions of i18next-fs-backend prior to 2.6.4 interpolate the caller-supplied lng and ns values directly into the configured loadPath and addPath templates with no path-component validation and no sanitisation. When an application exposes the resolved language code to user-controlled input (?lng= query parameter, cookie, request header), a crafted value can break out of the intended locale directory.

Affected call sites in lib/index.js:

  • read (line 38 pre-patch): const filename = interpolate(loadPath, { lng: language, ns: namespace })
  • removeFile (line 101 pre-patch): same pattern against addPath
  • writeFile (line 127 pre-patch): same pattern against addPath for queued missing-key writes

The helper interpolate in lib/utils.js substitutes raw values with no encoding — unlike the addQueryString helper in i18next-http-backend, there is no equivalent safety for path interpolation.

Impact

  • Arbitrary file read. With a loadPath like /locales/{{lng}}/{{ns}}.json, an attacker-controlled lng = '../../etc' (and matching ns) causes the backend to read a file outside the locale directory. For parsers that tolerate arbitrary content (YAML's freeform text), the file contents surface as a translation resource.
  • Arbitrary file overwrite. addPath is interpolated the same way for missing-key writes (the create() code path and the debounced writer in writeFile). A traversing lng/ns combination can cause the process to write JSON structures to an unintended filesystem location, potentially overwriting application files if the process user has write access.
  • Chain with .js/.ts eval. i18next-fs-backend supports loading .js and .ts locale files by eval-ing their content (intentional feature, documented as requiring trusted sources). Combining traversal with that path — for example lng = '../../../app/config' against loadPath: '/locales/{{lng}}/{{ns}}.js' — would cause the backend to execute a server-side file as JavaScript, exfiltrating whatever it can touch (process.env, connected services).

Exploitation requires the application to pass an untrusted lng/ns value through to i18next.t() without its own validation. Many i18next setups do exactly this via i18next-browser-languagedetector (query string / cookie detection).

Affected versions

All versions of i18next-fs-backend prior to 2.6.4.

Patch

Fixed in 2.6.4. lib/utils.js now exports:

  • isSafePathSegment(v) — returns true only if v is a non-empty string of ≤ 128 chars that does not contain .., /, \, control characters, or a prototype key (__proto__, constructor, prototype). Legitimate i18next language-code shapes (BCP-47, en_US, zh-Hant-HK, pirate-speak, my-custom.ns, +-joined multi-language values) all pass.
  • interpolatePath(template, data) — substitutes variables like the existing interpolate but refuses the whole result if any segment fails isSafePathSegment. Callers bail out with an error (read) or silently drop the queued write (writeFile, removeFile).

The .js / .ts eval behaviour is intentionally retained — dynamic expressions in locale files are a documented feature of this backend, and safe replacements like dynamic import() are async-only and incompatible with this backend's sync-capable code path. The README has a new "Security considerations" section that spells out the trust model: .js/.ts locale files must be treated as code.

Workarounds

No workaround short of upgrading. If you cannot upgrade immediately, sanitise lng / ns at your application boundary before passing them to i18next — reject values containing .., /, \, control characters, and cap the length.

Credits

Discovered via an internal security audit of the i18next ecosystem.

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "npm",
        "name": "i18next-fs-backend"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "2.6.4"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-41693"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-22",
      "CWE-73"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-04-22T17:43:14Z",
    "nvd_published_at": "2026-05-08T16:16:11Z",
    "severity": "HIGH"
  },
  "details": "### Summary\n\nVersions of `i18next-fs-backend` prior to 2.6.4 interpolate the caller-supplied `lng` and `ns` values directly into the configured `loadPath` and `addPath` templates with no path-component validation and no sanitisation. When an application exposes the resolved language code to user-controlled input (`?lng=` query parameter, cookie, request header), a crafted value can break out of the intended locale directory.\n\nAffected call sites in `lib/index.js`:\n\n- `read` (line 38 pre-patch): `const filename = interpolate(loadPath, { lng: language, ns: namespace })`\n- `removeFile` (line 101 pre-patch): same pattern against `addPath`\n- `writeFile` (line 127 pre-patch): same pattern against `addPath` for queued missing-key writes\n\nThe helper `interpolate` in `lib/utils.js` substitutes raw values with no encoding \u2014 unlike the `addQueryString` helper in `i18next-http-backend`, there is no equivalent safety for path interpolation.\n\n### Impact\n\n- **Arbitrary file read.** With a `loadPath` like `/locales/{{lng}}/{{ns}}.json`, an attacker-controlled `lng = \u0027../../etc\u0027` (and matching `ns`) causes the backend to read a file outside the locale directory. For parsers that tolerate arbitrary content (YAML\u0027s freeform text), the file contents surface as a translation resource.\n- **Arbitrary file overwrite.** `addPath` is interpolated the same way for missing-key writes (the `create()` code path and the debounced writer in `writeFile`). A traversing `lng`/`ns` combination can cause the process to write JSON structures to an unintended filesystem location, potentially overwriting application files if the process user has write access.\n- **Chain with `.js`/`.ts` eval.** `i18next-fs-backend` supports loading `.js` and `.ts` locale files by `eval`-ing their content (intentional feature, documented as requiring trusted sources). Combining traversal with that path \u2014 for example `lng = \u0027../../../app/config\u0027` against `loadPath: \u0027/locales/{{lng}}/{{ns}}.js\u0027` \u2014 would cause the backend to **execute** a server-side file as JavaScript, exfiltrating whatever it can touch (`process.env`, connected services).\n\nExploitation requires the application to pass an untrusted `lng`/`ns` value through to `i18next.t()` without its own validation. Many i18next setups do exactly this via `i18next-browser-languagedetector` (query string / cookie detection).\n\n### Affected versions\n\nAll versions of `i18next-fs-backend` prior to **2.6.4**.\n\n### Patch\n\nFixed in **2.6.4**. `lib/utils.js` now exports:\n\n- `isSafePathSegment(v)` \u2014 returns `true` only if `v` is a non-empty string of \u2264 128 chars that does not contain `..`, `/`, `\\`, control characters, or a prototype key (`__proto__`, `constructor`, `prototype`). Legitimate i18next language-code shapes (BCP-47, `en_US`, `zh-Hant-HK`, `pirate-speak`, `my-custom.ns`, `+`-joined multi-language values) all pass.\n- `interpolatePath(template, data)` \u2014 substitutes variables like the existing `interpolate` but refuses the whole result if any segment fails `isSafePathSegment`. Callers bail out with an error (`read`) or silently drop the queued write (`writeFile`, `removeFile`).\n\nThe `.js` / `.ts` `eval` behaviour is intentionally retained \u2014 dynamic expressions in locale files are a documented feature of this backend, and safe replacements like dynamic `import()` are async-only and incompatible with this backend\u0027s sync-capable code path. The README has a new \"Security considerations\" section that spells out the trust model: `.js`/`.ts` locale files must be treated as code.\n\n### Workarounds\n\nNo workaround short of upgrading. If you cannot upgrade immediately, sanitise `lng` / `ns` at your application boundary before passing them to i18next \u2014 reject values containing `..`, `/`, `\\`, control characters, and cap the length.\n\n### Credits\n\nDiscovered via an internal security audit of the i18next ecosystem.",
  "id": "GHSA-8847-338w-5hcj",
  "modified": "2026-05-13T13:30:00Z",
  "published": "2026-04-22T17:43:14Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/i18next/i18next-fs-backend/security/advisories/GHSA-8847-338w-5hcj"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-41693"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/i18next/i18next-fs-backend"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:L/A:N",
      "type": "CVSS_V3"
    }
  ],
  "summary": "i18next-fs-backend: Path traversal via unsanitised lng/ns allows arbitrary file read/overwrite"
}

GHSA-88GP-9664-52XH

Vulnerability from github – Published: 2025-05-24 06:30 – Updated: 2026-04-08 18:33
VLAI
Details

The eMagicOne Store Manager for WooCommerce plugin for WordPress is vulnerable to arbitrary file deletion due to insufficient file path validation in the delete_file() function in all versions up to, and including, 1.2.5. This makes it possible for unauthenticated attackers to delete arbitrary files on the server, which can easily lead to remote code execution when the right file is deleted (such as wp-config.php). This is only exploitable by unauthenticated attackers in default configurations where the the default password is left as 1:1, or where the attacker gains access to the credentials.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2025-4603"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-73"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2025-05-24T04:15:30Z",
    "severity": "CRITICAL"
  },
  "details": "The eMagicOne Store Manager for WooCommerce plugin for WordPress is vulnerable to arbitrary file deletion due to insufficient file path validation in the delete_file() function in all versions up to, and including, 1.2.5. This makes it possible for unauthenticated attackers to delete arbitrary files on the server, which can easily lead to remote code execution when the right file is deleted (such as wp-config.php). This is only exploitable by unauthenticated attackers in default configurations where the the default password is left as 1:1, or where the attacker gains access to the credentials.",
  "id": "GHSA-88gp-9664-52xh",
  "modified": "2026-04-08T18:33:53Z",
  "published": "2025-05-24T06:30:39Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2025-4603"
    },
    {
      "type": "WEB",
      "url": "https://github.com/d0n601/CVE-2025-4603"
    },
    {
      "type": "WEB",
      "url": "https://plugins.trac.wordpress.org/browser/store-manager-connector/trunk/classes/class-emosmconnectorcommon.php#L2167"
    },
    {
      "type": "WEB",
      "url": "https://plugins.trac.wordpress.org/browser/store-manager-connector/trunk/classes/class-emosmcwoocommerceoverrider.php#L380"
    },
    {
      "type": "WEB",
      "url": "https://plugins.trac.wordpress.org/browser/store-manager-connector/trunk/smconnector.php#L35-36"
    },
    {
      "type": "WEB",
      "url": "https://plugins.trac.wordpress.org/changeset/3308544"
    },
    {
      "type": "WEB",
      "url": "https://ryankozak.com/posts/cve-2025-4603"
    },
    {
      "type": "WEB",
      "url": "https://www.wordfence.com/threat-intel/vulnerabilities/id/242ad00b-3602-4988-ab7a-76fba2e9d4cf?source=cve"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:H",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-88PR-878C-24WF

Vulnerability from github – Published: 2026-08-04 17:43 – Updated: 2026-08-04 17:43
VLAI
Summary
Flowise: Authenticated arbitrary file write in the `S3 Directory` document loader via unsanitized S3 object keys
Details

Summary

Flowise on current main allows an authenticated user with documentStores:preview-process permission to trigger the S3 Directory
document loader with attacker-controlled S3 object keys. The loader joins each returned S3 key with a temporary directory using path.join(tempDir, key)
and writes the object bytes to disk without validating traversal sequences such as ../. Cleanup later removes only the original temporary directory, so files written outside that directory persist on the host filesystem.

This yields arbitrary file write with the privileges of the Flowise
server process.

A related variant exists in the S3File loader when
fileProcessingMethod = unstructured (same root cause; its cleanup behavior
turns it into a mixed arbitrary write/delete/DoS primitive).

## Affected component

  • packages/components/nodes/documentloaders/S3Directory/S3Directory.ts
    • line 191: filePath = path.join(tempDir, key) (unsanitized)
    • line 213: recursive mkdirSync creates parent path
    • line 216: writeFileSync writes attacker-controlled bytes
    • line 289: cleanup only removes the original tempDir, so escaped
      files remain on disk
  • Related (variant):
    packages/components/nodes/documentloaders/S3File/S3File.ts
    (lines 756, 780, 782, 817 — arbitrary write + recursive dirname delete)

## Reachability

  • Routes exposed:
    packages/server/src/routes/documentstore/index.ts:41,45
    (/api/v1/document-store/loader/preview,
    /api/v1/document-store/loader/process/:loaderId)
  • Both require documentStores:preview-process
  • packages/server/src/services/documentstore/index.ts:588 passes
    data.loaderConfig straight to the loader node with no path
    sanitization
  • S3Directory accepts a custom serverUrl, so the attacker does not need access to an existing trusted AWS bucket — they can point Flowise
    at a local MinIO or any S3-compatible endpoint they control

## Impact

  • Authenticated arbitrary file write to any path writable by the Flowise
    process
  • Destructive overwrite of application data, secrets, or configuration
  • Deployment-dependent lift to RCE if the service account can modify
    executable, startup, or interpreter-loaded files
    (e.g. .bashrc, systemd units, cron files, require.resolve targets,
    package.json postinstall scripts). This is not guaranteed
    product-wide.

## Preconditions

  • Flowise instance running (HTTP server mode)
  • Attacker has a workspace account with the
    documentStores:preview-process role
  • No additional infrastructure required — serverUrl can point to
    attacker-controlled S3-compatible endpoint

## Proof of Concept

  1. Authenticate as a user with documentStores:preview-process
  2. Run an S3-compatible server the attacker controls (e.g. MinIO)
  3. Create an object with a traversal key such as:
    ../../../../tmp/flowise-poc.txt
  4. Trigger:
    POST /api/v1/document-store/loader/preview
    (or /api/v1/document-store/loader/process/:loaderId)
    body: {
    "loaderId": "s3Directory",
    "loaderConfig": {
    "serverUrl": "http://attacker-minio:9000",
    "bucketName": "attacker-bucket",
    "prefix": "",
    "credential": ""
    }
    }
  5. Observe that Flowise writes the object bytes to the escaped path
  6. Observe that cleanup removes only the original temp directory; the escaped file persists

Local reproduction confirmed: writing a key containing
../../escape-target/poc.txt from a nested temp root created the file
outside the temp directory, and the cleanup removed only tempDir.

## Root Cause

The loader trusts S3 object keys as safe local relative paths. It should
canonicalize the destination with path.resolve(...), verify the resolved
path remains within the intended temp directory, and reject traversal or
absolute-path patterns before any directory creation or file write.

## Suggested Remediation

The repository already has shared path validators that are not used here:

  • packages/components/src/validator.ts:35 defines traversal checks
  • packages/components/src/validator.ts:295 defines sanitizeFileName

Recommended fix:

  1. Replace path.join(tempDir, key) with a resolve-and-verify flow
  2. Reject any resolved path outside tempDir
  3. Prefer a sanitized basename if directory structure is not required
  4. Apply the same fix to the S3File loader (fileProcessingMethod = unstructured branch)
Show details on source website

{
  "affected": [
    {
      "database_specific": {
        "last_known_affected_version_range": "\u003c= 3.1.2"
      },
      "package": {
        "ecosystem": "npm",
        "name": "flowise-components"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "3.1.3"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "database_specific": {
        "last_known_affected_version_range": "\u003c= 3.1.2"
      },
      "package": {
        "ecosystem": "npm",
        "name": "flowise"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "3.1.3"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [],
  "database_specific": {
    "cwe_ids": [
      "CWE-22",
      "CWE-73"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-08-04T17:43:45Z",
    "nvd_published_at": null,
    "severity": "HIGH"
  },
  "details": "## Summary                                                                                                                                                                                                   \n                                          \n  Flowise on current `main` allows an authenticated user with\n  `documentStores:preview-process` permission to trigger the `S3 Directory`                                                                                                                                    \n  document loader with attacker-controlled S3 object keys. The loader joins\n  each returned S3 key with a temporary directory using `path.join(tempDir, key)`                                                                                                                              \n  and writes the object bytes to disk **without validating traversal sequences\n  such as `../`**. Cleanup later removes only the original temporary directory,\n  so files written outside that directory persist on the host filesystem.                                                                                                                                      \n                                                                                                                                                                                                               \n  This yields **arbitrary file write** with the privileges of the Flowise                                                                                                                                      \n  server process.                                                                                                                                                                                              \n                                                                                                                                                                                                               \n  A related variant exists in the `S3File` loader when                                                                                                                                                         \n  `fileProcessingMethod = unstructured` (same root cause; its cleanup behavior                                                                                                                                 \n  turns it into a mixed arbitrary write/delete/DoS primitive).                                                                                                                                     \n                                                                                                                                                                                                               \n  ## Affected component                                                                                                                                                                                        \n                                                                                                                                                                                                               \n  - `packages/components/nodes/documentloaders/S3Directory/S3Directory.ts`\n    - line **191**: `filePath = path.join(tempDir, key)` (unsanitized)                                                                                                                                         \n    - line **213**: recursive `mkdirSync` creates parent path                                                                                                                                                  \n    - line **216**: `writeFileSync` writes attacker-controlled bytes                                                                                                                                           \n    - line **289**: cleanup only removes the original `tempDir`, so escaped                                                                                                                                    \n      files remain on disk                                                                                                                                                                                     \n  - Related (variant):                                                                                                                                                                                         \n    `packages/components/nodes/documentloaders/S3File/S3File.ts`                                                                                                                                               \n    (lines 756, 780, 782, 817 \u2014 arbitrary write + recursive dirname delete)\n                                                                                                                                                                                                               \n  ## Reachability                                                                                                                                                                                              \n                                                                                                                                                                                                               \n  - Routes exposed:                                                                                                                                                                                            \n    `packages/server/src/routes/documentstore/index.ts:41,45`                                                                                                                                                  \n    (`/api/v1/document-store/loader/preview`,                                                                                                                                                                  \n     `/api/v1/document-store/loader/process/:loaderId`)                                                                                                                                                        \n  - Both require `documentStores:preview-process`                                                                                                                                                              \n  - `packages/server/src/services/documentstore/index.ts:588` passes                                                                                                                                           \n    `data.loaderConfig` straight to the loader node **with no path                                                                                                                                             \n    sanitization**                                                                                                                                                                                             \n  - `S3Directory` accepts a custom `serverUrl`, so the attacker does **not\n    need access to an existing trusted AWS bucket** \u2014 they can point Flowise                                                                                                                                   \n    at a local MinIO or any S3-compatible endpoint they control                                                                                                                                                \n                                                                                                                                                                                                               \n  ## Impact                                                                                                                                                                                                    \n                                                                                                                                                                                                               \n  - Authenticated arbitrary file write to any path writable by the Flowise                                                                                                                                     \n    process                                                                                                                                                                                                    \n  - Destructive overwrite of application data, secrets, or configuration                                                                                                                                       \n  - Deployment-dependent lift to RCE if the service account can modify                                                                                                                                         \n    executable, startup, or interpreter-loaded files                                                                                                                                                           \n    (e.g. `.bashrc`, systemd units, cron files, `require.resolve` targets,                                                                                                                                     \n    `package.json` postinstall scripts). This is not guaranteed                                                                                                                                                \n    product-wide.                         \n                                                                                                                                                                                                               \n  ## Preconditions                                                                                                                                                                                             \n                                                                                                                                                                                                               \n  - Flowise instance running (HTTP server mode)                                                                                                                                                                \n  - Attacker has a workspace account with the                                                                                                                                                                  \n    `documentStores:preview-process` role                                                                                                                                                                      \n  - No additional infrastructure required \u2014 `serverUrl` can point to                                                                                                                                           \n    attacker-controlled S3-compatible endpoint                                                                                                                                                                 \n                                                                                                                                                                                                               \n  ## Proof of Concept                                                                                                                                                                                          \n                                                             \n  1. Authenticate as a user with `documentStores:preview-process`\n  2. Run an S3-compatible server the attacker controls (e.g. MinIO)                                                                                                                                            \n  3. Create an object with a traversal key such as:                                                                                                                                                            \n     `../../../../tmp/flowise-poc.txt`                                                                                                                                                                         \n  4. Trigger:                                                                                                                                                                                                  \n     POST /api/v1/document-store/loader/preview                                                                                                                                                                \n     (or /api/v1/document-store/loader/process/:loaderId)    \n     body: {                                                                                                                                                                                                   \n       \"loaderId\": \"s3Directory\",         \n       \"loaderConfig\": {                                                                                                                                                                                       \n         \"serverUrl\": \"http://attacker-minio:9000\",                                                                                                                                                            \n         \"bucketName\": \"attacker-bucket\",                                                                                                                                                                      \n         \"prefix\": \"\",                                                                                                                                                                                         \n         \"credential\": \"\"                                    \n       }                                                                                                                                                                                                       \n     }                                                       \n  5. Observe that Flowise writes the object bytes to the escaped path                                                                                                                                          \n  6. Observe that cleanup removes only the original temp directory; the\n  escaped file persists                                                                                                                                                                                        \n                                                                                                                                                                                                               \n  Local reproduction confirmed: writing a key containing     \n  `../../escape-target/poc.txt` from a nested temp root created the file                                                                                                                                       \n  outside the temp directory, and the cleanup removed only `tempDir`.   \n                                                                                                                                                                                                               \n  ## Root Cause                                                                                                                                                                                                \n                                                             \n  The loader trusts S3 object keys as safe local relative paths. It should                                                                                                                                     \n  canonicalize the destination with `path.resolve(...)`, verify the resolved                                                                                                                                   \n  path remains within the intended temp directory, and reject traversal or                                                                                                                                     \n  absolute-path patterns before any directory creation or file write.                                                                                                                                          \n                                                                                                                                                                                                               \n  ## Suggested Remediation                                                                                                                                                                                     \n                                                                                                                                                                                                               \n  The repository already has shared path validators that are not used here:                                                                                                                                    \n                                                                                                                                                                                                               \n  - `packages/components/src/validator.ts:35` defines traversal checks\n  - `packages/components/src/validator.ts:295` defines `sanitizeFileName`                                                                                                                                      \n                                                                                                                                                                                                               \n  Recommended fix:                                                                                                                                                                                             \n                                                                                                                                                                                                               \n  1. Replace `path.join(tempDir, key)` with a resolve-and-verify flow                                                                                                                                          \n  2. Reject any resolved path outside `tempDir`                                                                                                                                                                \n  3. Prefer a sanitized basename if directory structure is not required\n  4. Apply the same fix to the `S3File` loader (`fileProcessingMethod = unstructured` branch)",
  "id": "GHSA-88pr-878c-24wf",
  "modified": "2026-08-04T17:43:45Z",
  "published": "2026-08-04T17:43:45Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/FlowiseAI/Flowise/security/advisories/GHSA-88pr-878c-24wf"
    },
    {
      "type": "WEB",
      "url": "https://github.com/FlowiseAI/Flowise/pull/6549"
    },
    {
      "type": "WEB",
      "url": "https://github.com/FlowiseAI/Flowise/commit/571b5d6218b1c129588ac625c8f20e30905a67cb"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/FlowiseAI/Flowise"
    },
    {
      "type": "WEB",
      "url": "https://github.com/FlowiseAI/Flowise/releases/tag/flowise@3.1.3"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:N/VI:H/VA:H/SC:N/SI:N/SA:N",
      "type": "CVSS_V4"
    }
  ],
  "summary": "Flowise: Authenticated arbitrary file write in the `S3 Directory` document loader via unsanitized S3 object keys                                                                                                  "
}

GHSA-8C33-WHFW-95GH

Vulnerability from github – Published: 2026-05-19 18:32 – Updated: 2026-05-19 18:32
VLAI
Details

Terrascan v1.18.3 and prior are vulnerable to Server-Side Request Forgery (SSRF) via external URL resolution in uploaded IaC templates when running in server mode. When Terrascan parses uploaded ARM templates or CloudFormation templates, it resolves external URLs referenced within those templates via hashicorp/go-getter with all default detectors enabled, including FileDetector. An unauthenticated remote attacker can upload an ARM template containing a templateLink.uri or parametersLink.uri field, or a CloudFormation template containing an AWS::CloudFormation::Stack TemplateURL field, pointing to an attacker-controlled URL. Terrascan will fetch the attacker-controlled URL server-side. Unlike SSRF via the remote scan endpoint, file:// URLs are directly usable without requiring an X-Terraform-Get redirect, enabling local file read. This affects deployments running terrascan in server mode (terrascan server), which binds to 0.0.0.0 with no authentication. Note: Terrascan was archived in August 2023 and no patch will be released.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2026-47358"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-73",
      "CWE-918"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2026-05-19T17:16:23Z",
    "severity": "CRITICAL"
  },
  "details": "Terrascan v1.18.3 and prior are vulnerable to Server-Side Request Forgery (SSRF) via external URL resolution in uploaded IaC templates when running in server mode. When Terrascan parses uploaded ARM templates or CloudFormation templates, it resolves external URLs referenced within those templates via hashicorp/go-getter with all default detectors enabled, including FileDetector. An unauthenticated remote attacker can upload an ARM template containing a templateLink.uri or parametersLink.uri field, or a CloudFormation template containing an AWS::CloudFormation::Stack TemplateURL field, pointing to an attacker-controlled URL. Terrascan will fetch the attacker-controlled URL server-side. Unlike SSRF via the remote scan endpoint, file:// URLs are directly usable without requiring an X-Terraform-Get redirect, enabling local file read. This affects deployments running terrascan in server mode (terrascan server), which binds to 0.0.0.0 with no authentication. Note: Terrascan was archived in August 2023 and no patch will be released.",
  "id": "GHSA-8c33-whfw-95gh",
  "modified": "2026-05-19T18:32:13Z",
  "published": "2026-05-19T18:32:13Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-47358"
    },
    {
      "type": "WEB",
      "url": "https://github.com/tenable/terrascan"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N",
      "type": "CVSS_V3"
    },
    {
      "score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:N/VA:N/SC:H/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X",
      "type": "CVSS_V4"
    }
  ]
}

GHSA-8G6F-QW9X-4Q6Q

Vulnerability from github – Published: 2026-07-14 15:32 – Updated: 2026-09-03 19:49
VLAI
Summary
Snowflake SQLAlchemy affected by SQL injection and local file disclosure vulnerabilities
Details

Snowflake SQLAlchemy versions prior to 1.11.0 contain several security vulnerabilities, including: Improper handling of user-supplied column identifiers in merge operations could allow SQL injection through attacker-controlled input keys. An attacker may be able to exploit this through request field names in a dynamic upsert endpoint, potentially enabling read access to data visible to the application's database role or modification of values within the same MERGE statement. Improper literal rendering of bound parameters when building certain Snowflake-specific table creation queries could allow SQL injection. An attacker may be able to exploit this by supplying a crafted string to any application endpoint that passes user-controlled data through the affected query-building API, potentially causing arbitrary data exfiltration within the scope of the connection role. Improper forwarding of connection configuration parameters could allow an attacker to cause the library to read arbitrary local files and transmit their contents to an attacker-controlled endpoint. An attacker may be able to exploit this in deployment environments that accept user-controlled connection parameters, potentially exposing sensitive files accessible to the application process. The fix is available in Snowflake SQLAlchemy version 1.11.0. Users must manually upgrade.

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "PyPI",
        "name": "snowflake-sqlalchemy"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "1.1.6"
            },
            {
              "fixed": "1.11.0"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-15736"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-73"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-09-03T19:49:44Z",
    "nvd_published_at": "2026-07-14T15:17:01Z",
    "severity": "HIGH"
  },
  "details": "Snowflake SQLAlchemy versions prior to 1.11.0 contain several security vulnerabilities, including: Improper handling of user-supplied column identifiers in merge operations could allow SQL injection through attacker-controlled input keys. An attacker may be able to exploit this through request field names in a dynamic upsert endpoint, potentially enabling read access to data visible to the application\u0027s database role or modification of values within the same MERGE statement. Improper literal rendering of bound parameters when building certain Snowflake-specific table creation queries could allow SQL injection. An attacker may be able to exploit this by supplying a crafted string to any application endpoint that passes user-controlled data through the affected query-building API, potentially causing arbitrary data exfiltration within the scope of the connection role. Improper forwarding of connection configuration parameters could allow an attacker to cause the library to read arbitrary local files and transmit their contents to an attacker-controlled endpoint. An attacker may be able to exploit this in deployment environments that accept user-controlled connection parameters, potentially exposing sensitive files accessible to the application process. The fix is available in Snowflake SQLAlchemy version 1.11.0. Users must manually upgrade.",
  "id": "GHSA-8g6f-qw9x-4q6q",
  "modified": "2026-09-03T19:49:44Z",
  "published": "2026-07-14T15:32:17Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-15736"
    },
    {
      "type": "WEB",
      "url": "https://github.com/snowflakedb/snowflake-sqlalchemy/pull/707"
    },
    {
      "type": "WEB",
      "url": "https://github.com/snowflakedb/snowflake-sqlalchemy/pull/708"
    },
    {
      "type": "WEB",
      "url": "https://github.com/snowflakedb/snowflake-sqlalchemy/pull/710"
    },
    {
      "type": "WEB",
      "url": "https://github.com/snowflakedb/snowflake-sqlalchemy/commit/2c33792c91449e746a2c7ef24c25f0ede0a4a875"
    },
    {
      "type": "WEB",
      "url": "https://github.com/snowflakedb/snowflake-sqlalchemy/commit/35edf4dc5e76b9a9fdfa74c8e4f6fd14642110f1"
    },
    {
      "type": "WEB",
      "url": "https://github.com/snowflakedb/snowflake-sqlalchemy/commit/a198ed2197bb3e0be57268032ed6e8b7fdeb8129"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/snowflakedb/snowflake-sqlalchemy"
    },
    {
      "type": "WEB",
      "url": "https://github.com/snowflakedb/snowflake-sqlalchemy/releases"
    },
    {
      "type": "WEB",
      "url": "https://github.com/snowflakedb/snowflake-sqlalchemy/releases/tag/v1.11.0"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:L",
      "type": "CVSS_V3"
    }
  ],
  "summary": "Snowflake SQLAlchemy affected by SQL injection and local file disclosure vulnerabilities"
}

GHSA-8G6X-JFC6-X2J7

Vulnerability from github – Published: 2025-08-07 06:30 – Updated: 2025-08-07 06:30
VLAI
Details

: External Control of File Name or Path vulnerability in TAGFREE X-Free Uploader XFU allows : Parameter Injection.This issue affects X-Free Uploader: from 1.0.1.0084 before 1.0.1.0085, from 2.0.1.0034 before 2.0.1.0035.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2025-29866"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-73"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2025-08-07T06:15:41Z",
    "severity": "HIGH"
  },
  "details": ": External Control of File Name or Path vulnerability in TAGFREE X-Free Uploader XFU allows : Parameter Injection.This issue affects X-Free Uploader: from 1.0.1.0084 before 1.0.1.0085, from 2.0.1.0034 before 2.0.1.0035.",
  "id": "GHSA-8g6x-jfc6-x2j7",
  "modified": "2025-08-07T06:30:30Z",
  "published": "2025-08-07T06:30:30Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2025-29866"
    },
    {
      "type": "WEB",
      "url": "https://www.boho.or.kr/kr/bbs/view.do?searchCnd=\u0026bbsId=B0000302\u0026searchWrd=\u0026menuNo=205023\u0026pageIndex=1\u0026categoryCode=\u0026nttId=71827"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:H/VA:H/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X",
      "type": "CVSS_V4"
    }
  ]
}

GHSA-8HF9-3Q64-Q2QF

Vulnerability from github – Published: 2026-05-12 15:08 – Updated: 2026-06-08 23:50
VLAI
Summary
Dalfox Server Mode has an Unauthenticated Arbitrary File Create/Append via `output` Option
Details

Summary

When dalfox is run in REST API server mode, the output, output-all, and debug fields in model.Options are JSON-tagged and deserialized directly from the attacker's request body, then propagated unchanged through dalfox.Initialize into the scan engine's logging path. The logger opens the attacker-supplied path with os.O_APPEND|os.O_CREATE|os.O_WRONLY and writes scan log lines to it. Critically, this file write block lives outside the IsLibrary guard in DalLog, so it executes even in server/library mode where file output was never intended to operate. Because no API key is required in the default configuration, an unauthenticated network caller can create or append to any file writable by the dalfox process on the host filesystem.

Severity

High (CVSS 3.1: 8.2)

CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:L

  • Attack Vector: Network — server binds to 0.0.0.0:6664 by default.
  • Attack Complexity: Low — no preconditions; all trigger options (output, output-all, debug) are fully attacker-supplied in the JSON body.
  • Privileges Required: None — --api-key defaults to "", so the auth middleware is never registered.
  • User Interaction: None.
  • Scope: Unchanged — the file write stays within the dalfox process's OS authority.
  • Confidentiality Impact: None — this is a write-only primitive; no data is returned to the caller.
  • Integrity Impact: High — the attacker has full control over which file path is opened, enabling creation of new files or corruption of existing files anywhere the dalfox process has write permission. While the log content format is semi-fixed, the file path is entirely attacker-determined, making the integrity violation complete with respect to file targeting.
  • Availability Impact: Low — corrupting application configuration files or log files on the host can degrade the availability of other services relying on those files.

Affected Component

  • cmd/server.go — init() (line 51): --api-key defaults to "" — no auth by default
  • pkg/server/server.go — setupEchoServer() (line 68): auth middleware only registered when APIKey != ""
  • pkg/server/server.go — postScanHandler() (lines 173–191): rq.Options (including OutputFile, OutputAll, Debug) passed to ScanFromAPI without sanitization
  • lib/func.go — Initialize() (line 107): OutputFile explicitly propagated from caller options; OutputAll (line 167) and Debug (line 176) likewise
  • internal/printing/logger.go — DalLog() (lines 230–244): os.OpenFile(options.OutputFile, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) executes outside the IsLibrary guard

CWE

  • CWE-306: Missing Authentication for Critical Function
  • CWE-73: External Control of File Name or Path
  • CWE-434: Unrestricted Upload of File with Dangerous Type (write-path variant)

Description

output, output-all, and debug Are Fully Attacker-Controlled

model.Options exposes all three trigger fields with JSON tags:

// pkg/model/options.go:88,85,88
OutputFile  string `json:"output,omitempty"`
OutputAll   bool   `json:"output-all,omitempty"`
Debug       bool   `json:"debug,omitempty"`

postScanHandler binds the entire Req.Options from the JSON body and passes it directly to ScanFromAPI:

// pkg/server/server.go:173-191
rq := new(Req)
if err := c.Bind(rq); err != nil { ... }
go ScanFromAPI(rq.URL, rq.Options, *options, sid)

Initialize explicitly copies all three fields into newOptions:

// lib/func.go:107, 167, 176
"OutputFile": {&newOptions.OutputFile, options.OutputFile},
...
"OutputAll":  {&newOptions.OutputAll, options.OutputAll},
...
"Debug":      {&newOptions.Debug, options.Debug},

The File Write Is Not Guarded by IsLibrary

Initialize always sets IsLibrary: true (line 20) and Silence: true (line 44) in its returned options — the intent being that the scan engine runs in embedded/library mode during API calls, suppressing terminal I/O. DalLog does respect this for stderr output: lines 203–228 route logs to ScanResult.Logs (not stderr) when IsLibrary is true. However, the file write block at lines 230–244 is positioned after and outside that if-else:

// internal/printing/logger.go
mutex.Lock()
if options.IsLibrary {
    options.ScanResult.Logs = append(options.ScanResult.Logs, text)  // API path
} else {
    // stderr printing (CLI path)
}

// ← file write is here, unconditionally — no IsLibrary check
if options.OutputFile != "" {
    var fdtext string
    if ftext != "" {
        fdtext = ftext
        f, err := os.OpenFile(options.OutputFile,
            os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
        if err != nil {
            fmt.Fprintln(os.Stderr, "output file error (file)")
        }
        defer f.Close()
        if _, err := f.WriteString(fdtext + "\n"); err != nil {
            fmt.Fprintln(os.Stderr, "output file error (write)")
        }
    }
}
mutex.Unlock()

The ftext variable is populated whenever allWrite is true (options.Debug || options.OutputAll). Since both are attacker-supplied, both conditions are trivially satisfied.

What Gets Written

Log lines of the form:

[*] Starting scan [SID:<id>] / URL: <attacker-supplied-url>
[I] Checking BAV
[E] connection refused
[DEBUG] <internal state>
...

The URL appears verbatim in log messages, giving the attacker partial influence over the written content. While the format is not fully arbitrary (fixed prefixes like [*], [I], [E]), the file path is entirely attacker-controlled. The flags O_CREATE (creates the file if absent) and O_APPEND (never truncates) mean the attacker can: - Create new files at arbitrary paths - Append log content to existing files (corrupting configs, auth files, cron entries if the line happens to match syntax)

No Defense at Any Layer

The same opt-in API key gap applies here as in all prior findings:

// pkg/server/server.go:68-70
if options.ServerType == "rest" && options.APIKey != "" {
    e.Use(apiKeyAuth(options.APIKey, options))
}

There is no path allowlist, no IsLibrary guard on the file write, and no stripping of OutputFile from API-sourced requests anywhere in the codebase.

Proof of Concept

# Step 1 — Start dalfox REST server (default: no API key)
go run . server --host 127.0.0.1 --port 16664 --type rest

# Step 2 — Verify health (unauthenticated)
curl -s http://127.0.0.1:16664/health
# Expected: {"code":200,"msg":"ok"}

# Step 3 — Trigger arbitrary file creation with attacker-controlled path
curl -s -X POST http://127.0.0.1:16664/scan \
  -H 'Content-Type: application/json' \
  --data '{
    "url": "http://127.0.0.1:1/?x=1",
    "options": {
      "output": "/tmp/dalfox_sink_poc.log",
      "output-all": true,
      "debug": true,
      "use-headless": false
    }
  }'

# Step 4 — Verify file was created and written to by the dalfox process
sleep 2
cat /tmp/dalfox_sink_poc.log
# Expected:
# [*] Starting scan [SID:...] / URL: http://127.0.0.1:1/?x=1
# [I] Checking BAV
# [E] ...

No X-API-KEY header is required. Replace /tmp/dalfox_sink_poc.log with any path writable by the dalfox process: /var/www/html/injected.txt, /etc/cron.d/dalfox, ~/.ssh/authorized_keys (appending log lines that won't break key format but pollute the file), etc.

Impact

  • Arbitrary file creation: The attacker can create files at any path on the dalfox host filesystem accessible to the dalfox process, including web-serving directories, cron drop-in directories, and application config directories.
  • Arbitrary file append/corruption: Existing files can have log-format lines appended, degrading parsers that expect strict formats (sshd_config, crontab, /etc/hosts, application config files).
  • Partial content control via URL: The scan target URL appears verbatim in log output; combined with creative path targeting, this may enable injection into certain file formats.
  • No authentication required in the default deployment.
  • When dalfox runs under a privileged account (e.g., in a CI pipeline or as root in a container), the blast radius extends to system-wide files.

Recommended Remediation

Option 1: Strip filesystem-dangerous fields from API-sourced requests (preferred)

Nullify all fields that touch the local filesystem before passing options to ScanFromAPI. This is the same remediation recommended for the found-action RCE and custom-payload-file file-read findings and should be applied as a single consolidated patch:

// pkg/server/server.go — in postScanHandler, before ScanFromAPI:
rq.Options.OutputFile = ""
rq.Options.OutputAll = false          // safe to leave user value; file write is blocked by OutputFile=""
rq.Options.CustomPayloadFile = ""
rq.Options.CustomBlindXSSPayloadFile = ""
rq.Options.FoundAction = ""
rq.Options.FoundActionShell = ""
rq.Options.HarFilePath = ""

Option 2: Guard the file write with IsLibrary in DalLog

Move the OutputFile write block inside the else branch so it only executes in non-library (CLI) mode:

// internal/printing/logger.go — restructure the if-else:
if options.IsLibrary {
    options.ScanResult.Logs = append(options.ScanResult.Logs, text)
} else {
    // existing stderr printing logic...

    // file write belongs here, not after the if-else
    if options.OutputFile != "" && ftext != "" {
        f, err := os.OpenFile(options.OutputFile, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
        ...
    }
}

This fix addresses the root structural cause — the file write was intended for CLI mode only, and gating it on !IsLibrary matches that intent. Option 1 is still recommended as the primary fix; Option 2 adds defence-in-depth but requires care to not break legitimate CLI usage.

Option 3: Require --api-key at server startup

As with the other server-mode findings, making authentication mandatory eliminates the unauthenticated attack surface entirely:

// cmd/server.go — in runServerCmd:
if serverType == "rest" && apiKey == "" {
    fmt.Fprintln(os.Stderr, "ERROR: --api-key is required when running in REST server mode.")
    os.Exit(1)
}

All three options should be applied together.

Credit

Emmanuel David

Github:- https://github.com/drmingler.

Show details on source website

{
  "affected": [
    {
      "database_specific": {
        "last_known_affected_version_range": "\u003c= 2.12.0"
      },
      "package": {
        "ecosystem": "Go",
        "name": "github.com/hahwul/dalfox/v2"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "2.13.0"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-45089"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-306",
      "CWE-434",
      "CWE-73"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-05-12T15:08:27Z",
    "nvd_published_at": "2026-05-27T18:16:24Z",
    "severity": "HIGH"
  },
  "details": "## Summary\n\nWhen dalfox is run in REST API server mode, the `output`, `output-all`, and `debug` fields in `model.Options` are JSON-tagged and deserialized directly from the attacker\u0027s request body, then propagated unchanged through `dalfox.Initialize` into the scan engine\u0027s logging path. The logger opens the attacker-supplied path with `os.O_APPEND|os.O_CREATE|os.O_WRONLY` and writes scan log lines to it. Critically, this file write block lives outside the `IsLibrary` guard in `DalLog`, so it executes even in server/library mode where file output was never intended to operate. Because no API key is required in the default configuration, an unauthenticated network caller can create or append to any file writable by the dalfox process on the host filesystem.\n\n## Severity\n\n**High** (CVSS 3.1: 8.2)\n\n`CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:L`\n\n- **Attack Vector:** Network \u2014 server binds to `0.0.0.0:6664` by default.\n- **Attack Complexity:** Low \u2014 no preconditions; all trigger options (`output`, `output-all`, `debug`) are fully attacker-supplied in the JSON body.\n- **Privileges Required:** None \u2014 `--api-key` defaults to `\"\"`, so the auth middleware is never registered.\n- **User Interaction:** None.\n- **Scope:** Unchanged \u2014 the file write stays within the dalfox process\u0027s OS authority.\n- **Confidentiality Impact:** None \u2014 this is a write-only primitive; no data is returned to the caller.\n- **Integrity Impact:** High \u2014 the attacker has full control over which file path is opened, enabling creation of new files or corruption of existing files anywhere the dalfox process has write permission. While the log content format is semi-fixed, the file path is entirely attacker-determined, making the integrity violation complete with respect to file targeting.\n- **Availability Impact:** Low \u2014 corrupting application configuration files or log files on the host can degrade the availability of other services relying on those files.\n\n## Affected Component\n\n- `cmd/server.go` \u2014 `init()` (line 51): `--api-key` defaults to `\"\"` \u2014 no auth by default\n- `pkg/server/server.go` \u2014 `setupEchoServer()` (line 68): auth middleware only registered when `APIKey != \"\"`\n- `pkg/server/server.go` \u2014 `postScanHandler()` (lines 173\u2013191): `rq.Options` (including `OutputFile`, `OutputAll`, `Debug`) passed to `ScanFromAPI` without sanitization\n- `lib/func.go` \u2014 `Initialize()` (line 107): `OutputFile` explicitly propagated from caller options; `OutputAll` (line 167) and `Debug` (line 176) likewise\n- `internal/printing/logger.go` \u2014 `DalLog()` (lines 230\u2013244): `os.OpenFile(options.OutputFile, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)` executes outside the `IsLibrary` guard\n\n## CWE\n\n- **CWE-306**: Missing Authentication for Critical Function\n- **CWE-73**: External Control of File Name or Path\n- **CWE-434**: Unrestricted Upload of File with Dangerous Type (write-path variant)\n\n## Description\n\n### `output`, `output-all`, and `debug` Are Fully Attacker-Controlled\n\n`model.Options` exposes all three trigger fields with JSON tags:\n\n```go\n// pkg/model/options.go:88,85,88\nOutputFile  string `json:\"output,omitempty\"`\nOutputAll   bool   `json:\"output-all,omitempty\"`\nDebug       bool   `json:\"debug,omitempty\"`\n```\n\n`postScanHandler` binds the entire `Req.Options` from the JSON body and passes it directly to `ScanFromAPI`:\n\n```go\n// pkg/server/server.go:173-191\nrq := new(Req)\nif err := c.Bind(rq); err != nil { ... }\ngo ScanFromAPI(rq.URL, rq.Options, *options, sid)\n```\n\n`Initialize` explicitly copies all three fields into `newOptions`:\n\n```go\n// lib/func.go:107, 167, 176\n\"OutputFile\": {\u0026newOptions.OutputFile, options.OutputFile},\n...\n\"OutputAll\":  {\u0026newOptions.OutputAll, options.OutputAll},\n...\n\"Debug\":      {\u0026newOptions.Debug, options.Debug},\n```\n\n### The File Write Is Not Guarded by `IsLibrary`\n\n`Initialize` always sets `IsLibrary: true` (line 20) and `Silence: true` (line 44) in its returned options \u2014 the intent being that the scan engine runs in embedded/library mode during API calls, suppressing terminal I/O. `DalLog` does respect this for stderr output: lines 203\u2013228 route logs to `ScanResult.Logs` (not stderr) when `IsLibrary` is true. However, the file write block at lines 230\u2013244 is positioned **after and outside** that `if-else`:\n\n```go\n// internal/printing/logger.go\nmutex.Lock()\nif options.IsLibrary {\n    options.ScanResult.Logs = append(options.ScanResult.Logs, text)  // API path\n} else {\n    // stderr printing (CLI path)\n}\n\n// \u2190 file write is here, unconditionally \u2014 no IsLibrary check\nif options.OutputFile != \"\" {\n    var fdtext string\n    if ftext != \"\" {\n        fdtext = ftext\n        f, err := os.OpenFile(options.OutputFile,\n            os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)\n        if err != nil {\n            fmt.Fprintln(os.Stderr, \"output file error (file)\")\n        }\n        defer f.Close()\n        if _, err := f.WriteString(fdtext + \"\\n\"); err != nil {\n            fmt.Fprintln(os.Stderr, \"output file error (write)\")\n        }\n    }\n}\nmutex.Unlock()\n```\n\nThe `ftext` variable is populated whenever `allWrite` is true (`options.Debug || options.OutputAll`). Since both are attacker-supplied, both conditions are trivially satisfied.\n\n### What Gets Written\n\nLog lines of the form:\n\n```\n[*] Starting scan [SID:\u003cid\u003e] / URL: \u003cattacker-supplied-url\u003e\n[I] Checking BAV\n[E] connection refused\n[DEBUG] \u003cinternal state\u003e\n...\n```\n\nThe URL appears verbatim in log messages, giving the attacker partial influence over the written content. While the format is not fully arbitrary (fixed prefixes like `[*] `, `[I] `, `[E] `), the **file path is entirely attacker-controlled**. The flags `O_CREATE` (creates the file if absent) and `O_APPEND` (never truncates) mean the attacker can:\n- Create new files at arbitrary paths\n- Append log content to existing files (corrupting configs, auth files, cron entries if the line happens to match syntax)\n\n### No Defense at Any Layer\n\nThe same opt-in API key gap applies here as in all prior findings:\n\n```go\n// pkg/server/server.go:68-70\nif options.ServerType == \"rest\" \u0026\u0026 options.APIKey != \"\" {\n    e.Use(apiKeyAuth(options.APIKey, options))\n}\n```\n\nThere is no path allowlist, no `IsLibrary` guard on the file write, and no stripping of `OutputFile` from API-sourced requests anywhere in the codebase.\n\n## Proof of Concept\n\n```bash\n# Step 1 \u2014 Start dalfox REST server (default: no API key)\ngo run . server --host 127.0.0.1 --port 16664 --type rest\n\n# Step 2 \u2014 Verify health (unauthenticated)\ncurl -s http://127.0.0.1:16664/health\n# Expected: {\"code\":200,\"msg\":\"ok\"}\n\n# Step 3 \u2014 Trigger arbitrary file creation with attacker-controlled path\ncurl -s -X POST http://127.0.0.1:16664/scan \\\n  -H \u0027Content-Type: application/json\u0027 \\\n  --data \u0027{\n    \"url\": \"http://127.0.0.1:1/?x=1\",\n    \"options\": {\n      \"output\": \"/tmp/dalfox_sink_poc.log\",\n      \"output-all\": true,\n      \"debug\": true,\n      \"use-headless\": false\n    }\n  }\u0027\n\n# Step 4 \u2014 Verify file was created and written to by the dalfox process\nsleep 2\ncat /tmp/dalfox_sink_poc.log\n# Expected:\n# [*] Starting scan [SID:...] / URL: http://127.0.0.1:1/?x=1\n# [I] Checking BAV\n# [E] ...\n```\n\nNo `X-API-KEY` header is required. Replace `/tmp/dalfox_sink_poc.log` with any path writable by the dalfox process: `/var/www/html/injected.txt`, `/etc/cron.d/dalfox`, `~/.ssh/authorized_keys` (appending log lines that won\u0027t break key format but pollute the file), etc.\n\n## Impact\n\n- **Arbitrary file creation**: The attacker can create files at any path on the dalfox host filesystem accessible to the dalfox process, including web-serving directories, cron drop-in directories, and application config directories.\n- **Arbitrary file append/corruption**: Existing files can have log-format lines appended, degrading parsers that expect strict formats (sshd_config, crontab, /etc/hosts, application config files).\n- **Partial content control via URL**: The scan target URL appears verbatim in log output; combined with creative path targeting, this may enable injection into certain file formats.\n- **No authentication required** in the default deployment.\n- When dalfox runs under a privileged account (e.g., in a CI pipeline or as root in a container), the blast radius extends to system-wide files.\n\n## Recommended Remediation\n\n### Option 1: Strip filesystem-dangerous fields from API-sourced requests (preferred)\n\nNullify all fields that touch the local filesystem before passing options to `ScanFromAPI`. This is the same remediation recommended for the `found-action` RCE and `custom-payload-file` file-read findings and should be applied as a single consolidated patch:\n\n```go\n// pkg/server/server.go \u2014 in postScanHandler, before ScanFromAPI:\nrq.Options.OutputFile = \"\"\nrq.Options.OutputAll = false          // safe to leave user value; file write is blocked by OutputFile=\"\"\nrq.Options.CustomPayloadFile = \"\"\nrq.Options.CustomBlindXSSPayloadFile = \"\"\nrq.Options.FoundAction = \"\"\nrq.Options.FoundActionShell = \"\"\nrq.Options.HarFilePath = \"\"\n```\n\n### Option 2: Guard the file write with `IsLibrary` in `DalLog`\n\nMove the `OutputFile` write block inside the `else` branch so it only executes in non-library (CLI) mode:\n\n```go\n// internal/printing/logger.go \u2014 restructure the if-else:\nif options.IsLibrary {\n    options.ScanResult.Logs = append(options.ScanResult.Logs, text)\n} else {\n    // existing stderr printing logic...\n\n    // file write belongs here, not after the if-else\n    if options.OutputFile != \"\" \u0026\u0026 ftext != \"\" {\n        f, err := os.OpenFile(options.OutputFile, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)\n        ...\n    }\n}\n```\n\nThis fix addresses the root structural cause \u2014 the file write was intended for CLI mode only, and gating it on `!IsLibrary` matches that intent. Option 1 is still recommended as the primary fix; Option 2 adds defence-in-depth but requires care to not break legitimate CLI usage.\n\n### Option 3: Require `--api-key` at server startup\n\nAs with the other server-mode findings, making authentication mandatory eliminates the unauthenticated attack surface entirely:\n\n```go\n// cmd/server.go \u2014 in runServerCmd:\nif serverType == \"rest\" \u0026\u0026 apiKey == \"\" {\n    fmt.Fprintln(os.Stderr, \"ERROR: --api-key is required when running in REST server mode.\")\n    os.Exit(1)\n}\n```\n\nAll three options should be applied together.\n\n##Credit\n\nEmmanuel David\n\nGithub:- https://github.com/drmingler.",
  "id": "GHSA-8hf9-3q64-q2qf",
  "modified": "2026-06-08T23:50:06Z",
  "published": "2026-05-12T15:08:27Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/hahwul/dalfox/security/advisories/GHSA-8hf9-3q64-q2qf"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-45089"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/hahwul/dalfox"
    },
    {
      "type": "WEB",
      "url": "https://github.com/hahwul/dalfox/releases/tag/v2.13.0"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:L",
      "type": "CVSS_V3"
    }
  ],
  "summary": "Dalfox Server Mode has an Unauthenticated Arbitrary File Create/Append via `output` Option"
}

GHSA-8J7V-6G8V-2256

Vulnerability from github – Published: 2025-08-27 15:33 – Updated: 2025-08-27 15:33
VLAI
Details

A weakness has been identified in Campcodes Payroll Management System 1.0. The affected element is the function include of the file /index.php. This manipulation of the argument page causes file inclusion. The attack is possible to be carried out remotely. The exploit has been made available to the public and could be exploited.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2025-9529"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-73"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2025-08-27T14:15:56Z",
    "severity": "MODERATE"
  },
  "details": "A weakness has been identified in Campcodes Payroll Management System 1.0. The affected element is the function include of the file /index.php. This manipulation of the argument page causes file inclusion. The attack is possible to be carried out remotely. The exploit has been made available to the public and could be exploited.",
  "id": "GHSA-8j7v-6g8v-2256",
  "modified": "2025-08-27T15:33:15Z",
  "published": "2025-08-27T15:33:15Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2025-9529"
    },
    {
      "type": "WEB",
      "url": "https://github.com/chenjunjie3/cve/issues/6"
    },
    {
      "type": "WEB",
      "url": "https://vuldb.com/?ctiid.321548"
    },
    {
      "type": "WEB",
      "url": "https://vuldb.com/?id.321548"
    },
    {
      "type": "WEB",
      "url": "https://vuldb.com/?submit.635551"
    },
    {
      "type": "WEB",
      "url": "https://www.campcodes.com"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:L",
      "type": "CVSS_V3"
    },
    {
      "score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:L/VI:L/VA:L/SC:N/SI:N/SA:N/E:P/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X",
      "type": "CVSS_V4"
    }
  ]
}

GHSA-8JPV-7GWW-9R9J

Vulnerability from github – Published: 2026-04-15 00:31 – Updated: 2026-05-06 15:32
VLAI
Details

Unisys WebPerfect Image Suite versions 3.0.3960.22810 and 3.0.3960.22604 expose an unauthenticated WCF SOAP endpoint on TCP port 1208 that accepts unsanitized file paths in the ReadLicense action's LFName parameter, allowing remote attackers to trigger SMB connections and leak NTLMv2 machine-account hashes. Attackers can submit crafted SOAP requests with UNC paths to force the server to initiate outbound SMB connections, exposing authentication credentials that may be relayed for privilege escalation or lateral movement within the network.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2026-39907"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-73"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2026-04-14T22:16:32Z",
    "severity": "HIGH"
  },
  "details": "Unisys WebPerfect Image Suite versions 3.0.3960.22810 and 3.0.3960.22604 expose an unauthenticated WCF SOAP endpoint on TCP port 1208 that accepts unsanitized file paths in the ReadLicense action\u0027s LFName parameter, allowing remote attackers to trigger SMB connections and leak NTLMv2 machine-account hashes. Attackers can submit crafted SOAP requests with UNC paths to force the server to initiate outbound SMB connections, exposing authentication credentials that may be relayed for privilege escalation or lateral movement within the network.",
  "id": "GHSA-8jpv-7gww-9r9j",
  "modified": "2026-05-06T15:32:33Z",
  "published": "2026-04-15T00:31:35Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-39907"
    },
    {
      "type": "WEB",
      "url": "https://gist.github.com/VAMorales/be3e4ed472c51794493c1256cce16129"
    },
    {
      "type": "WEB",
      "url": "https://www.unisys.com/solutions/cai/applications"
    },
    {
      "type": "WEB",
      "url": "https://www.vulncheck.com/advisories/unisys-webperfect-image-suite-ntlmv2-hash-leakage-via-wcf-soap"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H",
      "type": "CVSS_V3"
    },
    {
      "score": "CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:L/VI:N/VA:N/SC:H/SI:H/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X",
      "type": "CVSS_V4"
    }
  ]
}

Mitigation
Architecture and Design

When the set of filenames is limited or known, create a mapping from a set of fixed input values (such as numeric IDs) to the actual filenames, and reject all other inputs. For example, ID 1 could map to "inbox.txt" and ID 2 could map to "profile.txt". Features such as the ESAPI AccessReferenceMap provide this capability.

Mitigation
Architecture and Design Operation
  • Run your code in a "jail" or similar sandbox environment that enforces strict boundaries between the process and the operating system. This may effectively restrict all access to files within a particular directory.
  • Examples include the Unix chroot jail and AppArmor. In general, managed code may provide some protection.
  • This may not be a feasible solution, and it only limits the impact to the operating system; the rest of your application may still be subject to compromise.
  • Be careful to avoid CWE-243 and other weaknesses related to jails.
Mitigation
Architecture and Design

For any security checks that are performed on the client side, ensure that these checks are duplicated on the server side, in order to avoid CWE-602. Attackers can bypass the client-side checks by modifying values after the checks have been performed, or by changing the client to remove the client-side checks entirely. Then, these modified values would be submitted to the server.

Mitigation MIT-5.1
Implementation

Strategy: Input Validation

  • Assume all input is malicious. Use an "accept known good" input validation strategy, i.e., use a list of acceptable inputs that strictly conform to specifications. Reject any input that does not strictly conform to specifications, or transform it into something that does.
  • When performing input validation, consider all potentially relevant properties, including length, type of input, the full range of acceptable values, missing or extra inputs, syntax, consistency across related fields, and conformance to business rules. As an example of business rule logic, "boat" may be syntactically valid because it only contains alphanumeric characters, but it is not valid if the input is only expected to contain colors such as "red" or "blue."
  • Do not rely exclusively on looking for malicious or malformed inputs. This is likely to miss at least one undesirable input, especially if the code's environment changes. This can give attackers enough room to bypass the intended validation. However, denylists can be useful for detecting potential attacks or determining which inputs are so malformed that they should be rejected outright.
  • When validating filenames, use stringent allowlists that limit the character set to be used. If feasible, only allow a single "." character in the filename to avoid weaknesses such as CWE-23, and exclude directory separators such as "/" to avoid CWE-36. Use a list of allowable file extensions, which will help to avoid CWE-434.
  • Do not rely exclusively on a filtering mechanism that removes potentially dangerous characters. This is equivalent to a denylist, which may be incomplete (CWE-184). For example, filtering "/" is insufficient protection if the filesystem also supports the use of "\" as a directory separator. Another possible error could occur when the filtering is applied in a way that still produces dangerous data (CWE-182). For example, if "../" sequences are removed from the ".../...//" string in a sequential fashion, two instances of "../" would be removed from the original string, but the remaining characters would still form the "../" string.
Mitigation
Implementation

Use a built-in path canonicalization function (such as realpath() in C) that produces the canonical version of the pathname, which effectively removes ".." sequences and symbolic links (CWE-23, CWE-59).

Mitigation
Installation Operation

Use OS-level permissions and run as a low-privileged user to limit the scope of any successful attack.

Mitigation
Operation Implementation

If you are using PHP, configure your application so that it does not use register_globals. During implementation, develop your application so that it does not rely on this feature, but be wary of implementing a register_globals emulation that is subject to weaknesses such as CWE-95, CWE-621, and similar issues.

Mitigation
Testing

Use tools and techniques that require manual (human) analysis, such as penetration testing, threat modeling, and interactive tools that allow the tester to record and modify an active session. These may be more effective than strictly automated techniques. This is especially the case with weaknesses that are related to design and business rules.

CAPEC-13: Subverting Environment Variable Values

The adversary directly or indirectly modifies environment variables used by or controlling the target software. The adversary's goal is to cause the target software to deviate from its expected operation in a manner that benefits the adversary.

CAPEC-267: Leverage Alternate Encoding

An adversary leverages the possibility to encode potentially harmful input or content used by applications such that the applications are ineffective at validating this encoding standard.

CAPEC-64: Using Slashes and URL Encoding Combined to Bypass Validation Logic

This attack targets the encoding of the URL combined with the encoding of the slash characters. An attacker can take advantage of the multiple ways of encoding a URL and abuse the interpretation of the URL. A URL may contain special character that need special syntax handling in order to be interpreted. Special characters are represented using a percentage character followed by two digits representing the octet code of the original character (%HEX-CODE). For instance US-ASCII space character would be represented with %20. This is often referred as escaped ending or percent-encoding. Since the server decodes the URL from the requests, it may restrict the access to some URL paths by validating and filtering out the URL requests it received. An attacker will try to craft an URL with a sequence of special characters which once interpreted by the server will be equivalent to a forbidden URL. It can be difficult to protect against this attack since the URL can contain other format of encoding such as UTF-8 encoding, Unicode-encoding, etc.

CAPEC-72: URL Encoding

This attack targets the encoding of the URL. An adversary can take advantage of the multiple way of encoding an URL and abuse the interpretation of the URL.

CAPEC-76: Manipulating Web Input to File System Calls

An attacker manipulates inputs to the target software which the target software passes to file system calls in the OS. The goal is to gain access to, and perhaps modify, areas of the file system that the target software did not intend to be accessible.

CAPEC-78: Using Escaped Slashes in Alternate Encoding

This attack targets the use of the backslash in alternate encoding. An adversary can provide a backslash as a leading character and causes a parser to believe that the next character is special. This is called an escape. By using that trick, the adversary tries to exploit alternate ways to encode the same character which leads to filter problems and opens avenues to attack.

CAPEC-79: Using Slashes in Alternate Encoding

This attack targets the encoding of the Slash characters. An adversary would try to exploit common filtering problems related to the use of the slashes characters to gain access to resources on the target host. Directory-driven systems, such as file systems and databases, typically use the slash character to indicate traversal between directories or other container components. For murky historical reasons, PCs (and, as a result, Microsoft OSs) choose to use a backslash, whereas the UNIX world typically makes use of the forward slash. The schizophrenic result is that many MS-based systems are required to understand both forms of the slash. This gives the adversary many opportunities to discover and abuse a number of common filtering problems. The goal of this pattern is to discover server software that only applies filters to one version, but not the other.

CAPEC-80: Using UTF-8 Encoding to Bypass Validation Logic

This attack is a specific variation on leveraging alternate encodings to bypass validation logic. This attack leverages the possibility to encode potentially harmful input in UTF-8 and submit it to applications not expecting or effective at validating this encoding standard making input filtering difficult. UTF-8 (8-bit UCS/Unicode Transformation Format) is a variable-length character encoding for Unicode. Legal UTF-8 characters are one to four bytes long. However, early version of the UTF-8 specification got some entries wrong (in some cases it permitted overlong characters). UTF-8 encoders are supposed to use the "shortest possible" encoding, but naive decoders may accept encodings that are longer than necessary. According to the RFC 3629, a particularly subtle form of this attack can be carried out against a parser which performs security-critical validity checks against the UTF-8 encoded form of its input, but interprets certain illegal octet sequences as characters.