Back to skill

Security audit

office secretary

Security checks for vulnerabilities and agentic risk

Overview

This M365 assistant is mostly coherent, but it asks for broad Microsoft Graph write permissions and stores delegated tokens locally even where implemented features appear read-only.

Review this before installing. Use a tenant test account first, reduce Graph permissions to the narrowest read/write scopes actually needed, avoid granting Files.ReadWrite or Calendars.ReadWrite unless write operations are added and intended, pin dependencies, and treat token_cache.bin as sensitive account access material.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
Findings (2)

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
secretary_engine.py:12
Finding

Excessive Microsoft Graph Delegated Permissions

Content
View full analysis

Vulnerability Details

File Location: secretary_engine.py:12-18; supporting documentation at SKILL.md:22-23
Vulnerability Type: Excessive OAuth permissions and violation of least privilege
Risk Level: Medium

Complete Vulnerable Code Snippet:

python
REQUIRED_SCOPES = [
    'User.Read',
    'Mail.ReadWrite',
    'Calendars.ReadWrite',
    'Files.ReadWrite',
    'ChatMessage.Send'
]

The corresponding setup instructions explicitly request the same broad write permissions:

markdown
2. **Permissions**: Grant Delegated `Mail.ReadWrite`, `Calendars.ReadWrite`, `Files.ReadWrite`, and `ChatMessage.Send`.

Technical Analysis

The application requests delegated Calendars.ReadWrite and Files.ReadWrite permissions even though the implemented calendar and Drive operations are read-only:

  • Calendar functionality calls me/calendar/getSchedule to retrieve availability.
  • Drive functionality lists root items and returns their names.
  • No implemented operation creates, modifies, moves, or deletes calendar or Drive content.

Consequently, the OAuth token has broader authority than the legitimate application behavior requires. The User.Read scope is also requested by the implementation but is not identified in the documented permission list.

Because this is a public-client application, the resulting delegated token is stored locally in token_cache.bin. Any party that compromises the host, token cache, or running process may be able to exercise all permissions represented by the token rather than being limited to the operations exposed by this script.

Attack Path

  1. A user registers the application and grants the delegated scopes specified by the project.
  2. The application completes interactive authentication and obtains a token containing calendar and file write permissions.
  3. MSAL serializes the authentication state into the local token cache.
  4. An attacker comp ...[truncated 1073 chars]
Remediation
View remediation

Remediation Suggestions

  1. Replace Calendars.ReadWrite with the narrowest delegated permission sufficient for the getSchedule operation.
  2. Replace Files.ReadWrite with the narrowest read-only permission sufficient to list the user's Drive item metadata.
  3. Retain Mail.ReadWrite only if assigning the Urgent category remains a required feature.
  4. Retain only the minimum Teams permission needed to post channel messages.
  5. Verify whether User.Read is required by the authentication flow or implemented features; remove it if unnecessary.
  6. Keep SKILL.md synchronized with the exact runtime scope list so users can make informed consent decisions.
  7. After reducing the scopes, revoke existing user consent and cached refresh tokens, then require reauthentication so previously issued broad tokens cannot continue to be used.
  8. Add automated tests or policy checks that compare each Graph endpoint against an approved minimum-scope allowlist.

T08 · Insecure Dependencies

Note
Location
requirements.txt:1
Finding

Unpinned Third-Party Python Dependencies

Content
View full analysis

Vulnerability Details

File Location: requirements.txt:1-3; duplicate unpinned declarations at SKILL.md:9
Vulnerability Type: Mutable and non-reproducible dependency resolution
Risk Level: Low

Complete Vulnerable Code Snippet:

text
msal
requests
python-dotenv

The Skill metadata also declares the packages without version constraints:

yaml
python_packages: ["msal", "requests", "python-dotenv"]

Technical Analysis

