T05 · Unauthorized Access and Privilege Escalation
- Location
scripts/outlook_pywin32/calendar.py:19- Finding
Invalid Account Selection Silently Falls Back to the Default Calendar
- Content
View full analysis
Vulnerability Details
File Location:
scripts/outlook_pywin32/calendar.py:19-30andscripts/outlook_pywin32/calendar.py:233-244
Vulnerability Type: Fail-open account authorization boundary
Risk Level: MediumVulnerable 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_listandcalendar_editsilently 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
View 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.
