Only the latest release of ms-365-admin-mcp-server receives security updates. Older versions may contain vulnerabilities that have been fixed upstream.
| Version | Supported |
|---|---|
main |
Yes |
| < main | No |
Do not open a public GitHub issue for security vulnerabilities.
Instead, report privately via one of these channels:
- GitHub's private vulnerability reporting (preferred)
- Email the maintainer listed in the GitHub organization profile
Include in your report:
- A description of the vulnerability and its potential impact
- Steps to reproduce (proof-of-concept if possible)
- Affected version (commit SHA or release tag)
- Suggested remediation, if any
- Acknowledgment — within 5 business days
- Initial assessment — within 10 business days
- Fix and disclosure — coordinated with the reporter; typically within 90 days depending on severity
The following are in scope for security reports:
- Authentication and authorization bypass (stdio and HTTP transports)
- JWT validation flaws in HTTP mode (issuer, audience, signature, tenant, client ID)
- Token leakage in logs, error responses, or traces
- Path traversal, SSRF, or command injection via tool parameters
- Privilege escalation via unexpected Graph API calls
- Risk-level misclassification of write tools (e.g.
criticaloperation marked aslow) - Prompt-injection escapes from the
<graph_response_*>envelope (SEC-G02) — for example, attacker-controlled Graph response content causing the LLM to issue unauthorised tool calls despite the envelope preamble - Supply chain issues in direct dependencies
Out of scope:
- Issues requiring physical access to the MCP host
- Social engineering of MCP operators
- Denial-of-service via resource exhaustion on the local process (the server is expected to be run with OS-level limits)
- Vulnerabilities in Microsoft Graph API itself (report those to Microsoft MSRC)
If you run this server, we recommend:
- Least-privilege credentials. Grant only the Graph API application permissions you actually need. Use
--presetand--enabled-toolsto scope the tool surface. - Read-only by default. Do not pass
--allow-writesunless a scenario requires mutations. - Secret management. Store
MS365_ADMIN_MCP_CLIENT_SECRETin Azure Key Vault (MS365_ADMIN_MCP_KEYVAULT_URL), never in plain environment files committed to source control. - Certificate authentication. Prefer certificates over client secrets where possible (planned; see
CHANGELOG.md). - Secret rotation. Rotate client secrets every 90 days; federated credentials and managed identity remove this burden.
- HTTP mode exposure. Never expose the HTTP transport on
0.0.0.0without a reverse proxy enforcing TLS and additional authentication. Always pass--allowed-clientswith the minimum set of Entra app IDs. - Audit trail. Enable verbose logging (
-v) and forward logs to a SIEM. All Graph mutations are also auditable vialist-directory-auditsandlist-intune-audit-events. - Network segmentation. Run the server in a network segment that only permits egress to
login.microsoftonline.comandgraph.microsoft.com(or sovereign equivalents). - PII-aware logging. Pass
--log-redact-upnwhen logs are forwarded to a SIEM or external log forwarder. The flag replaces UPN values in log lines with a deterministic SHA-256 prefix (sha256:<16hex>), preserving forensic correlation while removing the work-email PII (see "Personal data handled by this server" below).
When the server runs in --oauth-mode, the following user-attributable values appear in normal operation. Operators in regulated jurisdictions (PIPEDA, RGPD, Loi 25, KVKK, UU PDP, etc.) should account for these in their DPIA / records-of-processing:
| Value | Source | Where it appears | Mitigation |
|---|---|---|---|
UPN (user@tenant.onmicrosoft.com or work email) |
User token upn / preferred_username claim |
Log lines on auth success and rejection in user-token-authorization.ts and http-server.ts |
--log-redact-upn replaces with sha256:<16hex> |
Entra oid |
User token oid claim |
Same log lines | None — oid is a tenant-scoped GUID, not PII per most regulators; required for incident attribution |
| Source IP | TCP connection / X-Forwarded-For (when trust proxy is set) |
Express access logs, rate-limit accounting | Sanitize at the reverse proxy / log forwarder if required |
| Bearer tokens | Inbound /mcp requests |
Never logged — only the authentication outcome | n/a |
| Tool call parameters | MCP tool invocations | Logged at info level with parameter names only, never values (graph-tools.ts) |
n/a |
| Graph API responses | Microsoft Graph | Returned to the caller, never logged | n/a |
Default Log Analytics retention in the included Bicep template is 30 days (parameter logRetentionDays). Lower this for stricter data-minimization regimes.
The Entra oid is intentionally not redacted: it is a non-PII GUID, audit teams need a stable forensic anchor, and pivoting from oid to a user requires directory access that an external log forwarder does not have.
The following defenses are already implemented (see inline SEC-* comments in src/):
- JWT signature verification via Microsoft JWKS (RS256), issuer, audience, tenant, and client ID checks (
src/token-validator.ts) - Rate limiting: 100 req/min on
/mcp(src/http-server.ts) - Security headers:
X-Content-Type-Options,X-Frame-Options: DENY,Cache-Control: no-store, CSPdefault-src 'none' - Body size limit: 100 KB
- Path parameter validation against traversal (
../,/,\,?,#,&) forskipEncodingparams - ReDoS protection:
--enabled-toolsregex capped at 500 chars - Sensitive data redacted from logs
- Tenant
commonrejected (single-tenant required for client credentials) - Non-root Docker user
- Sanitized query strings in error messages (no secret leakage)