T09 · Insecure Skill Coding Practices
- Location
scripts/ews-mail.py:299- Finding
Path Traversal and Arbitrary File Overwrite Through Attachment Filenames
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill does what it claims for Exchange email, but its attachment download code can write outside the chosen folder and its headless Linux credential guidance weakens protection of mailbox credentials.
Install only if you trust this skill with full access to the configured Exchange mailbox and are comfortable reviewing its code. Avoid using attachment-download until filenames are sanitized and existing files are protected from overwrite. On headless Linux, do not store KEYRING_CRYPTFILE_PASSWORD in broadly readable config, shell profiles, logs, or service files; prefer a platform secret manager or tightly scoped secret injection.
scripts/ews-mail.py:299Path Traversal and Arbitrary File Overwrite Through Attachment Filenames
SKILL.md:9Security-Sensitive Dependencies Are Not Version or Hash Pinned
The Linux setup recommends keyrings.alt EncryptedKeyring with file-based encrypted secret storage on headless systems. While not inherently malicious, this backend is weaker operationally than a native secure secret store and can expand the attack surface if the host, file permissions, or master-password handling are weak.
# 安装依赖
pip3 install keyring exchangelib keyrings.alt
# 设置 master password 环境变量(用于加解密 EWS 密码)
# 在 ~/.openclaw/config.yaml 中添加:
The instructions recommend placing KEYRING_CRYPTFILE_PASSWORD in persistent configuration as an environment variable. Storing a master decryption password in config or process environment materially weakens the protection of the encrypted keyring because other local processes, service configs, crash dumps, or misconfigured logs may expose it.
# 设置 master password 环境变量(用于加解密 EWS 密码)
# 在 ~/.openclaw/config.yaml 中添加:
# env:
# KEYRING_CRYPTFILE_PASSWORD: "你自己定义的一个强密码"
#
# 或在 systemd service / 启动脚本中 export:
export KEYRING_CRYPTFILE_PASSWORD="你自己定义的一个强密码"
The guidance to export KEYRING_CRYPTFILE_PASSWORD in startup scripts or service environments encourages persistent plaintext secret exposure at the process/runtime layer. In enterprise or multi-user systems, such environment-based secret handling can be recovered through configuration disclosure, process inspection, support artifacts, or operational mistakes, enabling decryption of stored EWS credentials.
# KEYRING_CRYPTFILE_PASSWORD: "你自己定义的一个强密码"
#
# 或在 systemd service / 启动脚本中 export:
export KEYRING_CRYPTFILE_PASSWORD="你自己定义的一个强密码"
# 存储 EWS 密码(会用 AES 加密写入本地文件)
python3 ~/.openclaw/skills/ews-email/scripts/ews-mail.py setup
The anti-refusal language instructs the agent to never say it cannot read email content and insists on using message-read. Even though framed as operational guidance, this kind of coercive instruction can pressure an agent to bypass caution or contextual safety checks when handling sensitive mailbox data.
**`envelope-list` only shows subject lines and metadata. It does NOT contain the email body.**
**You MUST run `message-read` to get the actual email content. NEVER guess or summarize based on subject alone.**
**NEVER say you cannot read email content — you CAN, by running `message-read`.**
## Script Location
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
import urllib3
urllib3.disable_warnings()
KEYRING_SERVICE = "openclaw-ews-email"
SERVER = os.environ.get("EWS_SERVER", "")
EMAIL = os.environ.get("EWS_EMAIL", "")
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
import urllib3
urllib3.disable_warnings()
KEYRING_SERVICE = "openclaw-ews-email"
SERVER = os.environ.get("EWS_SERVER", "")
EMAIL = os.environ.get("EWS_EMAIL", "")
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
import urllib3
urllib3.disable_warnings()
KEYRING_SERVICE = "openclaw-ews-email"
SERVER = os.environ.get("EWS_SERVER", "")
EMAIL = os.environ.get("EWS_EMAIL", "")
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
import urllib3
urllib3.disable_warnings()
KEYRING_SERVICE = "openclaw-ews-email"
SERVER = os.environ.get("EWS_SERVER", "")
EMAIL = os.environ.get("EWS_EMAIL", "")
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
import urllib3
urllib3.disable_warnings()
KEYRING_SERVICE = "openclaw-ews-email"
SERVER = os.environ.get("EWS_SERVER", "")
EMAIL = os.environ.get("EWS_EMAIL", "")
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
import urllib3
urllib3.disable_warnings()
KEYRING_SERVICE = "openclaw-ews-email"
SERVER = os.environ.get("EWS_SERVER", "")
EMAIL = os.environ.get("EWS_EMAIL", "")
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
import urllib3
urllib3.disable_warnings()
KEYRING_SERVICE = "openclaw-ews-email"
SERVER = os.environ.get("EWS_SERVER", "")
EMAIL = os.environ.get("EWS_EMAIL", "")
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
SERVER = os.environ.get("EWS_SERVER", "")
EMAIL = os.environ.get("EWS_EMAIL", "")
def _init_keyring():
"""Initialize keyring backend. On headless Linux, use EncryptedKeyring with
master password from KEYRING_CRYPTFILE_PASSWORD env var."""
import keyring
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
SERVER = os.environ.get("EWS_SERVER", "")
EMAIL = os.environ.get("EWS_EMAIL", "")
def _init_keyring():
"""Initialize keyring backend. On headless Linux, use EncryptedKeyring with
master password from KEYRING_CRYPTFILE_PASSWORD env var."""
import keyring
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
SERVER = os.environ.get("EWS_SERVER", "")
EMAIL = os.environ.get("EWS_EMAIL", "")
def _init_keyring():
"""Initialize keyring backend. On headless Linux, use EncryptedKeyring with
master password from KEYRING_CRYPTFILE_PASSWORD env var."""
import keyring
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
SERVER = os.environ.get("EWS_SERVER", "")
EMAIL = os.environ.get("EWS_EMAIL", "")
def _init_keyring():
"""Initialize keyring backend. On headless Linux, use EncryptedKeyring with
master password from KEYRING_CRYPTFILE_PASSWORD env var."""
import keyring
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
SERVER = os.environ.get("EWS_SERVER", "")
EMAIL = os.environ.get("EWS_EMAIL", "")
def _init_keyring():
"""Initialize keyring backend. On headless Linux, use EncryptedKeyring with
master password from KEYRING_CRYPTFILE_PASSWORD env var."""
import keyring
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
SERVER = os.environ.get("EWS_SERVER", "")
EMAIL = os.environ.get("EWS_EMAIL", "")
def _init_keyring():
"""Initialize keyring backend. On headless Linux, use EncryptedKeyring with
master password from KEYRING_CRYPTFILE_PASSWORD env var."""
import keyring
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
SERVER = os.environ.get("EWS_SERVER", "")
EMAIL = os.environ.get("EWS_EMAIL", "")
def _init_keyring():
"""Initialize keyring backend. On headless Linux, use EncryptedKeyring with
master password from KEYRING_CRYPTFILE_PASSWORD env var."""
import keyring
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
SERVER = os.environ.get("EWS_SERVER", "")
EMAIL = os.environ.get("EWS_EMAIL", "")
def _init_keyring():
"""Initialize keyring backend. On headless Linux, use EncryptedKeyring with
master password from KEYRING_CRYPTFILE_PASSWORD env var."""
import keyring
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
SERVER = os.environ.get("EWS_SERVER", "")
EMAIL = os.environ.get("EWS_EMAIL", "")
def _init_keyring():
"""Initialize keyring backend. On headless Linux, use EncryptedKeyring with
master password from KEYRING_CRYPTFILE_PASSWORD env var."""
import keyring
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
SERVER = os.environ.get("EWS_SERVER", "")
EMAIL = os.environ.get("EWS_EMAIL", "")
def _init_keyring():
"""Initialize keyring backend. On headless Linux, use EncryptedKeyring with
master password from KEYRING_CRYPTFILE_PASSWORD env var."""
import keyring
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
SERVER = os.environ.get("EWS_SERVER", "")
EMAIL = os.environ.get("EWS_EMAIL", "")
def _init_keyring():
"""Initialize keyring backend. On headless Linux, use EncryptedKeyring with
master password from KEYRING_CRYPTFILE_PASSWORD env var."""
import keyring
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
SERVER = os.environ.get("EWS_SERVER", "")
EMAIL = os.environ.get("EWS_EMAIL", "")
def _init_keyring():
"""Initialize keyring backend. On headless Linux, use EncryptedKeyring with
master password from KEYRING_CRYPTFILE_PASSWORD env var."""
import keyring
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
SERVER = os.environ.get("EWS_SERVER", "")
EMAIL = os.environ.get("EWS_EMAIL", "")
def _init_keyring():
"""Initialize keyring backend. On headless Linux, use EncryptedKeyring with
master password from KEYRING_CRYPTFILE_PASSWORD env var."""
import keyring
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
SERVER = os.environ.get("EWS_SERVER", "")
EMAIL = os.environ.get("EWS_EMAIL", "")
def _init_keyring():
"""Initialize keyring backend. On headless Linux, use EncryptedKeyring with
master password from KEYRING_CRYPTFILE_PASSWORD env var."""
import keyring
No suspicious patterns detected.