T05 · Unauthorized Access and Privilege Escalation
- Location
email_briefing.py:10- Finding
Undeclared and Excessive Gmail Inbox Access
- Content
View full analysis
Vulnerability Details
File Location:
email_briefing.py, lines 10–11, 21–23, and 31–33
Vulnerability Type: Least-privilege violation through undeclared Gmail access
Risk Level: HighRelevant code:
python # Credentials from environment EMAIL = os.environ.get("GMAIL_EMAIL", "") # Set in ~/.openclaw/.env APP_PASSWORD = os.environ.get("GMAIL_APP_PASSWORD", "")python # Connect ctx = ssl.create_default_context() mail = imaplib.IMAP4_SSL(IMAP_SERVER, IMAP_PORT, ssl_context=ctx) mail.login(EMAIL, APP_PASSWORD) mail.select("INBOX")python for uid in mail_ids[-20:]: # last 20 status, msg_data = mail.fetch(uid, "(RFC822)") msg = emaillib.message_from_bytes(msg_data[0][1])Technical Analysis
SKILL.mddeclares a daily briefing covering weather, healthcare revenue-cycle news, Pittsburgh sports, and fantasy baseball. It does not declare email triage, Gmail authentication, or inbox processing. Nevertheless,email_briefing.pyobtains Gmail credentials from the process environment, authenticates to Gmail, selects the inbox, and retrieves up to 20 unread messages.The
RFC822fetch operation downloads complete messages, potentially including bodies and attachments. This exceeds the script's actual processing requirement because it only uses theSubject,From, andDateheaders for classification and display. The implementation therefore violates least privilege both at the feature level—email access is outside the documented Skill purpose—and at the data level—complete messages are retrieved when selected headers would suffice.The referenced
~/.openclaw/.envpath appears only in a comment. The code does not directly open, enumerate, or modify that file. Credentials are sent toimap.gmail.comover TLS using Python's certificate-validating default SSL context, and no attacker-controlled exfiltration endpoint was identified.Attack Path
- The Skil ...[truncated 1409 chars]
- Remediation
View remediation
Remediation Suggestions
- Remove
email_briefing.pyif email triage is not an intended part of the Morning Brief Skill. - If email triage is required, document it explicitly in
SKILL.md, including the accessed account, data categories, processing behavior, output destination, and retention risks, and require informed opt-in before requesting credentials. - Use a dedicated account or a narrowly scoped, revocable authorization mechanism where possible instead of an account-wide Gmail app password.
- Retrieve only the required headers rather than complete messages. For example, use an IMAP operation equivalent to:
python mail.fetch( uid, "(BODY.PEEK[HEADER.FIELDS (SUBJECT FROM DATE)])" ) - Avoid printing sensitive sender and subject metadata to persistent or shared logs. Send the minimum necessary briefing through an explicitly approved private destination.
- Validate both
GMAIL_EMAILandGMAIL_APP_PASSWORDbefore attempting authentication, and fail without exposing credential values. - Add robust checks for IMAP search and fetch statuses, malformed responses, and guaranteed logout through
try/finallyor a context manager. - Keep credentials in an approved secret manager or protected runtime injection mechanism, with restricted access, rotation, and revocation procedures.
- Remove
