T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/baby_tracker.py:90
- Finding
- Sensitive Infant Health Data Is Stored Without Restrictive Filesystem Permissions## Vulnerability Details **File Location**: `scripts/baby_tracker.py:90-116`, `scripts/baby_tracker.py:234-235`, and `scripts/import_huckleberry.py:239-242` **Vulnerability Type**: Plaintext sensitive-data storage with process-default filesystem permissions **Risk Level**: Medium ### Vulnerable Code ```python def ensure_store(data_dir: Path) -> dict[str, Path]: paths = data_paths(data_dir) paths["dir"].mkdir(parents=True, exist_ok=True) paths["charts"].mkdir(parents=True, exist_ok=True) if not paths["events"].exists(): with paths["events"].open("w", newline="", encoding="utf-8") as f: csv.DictWriter(f, fieldnames=EVENT_HEADERS).writeheader() if not paths["metadata"].exists(): write_json(paths["metadata"], { "baby_id": "baby-1", "name": None, "date_of_birth": None, "sex": None, "timezone": "Europe/London", "notes": "Set name, date_of_birth, and sex for age-aware percentile charts.", }) if not paths["percentiles"].exists(): with paths["percentiles"].open("w", newline="", encoding="utf-8") as f: writer = csv.DictWriter(f, fieldnames=PERCENTILE_HEADERS) writer.writeheader() for sex, rows in APPROX_WEIGHT_PCTS.items(): for age_days, p3, p15, p50, p85, p97 in rows: writer.writerow({ "sex": sex, "age_days": age_days, "p3": p3, "p15": p15, "p50": p50, "p85": p85, "p97": p97, "unit": "kg", "source": "Approximate guide points; replace with exact WHO LMS data for clinical use.", }) return paths ``` Events are subsequently appended without setting or verifying a private mode: ```python with paths["events"].open("a", newline="", encoding="utf-8") as f: csv.DictWriter(f, fieldnames=EVENT_HEA ...[truncated 2412 chars]
- Remediation
- ## Remediation Suggestions - Create the tracker data directory and chart directory with mode `0700`. - Create `events.csv`, `metadata.json`, percentile files, and generated charts with mode `0600` where portability permits. - Use `os.open()` with explicit modes and safe creation flags when creating sensitive files, then wrap the descriptor with `os.fdopen()`. - Apply `os.chmod()` to newly created temporary metadata files before atomically replacing the destination. - On startup, inspect the permissions of existing data directories and sensitive files. Refuse to continue or issue a prominent warning if group or world access is present. - Avoid automatically changing permissions on user-selected directories without confirmation, but clearly report insecure modes. - Document that data is stored in plaintext. Consider optional encryption at rest for shared devices, synchronized folders, and backups. - Ensure generated charts receive the same confidentiality protections because they contain names, dates, measurements, and percentile information. - Add automated tests that initialize the tracker under a permissive umask and verify that sensitive directories and files remain private.
