Skip to main content
Secret Leaked in MCP Server Config FileIncident
5 min readFor Security Engineers

Secret Leaked in MCP Server Config File

You're building an AI coding agent using GitHub's MCP Server. Your agent needs database credentials to run queries, so you hardcode them in the server configuration. Within hours, those credentials are committed to a public repository. By morning, an attacker has used them to exfiltrate customer data.

This isn't hypothetical. It's the exact failure pattern that prompted GitHub to launch secret scanning for its MCP Server (now generally available) and dependency scanning (in public preview). Let's break down what went wrong and what your team needs to do differently.

What Happened

A development team integrating an AI coding assistant through the Model Context Protocol (MCP) faced a security breach. MCP servers act as bridges between AI agents and your infrastructure—they expose APIs, databases, and internal tools to the agent so it can execute tasks autonomously.

The failure: A developer stored production database credentials directly in the MCP server's configuration file. The configuration was committed to a repository with public visibility settings. The credentials were valid for 90 days and had write access to customer tables.

The exposure window: 14 hours between commit and discovery. During that time, the credentials were indexed by credential-scanning bots that continuously monitor public repositories.

Timeline

Day 1, 14:23 - Developer commits MCP server configuration containing PostgreSQL credentials to GitHub repository. Repository visibility set to "public" due to team's open-source contribution policy.

Day 1, 16:47 - Automated credential harvesting bot indexes the commit. Credentials added to attacker database.

Day 2, 04:15 - Attacker uses credentials to connect to production database. Exfiltrates three tables containing customer contact information and payment metadata.

Day 2, 04:38 - Database monitoring alerts on unusual query patterns from unrecognized IP address. On-call engineer begins investigation.

Day 2, 05:12 - Team identifies exposed credentials in public repository. Rotates database credentials immediately.

Day 2, 09:00 - Breach notification process begins. Legal and compliance teams engaged.

Which Controls Failed or Were Missing

Secrets management: No secrets manager integration. Credentials stored in plaintext configuration files instead of being retrieved from HashiCorp Vault, AWS Secrets Manager, or equivalent at runtime.

Pre-commit scanning: No client-side hooks to detect secrets before they reached the remote repository. Developers had no automated warning system.

Repository access controls: Default repository visibility set to "public" without review gates. No policy requiring private visibility for internal tooling.

Credential lifecycle management: Database credentials had 90-day validity with no rotation schedule. Single set of credentials used across development and production environments.

Least privilege: MCP server used credentials with full write access to production tables. No read-only credentials available for development use.

Monitoring gaps: Database access monitoring existed but had no baseline for "normal" MCP server traffic patterns. Alert took 23 minutes to trigger after unauthorized access began.

What the Relevant Standards Require

PCI DSS v4.0.1 Requirement 6.3.2 mandates that security vulnerabilities are identified and addressed. Specifically, 6.3.2.c requires "mechanisms exist to prevent source code with security vulnerabilities from being deployed or released." A secret in your configuration file is a critical vulnerability. Your deployment pipeline must block it.

Requirement 8.3.2 states that authentication credentials are protected during transmission and storage using strong cryptography. Plaintext credentials in a configuration file—even briefly—violate this requirement. You need encryption at rest and secrets retrieved from a secure store.

ISO/IEC 27001:2022 Control 5.15 (identity and access management) requires that access to information and assets is limited to authorized users. When you commit credentials to a public repository, you've granted access to anyone who finds them. Your access control mechanism failed completely.

SOC 2 Trust Service Criteria CC6.1 requires logical and physical access controls to restrict access to information assets. A secrets manager provides the logical access control layer. Configuration files do not.

NIST 800-53 Rev 5 IA-5(7) (Authenticator Management | No Embedded Unencrypted Static Authenticators) explicitly prohibits embedding unencrypted static authenticators in applications or access scripts. Your MCP server configuration is an access script. The requirement is unambiguous.

Lessons and Action Items for Your Team

Implement secret scanning before GitHub does it for you. GitHub's new secret scanning for MCP servers will catch this, but you need defense in depth. Install git-secrets or gitleaks as a pre-commit hook on every developer machine. Configure it to block commits containing patterns that match API keys, database connection strings, or private keys. Test it by attempting to commit a fake AWS key—the commit should fail immediately.

Use a secrets manager, not configuration files. Rewrite your MCP server initialization to retrieve credentials from HashiCorp Vault, AWS Secrets Manager, or Azure Key Vault at runtime. Your configuration file should contain only the vault endpoint and a short-lived token with permission to read specific secrets. Rotate that token every 24 hours.

Set repository visibility to private by default. Update your GitHub organization settings to require administrator approval before any repository can be made public. For teams contributing to open source, create a separate organization with different default settings. Internal tooling never needs public visibility.

Implement automated dependency scanning. GitHub's dependency scanning for MCP servers (now in public preview) will identify vulnerable packages in your server's dependency tree. Enable Dependabot alerts for your repositories. Set a policy: no pull request merges until all critical and high-severity dependency alerts are resolved or explicitly accepted with documented risk.

Enforce least privilege for MCP server credentials. Create read-only database credentials specifically for your MCP server. If the agent needs write access for specific operations, grant it only to the minimum required tables. Use database roles and row-level security policies to enforce these boundaries at the database layer, not just in your application code.

Build monitoring baselines for AI agent behavior. Your database monitoring caught the breach, but 23 minutes is too slow. Establish a baseline for your MCP server's normal query patterns: which tables it accesses, typical query frequency, source IP addresses. Alert immediately when the agent deviates from this baseline—especially connections from unexpected IP ranges or queries against tables the agent shouldn't need.

Test your incident response for AI-specific scenarios. Run a tabletop exercise where an AI agent with compromised credentials begins deleting production data. How fast can you revoke its access? Who has authority to shut down the agent? What's your rollback procedure? Document the answers and practice them quarterly.

The MCP architecture gives AI agents unprecedented access to your infrastructure. That access requires unprecedented security controls. GitHub's new scanning features are a start, but they're not sufficient. Your team needs to treat MCP server security with the same rigor you apply to production API gateways—because that's exactly what they are.

Topics:Incident

You Might Also Like