None of the project's third-party dependencies has an exact version or integrity hash. Package installation can therefore resolve to different releases over time. A future compromised, malicious, or unexpectedly incompatible release could enter the environment without any project change or review.

The reviewed package names are conventional and no evidence of typosquatting, dependency confusion, or a currently malicious package was identified. The risk arises from mutable dependency resolution and the absence of artifact integrity verification.

Attack Path

  1. An operator installs dependencies using requirements.txt or the Skill metadata.
  2. The package resolver queries its configured package index and selects the latest versions satisfying the unrestricted declarations.
  3. If a selected upstream release or package-distribution account has been compromised, the resolver downloads the affected artifact.
  4. Package installation hooks or imported package code execute in the installation or application context.
  5. Malicious dependency code gains the privileges of the user running the installation or the secretary application.
  6. In that context, it could access local files, environment variables, the Microsoft authentication cache, and data handled by the application.

Exploitation depends on compromise or unsafe substitution within the configured dependency source; no such compromise was demonstrated during this audit.

Impact Assessment

A malicious ...[truncated 420 chars]

Remediation
View remediation

Remediation Suggestions

  1. Pin every direct and transitive dependency to a reviewed, exact version.
  2. Generate a lock file or fully resolved requirements file in a controlled build environment.
  3. Record approved distribution hashes and install with pip --require-hashes.
  4. Configure package installation to use a trusted, explicitly selected index or an internally controlled package mirror.
  5. Run dependency vulnerability and provenance checks in continuous integration.
  6. Establish a controlled update process that reviews release notes, security advisories, and integrity metadata before changing pinned versions.
  7. Keep the dependency declarations in SKILL.md consistent with the locked dependency set, or make the lock file the authoritative installation source.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (18)

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · .gitignore (reported line 1)May include surrounding context.

text
.env
token_cache.bin
__pycache__/
*.pptx

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The description presents the skill as a secure M365 assistant for triage, calendar coordination, and governance, but the documented commands and setup grant broader high-impact behaviors including Teams posting, OneDrive file access, and write permissions to mail, calendar, and files. This mismatch can mislead reviewers and users into authorizing a skill with broader authority than its stated purpose suggests.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · secretary_engine.py (reported line 7)May include surrounding context.

python
# Configuration
BASE_DIR = os.path.dirname(__file__)
load_dotenv(os.path.join(BASE_DIR, '.env'))
CACHE_PATH = os.path.join(BASE_DIR, 'token_cache.bin')

# FIX: Removed 'Tasks.ReadWrite' to adhere to least-privilege requirements.

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · secretary_engine.py (reported line 27)May include surrounding context.

python
self.base_url = "https://graph.microsoft.com/v1.0"
        
        if not self.client_id or not self.tenant_id:
            raise ValueError("SECURITY ERROR: Missing SECRETARY_CLIENT_ID or SECRETARY_TENANT_ID in .env")

        self.cache = msal.SerializableTokenCache()
        self._load_cache()

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding

The skill advertises executable commands that use shell, network, environment variables, and likely file access, but it does not declare any explicit tool scope such as permissions or allowed-tools. This weakens containment and reviewability because operators cannot easily verify what capabilities the skill is expected to use before enabling it.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The skill requests and documents high-impact delegated permissions such as Mail.ReadWrite, Calendars.ReadWrite, Files.ReadWrite, and ChatMessage.Send, yet it does not warn users that it can modify mailbox content, alter calendars, access files, or send messages to Teams channels. Without prominent warnings and consent context, users may trigger sensitive actions without understanding their consequences.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
80% confidence
Finding

