Threats Tagged 'cve-2026-61431'
View all threats tagged with 'cve-2026-61431'. Filter and sort to focus on specific types of threats.
Stop chasing alerts. Route them.
Start free, then upgrade once to turn Radar into an automated delivery engine for your security stack.
Custom feeds / Automations: email, Slack, webhooks, SIEM/MISP / API access (baseline limits)
API access activates after upgrading in Console -> Billing.
Check if your credentials are on the dark web
Instant breach scanning across billions of leaked records. Free tier available.
Filter Threats
Narrow down the results by type, severity, or affected countries
Threats Tagged 'cve-2026-61431'
Click on any threat for detailed analysis and mitigation recommendations
0 # ContextGatherer include resolution permits absolute and traversal reads outside the workspace ## Summary PraisonAI'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. ## Technical Details `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: ```python include_file = os.path.join(self.directory, '.praisoncontext') if os.path.exists(include_file): with open(include_file, 'r') as f: include_paths.extend( line.strip() for line in f if line.strip() and not line.startswith('#') ) ``` When `.praisoncontext` is present, `gather_context()` passes every include entry through `os.path.join(self.directory, include_path)` and then processes the result: ```python for include_path in self.include_paths: full_path = os.path.join(self.directory, include_path) process_path(full_path) ``` The `.praisoninclude` path has the same unsafe join after first processing the workspace: ```python process_path(self.directory) for include_path in self.include_paths: full_path = os.path.join(self.directory, include_path) process_path(full_path) ``` There 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: ```python with open(file_path, 'r', encoding='utf-8') as f: content = f.read() context.append( f"File: {file_path}\n\n{content}\n\n{'=' * 50}\n" ) self.included_files.append( Path(file_path).relative_to(self.directory) ) ``` For 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. ## PoV The minimal vulnerable shape is a workspace containing only a normal source file and one include file: ```text workspace/ .praisoncontext # contains: ../outside_secret.py inside.py outside_secret.py # outside the workspace ``` Running `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. ## PoC Save the self-contained script from the Appendix below as `context_include_workspace_pov.py`, then run it against a local checkout: ```bash export PRAISONAI=/path/to/PraisonAI PYTHONPATH="$PRAISONAI/src/praisonai" python context_include_workspace_pov.py ``` Expected vulnerable output: ```json { "expectations": { "control_inside_file_is_collected": true, "control_without_include_does_not_read_outside": true, "praisoncontext_absolute_path_discloses_outside": true, "praisoncontext_parent_traversal_discloses_outside": true, "praisoninclude_absolute_path_discloses_outside": true, "praisoninclude_parent_traversal_discloses_outside": true }, "source_commit": "1620b49f36945d8cc8ee5635b906c960df5097a0", "source_file": "$PRAISONAI/src/praisonai/praisonai/ui/context.py", "vulnerable": true } ``` The version sweep sampled old and current releases. All sampled versions are vulnerable: ```text {"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} {"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_ Join the discussion | CVE Database V5 | 10/08/2026, 17:58:30 UTC Added: 07/10/2026, 14:48:13 UTC |
Showing 1 to 1 of 1 result