Saving artifacts to a folder instead of overwriting#6
Conversation
EntelligenceAI PR SummaryRefactors Kubernetes AWS artifact handling to use per-deployment named subfolders and renames the helm values file, with supporting documentation, validation, and test updates.
Confidence Score: 2/5 - Changes NeededNot safe to merge — this PR introduces two meaningful vulnerabilities: a path traversal risk via Key Findings:
Files requiring special attention
|
| if output_dir is None: | ||
| cluster_name = str( | ||
| get_path( | ||
| load_config(config), | ||
| "cluster", | ||
| "name", | ||
| default="deepgram-self-hosted-cluster", | ||
| ) | ||
| ) | ||
| output_dir = artifacts_dir_for(cluster_name) |
There was a problem hiding this comment.
Move output_dir derivation inside the try block to catch load_config errors
load_config(config) at line 132 is outside the try/except (RuntimeError, ValueError) block. When --output-dir is omitted (the new default) and the config is not a YAML mapping, ValueError escapes unhandled as a raw traceback instead of printing [red]Could not render Kubernetes/AWS plan:[/red].
| if output_dir is None: | |
| cluster_name = str( | |
| get_path( | |
| load_config(config), | |
| "cluster", | |
| "name", | |
| default="deepgram-self-hosted-cluster", | |
| ) | |
| ) | |
| output_dir = artifacts_dir_for(cluster_name) | |
| try: | |
| if output_dir is None: | |
| cluster_name = str( | |
| get_path( | |
| load_config(config), | |
| "cluster", | |
| "name", | |
| default="deepgram-self-hosted-cluster", | |
| ) | |
| ) | |
| output_dir = artifacts_dir_for(cluster_name) |
Prompt to fix with AI
Copy this prompt into your AI coding assistant to fix this issue.
In src/deepgram_self_hosted/cli.py, the `if output_dir is None:` block (lines 129–138) that calls `load_config(config)` sits BEFORE the `try` block at line 139. If the config file is not a valid YAML mapping, `load_config` raises `ValueError` which is not caught, producing a raw traceback instead of the friendly error message. Fix: move the entire `if output_dir is None:` block to be the FIRST statement inside the `try` block (i.e., indent it one level further so it sits between `try:` and the existing `cluster_config, values = ...` call). The `try` block already catches `ValueError`, so the error will then be handled correctly.
| # Used for cluster name and artifact folder name. A subset of AWS EKS naming | ||
| # (alphanumeric + `-`) that is also filename-safe on Linux/macOS/Windows. | ||
| NAME_PATTERN = re.compile(r"^[A-Za-z0-9._-]+$") | ||
| NAME_HINT = "Use letters, digits, '.', '-', or '_' only." | ||
|
|
||
|
|
||
| def validate_name(value: str) -> bool | str: | ||
| """Questionary validator for cluster/folder names.""" | ||
| stripped = value.strip() | ||
| if not stripped: |
There was a problem hiding this comment.
validate_name allows '..' enabling path traversal into artifacts_dir_for
wizard.py's NAME_PATTERN (^[A-Za-z0-9._-]+$) accepts .. and . as valid names. kubernetes_aws.py passes the validated name directly to artifacts_dir_for(name) (paths.py), so artifacts_dir_for('..') resolves to kubernetes/aws/ — one level above the intended artifacts root — silently writing cluster-config, helm-values, and session files there.
| # Used for cluster name and artifact folder name. A subset of AWS EKS naming | |
| # (alphanumeric + `-`) that is also filename-safe on Linux/macOS/Windows. | |
| NAME_PATTERN = re.compile(r"^[A-Za-z0-9._-]+$") | |
| NAME_HINT = "Use letters, digits, '.', '-', or '_' only." | |
| def validate_name(value: str) -> bool | str: | |
| """Questionary validator for cluster/folder names.""" | |
| stripped = value.strip() | |
| if not stripped: | |
| NAME_PATTERN = re.compile(r"^[A-Za-z0-9][A-Za-z0-9_-]*(?:\.[A-Za-z0-9_-]+)*$") |
Prompt to fix with AI
Copy this prompt into your AI coding assistant to fix this issue.
In `src/deepgram_self_hosted/wizard.py`, tighten `NAME_PATTERN` so that `.` and `..` (and names starting/ending with a dot) are rejected. A minimal fix: require the name to start and end with an alphanumeric character, e.g. `re.compile(r'^[A-Za-z0-9][A-Za-z0-9._-]*[A-Za-z0-9]$|^[A-Za-z0-9]$')`. Add a test in `test_validate_name_rejects_unsafe_characters` for `validate_name('..')` and `validate_name('.')`. The validator is consumed by `_prompt_for_artifact_folder` in `kubernetes_aws.py` which passes the result straight to `artifacts_dir_for(name)` with no further sanitization.
No description provided.