T05 · Unauthorized Access and Privilege Escalation
Warning
- Location
- scripts/outlook_pywin32/calendar.py:19
- Finding
- Invalid Account Selection Silently Falls Back to the Default Calendar## Vulnerability Details **File Location**: `scripts/outlook_pywin32/calendar.py:19-30` and `scripts/outlook_pywin32/calendar.py:233-244` **Vulnerability Type**: Fail-open account authorization boundary **Risk Level**: Medium ### Vulnerable Code ```python if account: for acc in namespace.Accounts: if acc.SmtpAddress.lower() == account.lower(): store = acc.DeliveryStore calendar_folder = store.GetDefaultFolder(9) break else: # If the specified account is not found, use the default folder calendar_folder = namespace.GetDefaultFolder(9) else: calendar_folder = namespace.GetDefaultFolder(9) ``` The same fallback pattern is used by `calendar_edit`: ```python if account: for acc in namespace.Accounts: if acc.SmtpAddress.lower() == account.lower(): store = acc.DeliveryStore calendar_folder = store.GetDefaultFolder(9) break else: # If the specified account is not found, use the default folder calendar_folder = namespace.GetDefaultFolder(9) else: calendar_folder = namespace.GetDefaultFolder(9) ``` ### Technical Analysis When a caller explicitly supplies an Outlook account, the application searches the locally configured accounts for a matching SMTP address. If no match is found, both `calendar_list` and `calendar_edit` silently select the default calendar instead of rejecting the request. This is a fail-open account-selection behavior. An explicit account identifier establishes the intended mailbox boundary, so failure to resolve it should terminate the operation. Falling back to another mailbox violates that boundary and is inconsistent with `get_mail_folder`, which raises an exception when a requested mail account cannot be found. The edit operation is particularly sensitive because it searches the selected calendar for the first matching subject or start time and then modifies that item. The unintended fallba ...[truncated 1302 chars]
- Remediation
- ## Remediation Suggestions - Fail closed whenever an explicitly requested account cannot be found. - Create a shared strict account resolver and use it consistently for mail, calendar, and folder operations. - Never substitute the default mailbox when the caller supplied an account. - Return a clear error without exposing other configured account data. - Require both an immutable event identifier and the intended account for calendar edits where possible. - Add tests covering nonexistent accounts, case-insensitive matching, multiple accounts, and delegated stores. Example hardening: ```python def get_calendar_folder(namespace, account_email=None): if not account_email: return namespace.GetDefaultFolder(9) for account in namespace.Accounts: smtp_address = getattr(account, "SmtpAddress", "") if smtp_address.lower() == account_email.lower(): return account.DeliveryStore.GetDefaultFolder(9) raise ValueError(f"Outlook account not found: {account_email}") ``` Both listing and editing functions should call this resolver and terminate if it raises an error.
