By the Knostic Research Team
Recommendation 1: Authentication is Not Optional—It's Your Front Door Lock
Leaving an MCP server without authentication is the digital equivalent of leaving your house unlocked in a bad neighborhood with a neon sign pointing to your jewelry box. The protocol now recommends OAuth 2.1, and you should treat this as a mandatory, non-negotiable baseline for any server exposed to the internet.
- How to Implement It: For machine-to-machine communication (like one of your internal services calling the MCP server), the Client Credentials Grant flow is the industry standard. This is a secure way for applications to authenticate without a user being present. Here's how it works:
- You register your client application (the service that will call your MCP server) with an Identity Provider (IdP) like Okta, Auth0, Microsoft Entra ID, or your own self-hosted solution.
- The IdP gives your client a unique client_id and a client_secret.
- When your client needs to talk to the MCP server, it first presents its ID and secret to the IdP's token endpoint.
- If the credentials are valid, the IdP issues a short-lived JSON Web Token (JWT), also known as an access token.
- The client then includes this token in the Authorization header of every request it makes to your MCP server (Authorization: Bearer <your_jwt>).
- Your MCP server, acting as a "Resource Server," must then validate this token on every single request. This involves checking the token's signature, its expiration date, and that it was issued by the correct authority (the IdP). Most web frameworks have mature libraries that make this validation straightforward.
- Simpler Alternatives (with Big Caveats): For internal projects or less critical servers that are not exposed to the public internet, a simple static API key can be a starting point. The client would pass a long, randomly generated secret key in a custom HTTP header (e.g., X-API-Key: <your_secret_key>). While better than nothing, be acutely aware that these keys are often long-lived and can be accidentally leaked in logs, code repositories, or CI/CD pipelines. If you use this method, you must have a documented plan for frequent key rotation.
- The Golden Rule: Regardless of the method, ensure all communication happens over HTTPS (TLS). Sending tokens or keys over an unencrypted channel is like shouting your password across a crowded room. Use a service like Let's Encrypt to get free, automatically renewing TLS certificates. There is no excuse for unencrypted traffic in 2024.
Recommendation 2: Embrace the Principle of Least Privilege (PoLP)—Don't Give a Screwdriver the Keys to the Kingdom
A common mistake is to grant an MCP server's tools overly broad permissions "just to make it work." This is a recipe for disaster. PoLP means every component of your system should have the absolute minimum level of access required to perform its function, and not an ounce more. Think of it as giving your house cleaner a key to the front door, not the master key that also opens your safe and your car.
- At the Tool Level: If a tool's purpose is to fetch user profiles, its database credentials should only have SELECT permissions on the users table. It should not have UPDATE, DELETE, or, heaven forbid, DROP TABLE rights. If a tool needs to write to a specific directory, its permissions should be limited to that directory alone, not the entire filesystem. Be granular.
- At the Process Level: The service account running the MCP server process itself should be a low-privilege user. It should not run as root or Administrator. If the server process is compromised, this containment measure can prevent an attacker from taking over the entire host machine.
- At the Network Level: Use network segmentation. Your MCP server should be in a firewalled-off network segment (a DMZ). Its firewall rules should be configured to deny all traffic by default and only allow connections from specific, trusted IP addresses on the specific ports it needs. It should only be able to initiate connections to the handful of internal services it's supposed to talk to (e.g., a specific database or internal API).
Recommendation 3: Become a Vigilant Watcher—You Can't Protect What You Can't See
An unmonitored server is a blind spot in your security posture. Comprehensive logging and alerting are non-negotiable for any production system, especially one as powerful as an MCP server.
- What to Log: Log everything. Every incoming request should generate a log entry containing the timestamp, source IP address, the full request path, the HTTP method, the user agent, and the response status code. For MCP-specific logging, record the method being called (tools/list, tools/call, etc.), the name of the tool invoked, and the parameters provided (while being careful to scrub any personally identifiable information or secrets from the logs). Most importantly, log all failed authentication attempts. These are the breadcrumbs an attacker leaves behind.
- What to Alert On: A single failed login is normal. A hundred failed logins from the same IP in one minute is an attack. Set up automated alerts for suspicious activity:
- A high volume of failed authentication attempts from a single IP or on a single account.
- Requests from unexpected or known malicious IP ranges (use threat intelligence feeds).
- An unusual number of tools/list requests, which can be a sign of an attacker performing reconnaissance to see what they can exploit.
- A spike in error rates from a specific tool, which could indicate an attempt to find a vulnerability through fuzzing.
- Centralize Your Logs: Use a Security Information and Event Management (SIEM) tool like Splunk, Datadog, or an open-source solution like the ELK Stack (Elasticsearch, Logstash, Kibana) to aggregate logs from your MCP server, firewall, and other systems. This allows you to correlate events across your entire infrastructure to spot complex, multi-stage attacks.
Recommendation 4: Sanitize Everything—Trust No Input
This is the cardinal rule of application security: treat all input as hostile. Every parameter that comes into one of your tools from an external source—even from an authenticated client—must be rigorously validated and sanitized before it's used.
- Prevent Injection Attacks: If a tool takes a parameter that will be used in a database query, you must use parameterized queries (prepared statements) to prevent SQL injection. Never, ever build a SQL query by concatenating strings with user input.
- Prevent Path Traversal: If a tool works with files, validate that the provided filename does not contain sequences like ../ that would allow an attacker to navigate outside the intended directory and read sensitive system files.
- Enforce Strict Typing and Formatting: If a tool expects an integer, ensure the input is an integer. If it expects a date, validate that it matches the correct format. This prevents a wide range of parsing errors and unexpected behaviors.
Read more about our experiments about how attackers can find unprotected MCP servers on the Internet here.
With your defenses in place, see how to scale discovery effortlessly in “Automating MCP Server Discovery with Claude Sonnet 4”.
New to our MCP deep dive? Catch up in order: begin with What is a ‘Model Context Protocol' Server in GenAI for the basics, learn discovery tactics in How to Find an MCP Server with Shodan, and peek under the hood in How MCP Servers Communicate.