T09 · Insecure Skill Coding Practices
- Location
scripts/healer.py:105- Finding
Malformed or Empty Lock Files Are Incorrectly Classified as Stale
- Content
View full analysis
Vulnerability Details
File Location:
scripts/healer.py, lines 105-119
Vulnerability Type: Fail-open lock ownership validation
Risk Level: MediumVulnerable Code
python # If no PID in file, try to get from filename pattern or stat if pid is None: # Use stat to get creation time stat = lock_path.stat() mtime = stat.st_mtime age_seconds = time.time() - mtime # Create lock info without PID return LockInfo( lock_path=lock_path, session_path=session_path, session_id=session_id, pid=0, is_alive=False, # Assume stale if we can't find PID age_seconds=age_seconds, agent_name=agent_name )Technical Analysis
When a lock file is empty, malformed, partially written, or does not contain a parseable PID, the implementation assigns
pid=0and unconditionally setsis_alive=False. Thehealoperation treats this value as proof that the lock is stale and can delete it.Failure to obtain ownership information is not equivalent to proving that the owner is dead. Lock metadata may be temporarily incomplete while an active process creates or updates the file. Consequently, the implementation fails open during an uncertain state.
This behavior also conflicts with the documented safety guarantee that locks belonging to active processes are not removed unless the user supplies
--force.Attack Path
- An active OpenClaw process creates a lock file that is empty, partially written, or contains metadata without a parseable PID.
- A user or automated task invokes
healer.py heal. _parse_lockcannot extract the PID and setsis_alive=False.healclassifies the lock as stale and deletes it without requiring--force.- Another process may enter the session while the original process still considers itself the owner.
- Concurrent access can corrupt session data or cause inconsisten ...[truncated 392 chars]
- Remediation
View remediation
Remediation Suggestions
- Represent missing or invalid ownership information as an explicit
UNKNOWNstate rather thanis_alive=False. - Never remove an unknown-owner lock during normal
healexecution. - Require an explicit
--forceoption to remove locks whose ownership cannot be verified. - Consider requiring both an age threshold and unavailable ownership before presenting such a lock as potentially stale.
- Re-read and validate the lock immediately before deletion to reduce time-of-check/time-of-use exposure.
- Use a lock protocol that writes ownership metadata atomically, such as writing to a temporary file and then using an atomic rename.
- Clearly report unknown ownership to the user instead of labeling the process as dead.
- Represent missing or invalid ownership information as an explicit
