T01 · Skill Instruction Hijacking
- Location
scripts/listener.py:165- Finding
Untrusted Email Content Is Forwarded Directly to the Agent Webhook
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This email listener appears purpose-built rather than malicious, but it needs review because it handles mailbox passwords, email content, and webhook tokens with several under-scoped safeguards.
Install only if you are comfortable with a long-running process that can access monitored mailboxes and wake your OpenClaw agent on incoming email. Prefer keyring or another secret manager, verify the config file is owner-only, keep the webhook URL on loopback or HTTPS to a trusted host, avoid forwarding body previews unless needed, and treat email-triggered agent actions as untrusted until confirmed.
scripts/listener.py:165Untrusted Email Content Is Forwarded Directly to the Agent Webhook
scripts/setup.py:78Arbitrary or Plaintext Webhook Destinations Can Receive Email Content and Authentication Tokens
scripts/setup.py:60Plaintext Credentials Are Written Without Enforced Restrictive File Permissions
README.md:23Dependencies and Skill Artifacts Are Installed Without Version, Hash, or Signature Verification
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
#### Supported Platforms
- **macOS**: Uses Keychain (OS-level encryption, user session)
- **Linux Desktop**: GNOME Keyring, KDE Wallet (user session)
- **Windows**: Credential Manager (OS-level encryption)
This rollback example retrieves passwords from the system keyring and writes them back into the JSON config as plaintext (account['password'] = password). Even though the intent is legitimate, the documented procedure materially weakens credential security by increasing exposure at rest if the file is later read, backed up, or mishandled.
for account in config['accounts']:
username = account['username']
password = keyring.get_password('imap-idle', username)
if password:
account['password'] = password
print(f'✅ Restored password for {username}')
Falling back to account_config.get('password') supports storing IMAP passwords in plaintext configuration files, increasing the risk of credential exposure through filesystem compromise, backups, or accidental disclosure. In an email-monitoring skill, compromise of these credentials grants direct mailbox access and can expose large volumes of sensitive communications.
self.logger.debug(f"🔐 Using keyring password for {username}")
return password
except Exception as e:
self.logger.warning(f"⚠️ Keyring access failed for {username}: {e}")
# Fall back to config file
password = account_config.get('password')
Falling back to reading IMAP passwords from the JSON config encourages plaintext credential storage on disk. If file permissions are weak, backups are exposed, or the host is shared, attackers can recover mailbox credentials and gain access to monitored accounts.
self.logger.debug(f"🔐 Using keyring password for {username}")
return password
except Exception as e:
self.logger.warning(f"⚠️ Keyring access failed for {username}: {e}")
# Fall back to config file
password = account_config.get('password')
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
import getpass
from pathlib import Path
# Optional keyring support
try:
import keyring
KEYRING_AVAILABLE = True
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
import getpass
from pathlib import Path
# Optional keyring support
try:
import keyring
KEYRING_AVAILABLE = True
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
import getpass
from pathlib import Path
# Optional keyring support
try:
import keyring
KEYRING_AVAILABLE = True
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
import getpass
from pathlib import Path
# Optional keyring support
try:
import keyring
KEYRING_AVAILABLE = True
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
import getpass
from pathlib import Path
# Optional keyring support
try:
import keyring
KEYRING_AVAILABLE = True
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
import getpass
from pathlib import Path
# Optional keyring support
try:
import keyring
KEYRING_AVAILABLE = True
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
import getpass
from pathlib import Path
# Optional keyring support
try:
import keyring
KEYRING_AVAILABLE = True
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
import getpass
from pathlib import Path
# Optional keyring support
try:
import keyring
KEYRING_AVAILABLE = True
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
import getpass
from pathlib import Path
# Optional keyring support
try:
import keyring
KEYRING_AVAILABLE = True
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
import getpass
from pathlib import Path
# Optional keyring support
try:
import keyring
KEYRING_AVAILABLE = True
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
import getpass
from pathlib import Path
# Optional keyring support
try:
import keyring
KEYRING_AVAILABLE = True
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
import getpass
from pathlib import Path
# Optional keyring support
try:
import keyring
KEYRING_AVAILABLE = True
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
import getpass
from pathlib import Path
# Optional keyring support
try:
import keyring
KEYRING_AVAILABLE = True
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
import getpass
from pathlib import Path
# Optional keyring support
try:
import keyring
KEYRING_AVAILABLE = True
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
import getpass
from pathlib import Path
# Optional keyring support
try:
import keyring
KEYRING_AVAILABLE = True
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
import getpass
from pathlib import Path
# Optional keyring support
try:
import keyring
KEYRING_AVAILABLE = True
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
import getpass
from pathlib import Path
# Optional keyring support
try:
import keyring
KEYRING_AVAILABLE = True
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
import getpass
from pathlib import Path
# Optional keyring support
try:
import keyring
KEYRING_AVAILABLE = True
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
import getpass
from pathlib import Path
# Optional keyring support
try:
import keyring
KEYRING_AVAILABLE = True
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
import getpass
from pathlib import Path
# Optional keyring support
try:
import keyring
KEYRING_AVAILABLE = True
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
import getpass
from pathlib import Path
# Optional keyring support
try:
import keyring
KEYRING_AVAILABLE = True
Detected: suspicious.exposed_secret_literal