T09 · Insecure Skill Coding Practices
- Location
scripts/health_manager.py:13- Finding
Sensitive health data is stored in plaintext files without enforced restrictive permissions
- Content
View full analysis
Vulnerability Details
File Locations:
scripts/health_manager.py:13-31scripts/health_storage.py:12-27
Vulnerability Type: Sensitive data exposure through insecure file permissions and plaintext storage
Risk Level: MediumVulnerable Code
scripts/health_manager.py:13-31:python DATA_DIR = Path.home() / ".health_data" def init_storage(): """Initialize storage directory and default files""" DATA_DIR.mkdir(exist_ok=True) files = { "profile.json": {}, "medications.json": [], "reminders.json": [], "records.json": [], "goals.json": { "daily_steps": 10000, "daily_water": 8, "daily_sleep": 8, "weekly_exercise": 150 } } for filename, default in files.items(): path = DATA_DIR / filename if not path.exists(): with open(path, 'w') as f: json.dump(default, f, indent=2)scripts/health_storage.py:12-27:python DATA_DIR = Path.home() / ".health_data" def init_storage(): """Initialize storage directory""" DATA_DIR.mkdir(exist_ok=True) # Create default files for file in ["medications.json", "reminders.json", "records.json", "profile.json"]: path = DATA_DIR / file if not path.exists(): with open(path, 'w') as f: if "records" in file: json.dump([], f) else: json.dump({}, f)Technical Analysis
Both storage implementations create
~/.health_dataand its JSON files using process-default permissions. Neither implementation specifies a restrictive directory mode such as0700, a file mode such as0600, nor repairs permissions on existing storage.The effective permissions therefore depend on the process umask. With a common umask of
022, ...[truncated 2393 chars]- Remediation
View remediation
Remediation Suggestions
-
Create the storage directory with owner-only access and repair the mode if it already exists:
python DATA_DIR.mkdir(mode=0o700, parents=True, exist_ok=True) DATA_DIR.chmod(0o700) -
Create new data files with mode
0600. Useos.openwhere exclusive and explicit creation permissions are required:python fd = os.open( path, os.O_WRONLY | os.O_CREAT | os.O_EXCL, 0o600, ) with os.fdopen(fd, "w", encoding="utf-8") as f: json.dump(default, f, indent=2) -
Correct permissions on existing files after validating that they are regular files owned by the current user:
python if path.exists(): if path.is_symlink() or not path.is_file(): raise RuntimeError(f"Unsafe storage path: {path}") if path.stat().st_uid != os.getuid(): raise PermissionError(f"Unexpected file owner: {path}") path.chmod(0o600) -
Use atomic writes to reduce corruption risk. Write to a securely created temporary file in the same directory, set mode
0600, flush and synchronize it, and then replace the destination withos.replace. -
Apply the same secure storage helper consistently in both modules instead of maintaining two separate initialization and write implementations.
-
For deployments with stronger confidentiality requirements, encrypt health records at rest using an authenticated encryption scheme. Store encryption keys in an operating-system credential store rather than alongside the JSON files.
-
Add automated tests that verify the directory is
0700, files are0600, symlinks are rejected, ownership is checked, and existing insecure permissions are repaired.
-
