T09 · Insecure Skill Coding Practices
- Location
scripts/screen_time.py:38- Finding
Screen-Time Records Are Created Without Restrictive File Permissions
- Content
View full analysis
Vulnerability Details
File Location:
scripts/screen_time.py, lines 38–72
Vulnerability Type: Insecure storage of sensitive child and behavioral data
Risk Level: MediumVulnerable Code
python DB_PATH = os.path.expanduser("~/.screen_time.json") # --- Database --- def load_db(): if os.path.exists(DB_PATH): with open(DB_PATH, "r") as f: return json.load(f) return {"children": {}} def save_db(db): with open(DB_PATH, "w") as f: json.dump(db, f, indent=2, default=str)Technical Analysis
The application stores children's names, ages, screen-use history, activities, behavioral rewards, deductions, and compliance information in
~/.screen_time.json. The database is written with a normalopen(..., "w")operation without explicitly enforcing owner-only permissions.When the file is first created, its effective permissions depend on the process umask. For example, a permissive or common multi-user configuration may create the file with mode
0644, making it readable by other local users if the home directory is traversable. More permissive umasks or shared-group environments can also make the file writable by unintended users.The application also does not inspect or repair the permissions of an existing database. Consequently, records remain exposed if the file was created with unsafe permissions, copied from another location, or manually assigned permissive access.
This is particularly relevant because the database concerns minors and can contain detailed behavioral and activity records. Although no passwords or authentication tokens are stored, the information has privacy and safeguarding implications.
Attack Path
- A parent runs a state-changing command such as
add-child,log,award, ordeducton a multi-user system. save_db()creates~/.screen_time.jsonusing the process's current umask rather than explicitly selecti ...[truncated 1504 chars]
- A parent runs a state-changing command such as
- Remediation
View remediation
Remediation Suggestions
Enforce owner-only permissions when creating and updating the database:
python import json import os import stat import tempfile def save_db(db): directory = os.path.dirname(DB_PATH) os.makedirs(directory, mode=0o700, exist_ok=True) fd, temporary_path = tempfile.mkstemp( prefix=".screen_time.", suffix=".tmp", dir=directory, ) try: os.fchmod(fd, 0o600) with os.fdopen(fd, "w", encoding="utf-8") as f: json.dump(db, f, indent=2, default=str) f.flush() os.fsync(f.fileno()) os.replace(temporary_path, DB_PATH) os.chmod(DB_PATH, 0o600) except Exception: try: os.unlink(temporary_path) except FileNotFoundError: pass raiseAdditional hardening measures should include:
- Validate the permissions of an existing database during startup and reject or repair group/world-accessible modes.
- Confirm that the database is a regular file owned by the current user before reading or replacing it.
- Use atomic replacement to reduce corruption from interrupted writes.
- Use explicit UTF-8 encoding for deterministic handling of names and activity descriptions.
- Document that the database contains private records concerning minors and should not be placed in shared directories.
- Consider optional encryption at rest where the host threat model includes administrators, shared backups, or device theft; restrictive permissions alone do not protect against those threats.
