T09 · Insecure Skill Coding Practices
- Location
scripts/build_story.py:37- Finding
Interview stories are stored without enforced access restrictions
- Content
View full analysis
Vulnerability Details
File Location:
scripts/build_story.py, lines 37-48
Vulnerability Type: Plaintext sensitive-data storage with permissions dependent on the process umask
Risk Level: MediumVulnerable Code
python stories_file = os.path.join(INTERVIEW_DIR, "stories.json") data = {"stories": []} if os.path.exists(stories_file): with open(stories_file, 'r') as f: data = json.load(f) data['stories'].append(story) ensure_dir() with open(stories_file, 'w') as f: json.dump(data, f, indent=2)The storage directory is created without an explicit restrictive mode:
python INTERVIEW_DIR = os.path.expanduser("~/.openclaw/workspace/memory/interview") def ensure_dir(): os.makedirs(INTERVIEW_DIR, exist_ok=True)Technical Analysis
The script persists user-supplied interview narratives—including situations, actions, results, lessons, and potentially confidential employer information—as unencrypted JSON. Neither the directory nor the file is explicitly restricted to the owning user.
os.makedirs()uses a default requested mode modified by the process umask, whileopen(..., 'w')creates a file with permissions similarly governed by the umask. Under a permissive runtime configuration, the resulting directory or file may be readable by other local users. Existing files with overly broad permissions are also reused without permission validation or correction.This weakens the Skill's stated guarantee that interview content is not shared. The issue is limited to local filesystem confidentiality; the audited script contains no network requests or remote exfiltration behavior.
Attack Path
- A user invokes
build_story.pyand supplies confidential interview or employment history. - The script creates
memory/interview/stories.jsonunder a process environment with a permissive umask, or reuses an existing file with broad permissions. - The story i ...[truncated 680 chars]
- A user invokes
- Remediation
View remediation
Remediation Suggestions
- Create the interview directory with owner-only permissions, such as mode
0700, and verify the mode even when the directory already exists. - Create new data files atomically with mode
0600, for example throughos.open()usingO_CREAT | O_EXCLand an explicit mode. - Apply
os.chmod(stories_file, 0o600)after securely opening an existing file, subject to appropriate error handling. - Write updates to a securely created temporary file in the same directory, flush and synchronize it, and atomically replace the destination to avoid partial writes.
- Consider optional encryption at rest if the operating environment includes untrusted administrators, backups, or shared storage.
- Implement and document retention and deletion controls consistent with the privacy claims in
SKILL.md.
- Create the interview directory with owner-only permissions, such as mode
