T09 · Insecure Skill Coding Practices
- Location
scripts/fritz_status.py:13- Finding
Shared credential store and unrestricted router destination
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill’s router monitoring purpose is coherent, but it can immediately reboot, reconnect, or disable Wi-Fi and handles router credentials with weak scoping.
Review before installing. Use a dedicated low-privilege FRITZ!Box account where possible, keep credentials in a skill-specific file with restricted permissions, verify FRITZBOX_HOST points only to your router, and avoid letting agents run reboot, reconnect, wlan off, or calls without explicit confirmation. Pin dependencies or install in an isolated virtual environment.
scripts/fritz_status.py:13Shared credential store and unrestricted router destination
scripts/fritz_status.py:171Unvalidated call-list URL permits server-side request forgery and unsafe resource retrieval
scripts/fritz_status.py:135Router-wide destructive operations execute without runtime confirmation
requirements.txt:1Open-ended dependency versions create a supply-chain risk
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
#!/usr/bin/env python3
"""
FritzBox Status Checker
Lädt Credentials aus ~/.openclaw/skills/.env
"""
import os
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
#!/usr/bin/env python3
"""
FritzBox Status Checker
Lädt Credentials aus ~/.openclaw/skills/.env
"""
import os
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
#!/usr/bin/env python3
"""
FritzBox Status Checker
Lädt Credentials aus ~/.openclaw/skills/.env
"""
import os
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
#!/usr/bin/env python3
"""
FritzBox Status Checker
Lädt Credentials aus ~/.openclaw/skills/.env
"""
import os
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
from datetime import datetime
# Fallback: skill-lokales .env
SKILL_ENV = Path(__file__).parent.parent / ".env"
OPENCLAW_ENV = Path.home() / ".openclaw" / "skills" / ".env"
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
from datetime import datetime
# Fallback: skill-lokales .env
SKILL_ENV = Path(__file__).parent.parent / ".env"
OPENCLAW_ENV = Path.home() / ".openclaw" / "skills" / ".env"
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.
Create or update your ~/.openclaw/skills/.env file:
FRITZBOX_HOST=192.168.178.1
The skill documents use of environment secrets and direct network access to a local FRITZ!Box, but it declares no explicit tool scope or permission boundary. That omission increases the chance an agent can access secrets or invoke networked router-control actions without clear policy gating, which is especially risky because the documented capabilities include disruptive actions like reboot, reconnect, and WLAN changes.
The manifest description and the entire user-facing documentation are written in German, including command guidance and safety instructions, with no indication that language choice is optional. This creates a locale/language policy concern because the skill appears to require a specific language without explicit user opt-in or a documented region-specific need.
The calls command fetches and processes the router's call list, which contains sensitive personal communication metadata such as caller identities, timestamps, and durations. While the command help says it shows the call list, there is no explicit warning in code comments, prompts, or output that sensitive telephony data will be retrieved from the router.
The WLAN command performs immediate state changes across configured radios when given 'on' or 'off', without any confirmation or safety interlock. In an agent/automation context this is disruptive because it can instantly disconnect users and dependent devices, and may lock out remote administrators relying on Wi‑Fi.
The manifest describes status queries and control of the FRITZ!Box itself, specifically status, traffic, host lists, WLAN control, call lists, reconnect, and reboot. In the extension examples, the file documents DECT smart-home capabilities such as listing home automation devices and switching a smart plug, which expands the skill's apparent capability into controlling unrelated end devices in the home.
The manifest and earlier documentation describe access to call lists, which implies retrieval of stored call history. The call-monitoring section adds a distinct capability: live monitoring of incoming and outgoing call events, which is more privacy-sensitive and not stated in the declared purpose.
The dependency is specified with only a lower bound, so builds may resolve to different versions over time. This weakens reproducibility and can unintentionally pull in a later vulnerable or breaking release through normal dependency resolution.
fritzconnection>=1.15.0
python-dotenv>=1.0.0
python-dotenv is also unpinned, which means the installed version is not deterministic and may vary across environments or over time. In a skill that may handle local configuration and secrets, uncontrolled dependency drift increases the chance of introducing a vulnerable or incompatible release.
fritzconnection>=1.15.0
python-dotenv>=1.0.0
The manifest does not pin python-dotenv, and there are known advisories affecting some versions, so the project cannot demonstrate that it avoids those vulnerable releases. While the requirements file alone does not prove an exploitable condition, the uncertainty is a supply-chain risk, especially because dotenv libraries commonly interact with local files and environment-based secrets.
No suspicious patterns detected.