Configuration & Environment
MCP server logs include PII (email, SSN, phone, credit-card, government ID) — log aggregators, third-party log services, and incident-response screenshots become a privacy breach surface. Sibling rules in the sensitive-data-exposure (CWE-532) family: MCP-202 (secrets to MCP responses) and MCP-306 (auth headers logged before auth check).
Logs travel further than developers expect: aggregators like Datadog, Sentry, and CloudWatch are reachable by every engineer, contractor, and on-call. PII landing in logs creates a compliance liability (GDPR, CCPA, HIPAA) and a real-world breach risk if any of those tools is itself compromised.
MCP tool inputs frequently contain user identifiers — emails to send to, phone numbers to look up, account IDs to query. Defensive logging (`logger.info("sending mail", to=email)`) trades one debugging convenience for a long tail of compliance work. The right pattern is to log a redacted/hashed identifier and a separate correlation ID.
@server.tool() |
def send_welcome(email: str) -> str: |
logger.info("sending welcome to %s", email) # PII in logs. |
send_email(email, ...) |
return "ok" |
import hashlib |
def hash_id(s: str) -> str: |
return hashlib.sha256(s.encode()).hexdigest()[:8] |
@server.tool() |
def send_welcome(email: str) -> str: |
logger.info("sending welcome", extra={"email_hash": hash_id(email)}) |
send_email(email, ...) |
return "ok" |
MCPSafe flags logger calls (`logger.*`, `print`, `console.log`) whose argument list contains identifiers with PII-suggesting names: `email`, `phone`, `ssn`, `address`, `dob`, `card`, `credit_card`, `iban`. Calls passing the value through a hash or redaction helper are exempted.
See the full threat catalog for every documented detection.
MCPSafe runs this check — and every other rule in the catalog — on any MCP server you paste in.
Scan now