Rules / CFG100
CFG100 Grok [plugins] turns plugins on or widens where they load from
Severity: warn
OWASP: LLM04:2026 – Supply Chain
OWASP Agentic: ASI04:2026 – Agentic Supply Chain Vulnerabilities: LLM04:2026 now covers the model and data supply chain and refers the agentic one, "including MCP servers and tool registries", to ASI04
What cfgaudit checks
xAI's settings reference states which tables a project .grok/config.toml may contribute: "Project .grok/config.toml only contributes [mcp_servers], [plugins], and [permission]." cfgaudit read one of the three. This rule covers the second.
| Field | Finding |
|---|---|
paths naming a directory inside the repository |
warn — the repository ships the plugin code and points the loader at it |
paths naming a directory outside it |
warn — a committed file points the loader somewhere contributors did not choose |
enabled |
warn — project plugins default to off, so a committed entry switches them on |
disabled |
never reported |
The direction comes from Grok's own documentation of the field: enabled is "explicitly enable plugins (useful when project plugins default off)". The parenthetical is the whole point. Project plugins default to off, so a committed enabled is the thing that turns them on rather than a restatement of the default.
disabled names plugins to discover but not activate, which is hardening. Reporting it would be the trap that caught Codex's exclude_slash_tmp and Cursor's disableTmpWrite, and a real committed config uses it exactly that way.
A file that both points paths at a repo-local directory and names the plugin in enabled gets one finding that says both, rather than two overlapping ones. That pairing is the sharpest case and it exists in the wild: one config carries paths = ["./plugins/soleur"] beside enabled = ["soleur"], with a comment describing it as the Grok equivalent of claude --plugin-dir.
Why this is reported at all, given folder trust
Grok gates hooks, MCP servers, LSP servers and plugins from a cloned repository behind folder trust (#385 established this). That is a real mitigant, and it is why every finding here is warn rather than error.
It is not a reason for silence, and the answer has to hold for the whole file rather than be decided per table. cfgaudit already reports [mcp_servers] from this same file under this same gate. Trust is one prompt covering everything the repository declares, granted to get any functionality at all; it is not consent to a specific plugin.
So both tables are reported, both at the severity the mitigant earns. The file no longer gets two different answers to one question.
[permission] stays declined, and for a reason folder trust has nothing to do with: its rules merge deny > ask > allow so a user's deny always beats a repository's allow, and argument matching is segmented. See the Grok section of the README.
Scope
Project scope only. A user-global ~/.grok/config.toml is the user's own choice, matching how CFG055 and CFG089 scope their equivalents.
Trigger example
[plugins]
paths = ["./plugins/soleur"]
enabled = ["soleur"]
→ one warn naming both halves.
Safe alternative
Leave the table out and let contributors install and enable plugins themselves. If the project genuinely ships a plugin, document how to install it rather than activating it from a committed file.
[plugins]
disabled = ["boardgame-io"]
Narrowing is not reported.
References
- CFG055 (Claude Code
enabledPlugins/extraKnownMarketplaces), CFG089 (Copilot's equivalents) — the same threat model on other agents - CFG098 (
marketplace.jsonplugin sources) — the author side of the same supply chain - OWASP LLM04:2026 – Supply Chain
Documentation for cfgaudit 1.18.1. Source of this page · Rule implementation