The skill loads environment-based configuration from a local .env file, and later accesses SECRETARY_CLIENT_ID and SECRETARY_TENANT_ID. In this code file there is no confirmation, print/log disclosure, or comment warning the user that credential-like configuration will be read at runtime.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The comments claim the scopes perfectly match documented features and least-privilege requirements, yet the code requests Files.ReadWrite and ChatMessage.Send, which exceed the stated manifest purpose. Misrepresenting permission necessity can cause over-privileged deployment and increases the blast radius if the skill is misused or compromised.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The generic call method sends authenticated HTTP requests to Microsoft Graph, and the surrounding methods use it to access email, calendar schedules, OneDrive metadata, and Teams messages. This file contains no confirmation prompt, visible disclosure, or user-facing warning before transmitting or retrieving potentially sensitive user and system data over the network.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The code can send Teams channel messages via post_teams, but the stated skill description only mentions triage, calendar coordination, and governance. This capability mismatch is dangerous because it hides an outbound communication action from users and reviewers, increasing the chance of unauthorized messaging or social-engineering abuse under trusted M365 credentials.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill can send Teams messages directly with post_teams and does so without any explicit confirmation or safety checks. In a workplace assistant, unchecked outbound messaging can be abused for impersonation, spam, or social engineering using the user's trusted identity.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

triage_mail automatically modifies mailbox state by re-categorizing high-importance messages as Urgent without any confirmation, dry-run mode, or policy guardrails. In an assistant context, silent mailbox mutation can mislabel messages, disrupt workflows, and be abused to alter user data under legitimate credentials.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

cleanup_drive accesses OneDrive contents by listing drive items older than 90 days, but the skill description does not disclose file-access behavior. Hidden file access expands the trust boundary beyond the declared purpose and may expose or enable actions on user storage data without informed consent.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
98% confidence
Finding

The dependency msal is unpinned, so installs may resolve to different versions over time, reducing build reproducibility and potentially pulling in a newly introduced vulnerable or breaking release. In a security-sensitive M365 assistant that likely handles authentication flows, uncontrolled dependency drift increases supply-chain risk.

Content

Scanner excerpt · requirements.txt (reported line 1)May include surrounding context.

text
msal
requests
python-dotenv

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
99% confidence
Finding

The dependency requests is unpinned, allowing package resolution to vary across environments and time. Because requests has multiple known advisories in some releases, failing to pin to a reviewed, patched version creates avoidable supply-chain and security exposure.

Content

Scanner excerpt · requirements.txt (reported line 2)May include surrounding context.

text
msal
requests
python-dotenv

Unverifiable Dependency: requests has 16 known advisory(ies) (CVE-2014-1830 (Exposure of Sensitive Information to an Unauthorized Actor in Requests); CVE-2024-47081 (Requests vulnerable to .netrc credentials leak via malicious URLs); CVE-2024-35195 (Requests `Session` object does not verify requests after making first request wi) +13 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
95% confidence
Finding

requests has known advisories in some versions, and because no version is pinned, there is no way to verify whether installation will select a patched or vulnerable release. In an assistant that likely makes outbound HTTP requests to Microsoft 365 or related services, a vulnerable HTTP client can expose credentials, request integrity, or sensitive metadata depending on the specific affected version.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
99% confidence
Finding

The dependency python-dotenv is unpinned, which makes the installed version non-deterministic and may introduce vulnerable releases into the environment. For a skill that may rely on environment-based secrets or configuration, dependency drift can directly affect how sensitive configuration files are read or modified.

Content

Scanner excerpt · requirements.txt (reported line 3)May include surrounding context.

text
msal
requests
python-dotenv

Unverifiable Dependency: python-dotenv has 2 known advisory(ies) (CVE-2026-28684 (python-dotenv: Symlink following in set_key allows arbitrary file overwrite via ); CVE-2026-28684 (python-dotenv reads key-value pairs from a .env file and can set them as environ)), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
94% confidence
Finding

python-dotenv has known advisories in some releases, and the absence of version pinning makes it impossible to establish whether a safe version will be installed. Given this skill's likely use of local environment files for secrets or configuration, a vulnerable dotenv library could increase the risk of unsafe file handling or secret exposure depending on how it is used elsewhere in the project.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.