SW-CFG-010: Literal value under a secret name in an MCP server configuration
Last updated 7 November 2026
| Fact | Value |
|---|---|
| Severity | High |
| Checks | Configuration file |
| Malicious indicator | No |
| OWASP Agentic Top 10 | None mapped |
| OWASP MCP Top 10 | MCP01, MCP07 |
| NIST SP 800-53 | IA-5 (provisional mapping to SP 800-53 base controls) |
| First shipped in | Scanner 0.3.0 |
What it detects
The rule reads each server of the MCP client files and looks at three places: each key of env, each header name, and each option of args together with its value, written as --flag=value or as --flag value. A name is secret-sounding when, split at every character that is not a letter or digit and at every change from lower to upper case (so apiKey is two words), it holds one of token, secret, password, passwd, pwd, credential, credentials, apikey, privatekey, authorization or cookie, or one of the pairs api key, access key, private key, client secret, auth token and bearer token.
A value under such a name fires when, after a leading Bearer or Basic word is dropped, it has at least eight characters, is not a reference (${NAME}, ${env:NAME}, ${input:ID} or $NAME) and is not wholly a placeholder (a run of x characters, dots or stars, a name in angle brackets, a word that starts with your, changeme or example). A value in a known credential shape is left to SW-CFG-002, so one value gives one finding. The evidence is the server and the field, followed by "holds a literal value"; the value itself is never shown.
Why it matters
A key or password written under a name like DATABASE_PASSWORD is a secret even when no pattern recognises its shape, and a person reading the file can see that at once. It is committed with the repository and stays in its history after the file is changed. The scanner maps this rule to OWASP MCP01, Token Mismanagement & Secret Exposure, and MCP07, Insufficient Authentication & Authorization, and to NIST SP 800-53 control IA-5, Authenticator Management, and it catches the passwords and internal tokens that the shape-based rule cannot.
Example
The server below sets DATABASE_PASSWORD to a plain value. The value has no known credential shape, so SW-CFG-002 stays quiet, but the name says what it is:
.mcp.json
{
"mcpServers": {
"reports": {
"command": "npx",
"args": [
"-y",
"reports-mcp@2.0.1"
],
"env": {
"DATABASE_PASSWORD": "dummy-password-0000"
}
}
}
}The evidence reads env.DATABASE_PASSWORD and says that it holds a literal value, with three stars in place of the value.
How to fix
Take the value out of the file, change the password at its source because the old one is in the history, and write a reference in its place. The rule accepts ${NAME}, ${env:NAME}, ${input:ID} and $NAME; your client decides which of them it expands.
If it is a false positive
The rule judges the name, not the meaning. A setting such as OAUTH_TOKEN_URL holds an address, not a token, and its name still contains the word token. Accept the finding with a note that says what the value is, or rename the setting if you control it.
If the finding is not a problem in your case, accept it with a note: in the dashboard a manager or owner can accept a finding and the note is kept with it; with the scanner on its own, add it to the baseline file with a reason and an expiry date.