title: MCP Server Security Policy Fail-Open on Initialization Failure (CVE-2026-16584)
id: ATR-2026-02402
rule_version: 1
status: experimental
description: |
  Detects the fail-open class of agent authorization failure: an MCP server or agent runtime whose policy / guardrail / consent enforcement data fails to load at startup, logs a warning, and KEEPS SERVING with per-request checks silently skipped for the lifetime of the process. Anchored on CVE-2026-16584 (CWE-455, Non-exit on Failed Initialization) in awslabs.aws-api-mcp-server >= 0.2.13, < 1.3.47: the read-only operations index is built from a live fetch of https://servicereference.us-east-1.amazonaws.com/, and a transient network or permission failure left READ_OPERATIONS_INDEX unset. Both the READ_OPERATIONS_ONLY denial and the REQUIRE_MUTATION_CONSENT elicitation prompt were then bypassed, so indirect prompt injection could drive `call_aws` into mutating AWS CLI operations with no consent record. The fix (1.3.47) refuses to start and denies at execution time instead. This is the third shape of human-approval bypass: nobody disabled the gate and nobody tricked the user — the gate died on its own and stayed quiet. Detection covers (a) the verbatim pre-fix degraded-start log line, (b) that line correlated with the server still executing AWS CLI commands, (c) the generic fail-open log shape for any policy/guardrail/consent loader that continues after an init failure, (d) explicit fail-open configuration knobs on a policy/guardrail/consent component, (e) an MCP exchange carrying a mutating call_aws command alongside an unenforced-policy marker, and (f) injected instructions that deliberately induce or exploit the degraded state.
author: ATR Community
date: 2026/07/28
schema_version: '0.1'
detection_tier: pattern
maturity: test
severity: high
references:
  owasp_llm:
    - LLM06:2025
  owasp_agentic:
    - ASI02:2026
    - ASI04:2026
  mitre_atlas:
    - AML.T0053 - AI Agent Tool Invocation
    - AML.T0051.001 - Indirect
  mitre_attack:
    - 'T1562.001 - Impair Defenses: Disable or Modify Tools'
    - 'T1078.004 - Valid Accounts: Cloud Accounts'
  cve:
    - CVE-2026-16584
  cwe:
    - CWE-455
    - CWE-636
    - CWE-863
  external:
    - https://advisories.gitlab.com/pypi/awslabs.aws-api-mcp-server/CVE-2026-16584/
    - https://github.com/awslabs/mcp/security/advisories/GHSA-29w2-fq35-v728
    - https://github.com/awslabs/mcp/commit/ab1bbebc097d674c1cdd4bd75a8f313be18473bf
metadata_provenance:
  cve: human-reviewed
  cwe: human-reviewed
  owasp_llm: human-reviewed
  owasp_agentic: human-reviewed
  mitre_atlas: human-reviewed
compliance:
  eu_ai_act:
    - article: '14'
      context: Article 14 human oversight is defeated when the consent elicitation that gates mutating operations stops firing because its backing index failed to load. The operator sees no prompt and no error, so the absence of oversight is indistinguishable from an approved action; detecting the degraded-start marker is what restores the operator's ability to know oversight is off.
      strength: primary
    - article: '15'
      context: 'Article 15 requires AI systems to be resilient against faults and errors. CVE-2026-16584 is the textbook counter-example: a recoverable transient fault in a startup fetch silently downgraded the system''s own access-control layer for the whole process lifetime instead of failing safe.'
      strength: primary
    - article: '12'
      context: Article 12 record-keeping is the only place a fail-open window leaves evidence. A deployment whose logs are not scanned for policy-loader failure lines cannot later reconstruct which mutating operations executed unenforced.
      strength: secondary
  nist_ai_rmf:
    - function: Manage
      subcategory: MG.2.4
      context: MANAGE 2.4 requires mechanisms to deactivate or recover systems that exhibit unintended behaviour. A policy engine that stays up after losing its enforcement data is exactly such a system; this rule supplies the runtime trigger for restarting or quarantining the MCP server rather than letting it serve degraded.
      strength: primary
    - function: Measure
      subcategory: MS.2.6
      context: MEASURE 2.6 (safety evaluation under expected and unexpected conditions) is supported by treating startup-fetch failure of the read-only operations index as a required negative test case, not an edge case tolerated with a warning.
      strength: primary
    - function: Map
      subcategory: MP.5.1
      context: MAP 5.1 asks which impacts are likely. For agent-driven cloud control planes the answer includes unauthorized mutating API calls executed during a silent enforcement outage; this failure mode must be entered in the AI risk register for every MCP server that loads policy data over the network.
      strength: secondary
    - function: Govern
      subcategory: GV.6.1
      context: GV.6.1 supplier risk management must cover third-party MCP servers whose security controls depend on a remote metadata fetch, with an explicit requirement that policy-load failure be fail-closed before the server is admitted to an agent toolchain.
      strength: secondary
  iso_42001:
    - clause: '8.1'
      context: Clause 8.1 operational planning and control requires that the operating state actually delivered matches the state that was planned. Pinning awslabs.aws-api-mcp-server to 1.3.47 or later, and alerting on policy-loader failure lines, are the two operational controls that keep the deployed enforcement state equal to the designed one.
      strength: primary
    - clause: '8.3'
      context: 'Clause 8.3 AI risk treatment: this rule is the detective control for the residual risk left by any policy engine whose enforcement data is fetched rather than embedded, including forks and vendored copies that never received the 1.3.47 fix.'
      strength: secondary
    - clause: '9.1'
      context: Clause 9.1 monitoring and measurement — a fail-open window produces no denial events, so absence of denials cannot be read as absence of risk; the loader-failure signal is the measurable indicator that must be monitored instead.
      strength: secondary
tags:
  category: privilege-escalation
  subcategory: policy-engine-fail-open
  scan_target: runtime
  confidence: high
agent_source:
  type: mcp_exchange
  framework:
    - aws-api-mcp-server
    - mcp
    - any
  provider:
    - any
detection:
  condition: any
  false_positives:
    - Security advisories, changelogs, incident write-ups or postmortems that quote the pre-fix log line verbatim including a trailing exception name. Layer 1 cannot tell a quoted log from an emitted one; scan_target is runtime specifically so static skill/doc scans do not load this rule.
    - Chaos-engineering or fault-injection suites that deliberately break the policy loader to prove the fail-closed path works. These produce genuine loader-failure lines by design.
    - Log aggregation pipelines that replay historical logs from a deployment that was already patched and restarted; the old degraded-start line is real but no longer actionable.
    - Non-security components that legitimately fail open by design and happen to sit within the layer 4 proximity window, for example an authorization-decision CACHE whose miss behaviour is 'continue to the origin policy engine' rather than 'allow the request'.
    - Vendor SDKs whose log wording places a policy noun after the load verb in a fail-CLOSED message that also contains an unrelated 'skipping' or 'ignoring' token within the layer 3 window.
  conditions:
    - field: content
      operator: regex
      value: (?i)failed to load read[ _\-]?operations[ _\-]?index\s*:\s*(?:error retrieving the service reference document|[\w.]{0,64}(?:error|exception|timeout|timed out|refused|unreachable|failure|failed|denied|resolve|connection|ssl|certificate|permission|no such file)\b)
      description: 'Pre-fix awslabs.aws-api-mcp-server degraded-start marker: read-only operations index failed to load and the process did not exit — policy enforcement is off for the process lifetime (CVE-2026-16584)'
    - field: content
      operator: regex
      value: (?i)failed to load read[ _\-]?operations[ _\-]?index\s*:[\s\S]{0,800}attempting to execute aws cli command
      description: Policy index load failure followed by continued AWS CLI execution in the same process — CVE-2026-16584 actively exploited window. The 800-character correlation budget means a busy or slow server pushes the execution line out of range; layer 1 still alerts on the loader failure, but this layer's exploitation evidence is lost.
    - field: content
      operator: regex
      value: (?i)(?:fail(?:ed|ure|ing)?|error|unable|could not|cannot|exception)[^\n]{0,64}(?:load(?:ing)?|initiali[sz]|fetch(?:ing)?|refresh(?:ing)?|pars(?:e|ing)|retriev(?:e|ing))[^\n]{0,64}(?:securit(?:y|ies)[ _\-]?polic|polic(?:y|ies)[ _\-]?(?:engine|index|bundle|store|data|document|file)|guardrail|read[ _\-]?only[ _\-]?operations|allow[ _\-]?list|deny[ _\-]?list|permission[ _\-]?(?:index|map|table)|consent[ _\-]?(?:list|polic)|tool[ _\-]?permission)[\s\S]{0,300}(?:without[ _\-]?(?:enforcement|validation|authoriz(?:ation)?|consent|approval|polic(?:y|ies)[ _\-]?check)|fail(?:ing|ed)?[ _\-]?open|not[ _\-]?(?:be[ _\-]?)?enforc(?:ed|ing)|no[ _\-]?longer[ _\-]?enforc(?:ed|ing)|un[ _\-]?enforced|enforcement[ _\-]?(?:is[ _\-]?)?(?:disabled|off|skipped|bypassed|suspended|unavailable|degraded)|allow(?:ing)?[ _\-]?all|degraded[ _\-]?mode|(?:continu(?:e|es|ing)|proceed(?:s|ing)?|start(?:s|ing|ed)?|serv(?:e|es|ing)|run(?:s|ning)?)[^\n]{0,40}(?:without[ _\-]?(?:enforcement|validation|authoriz|consent|approval|check)|anyway|regardless|unenforced|in[ _\-]?degraded)|(?:skipp?(?:ed|ing)|bypass(?:ed|ing)?|disabl(?:ed|ing)|ignor(?:e|ed|ing)|omitt?(?:ed|ing))[ _\-]?(?:all[ _\-]?|the[ _\-]?|any[ _\-]?|per[ _\-]?request[ _\-]?|further[ _\-]?|remaining[ _\-]?)?(?:polic(?:y|ies)|guardrail|consent|approval|authoriz|permission|enforcement|security[ _\-]?check|access[ _\-]?control|check)|(?:polic(?:y|ies)|guardrail|consent|approval|authoriz|permission|enforcement|security[ _\-]?check|access[ _\-]?control|check)[ _\-]?(?:check|prompt|gate|evaluation)?s?[ _\-]?(?:are[ _\-]?|is[ _\-]?|will[ _\-]?be[ _\-]?|were[ _\-]?)?(?:skipp?(?:ed|ing)|bypassed|disabled|not[ _\-]applied|not[ _\-]enforced))
      description: 'Generic fail-open: an agent policy/guardrail/consent loader reported an initialization failure and announced it is continuing without enforcement (CWE-455)'
    - field: content
      operator: regex
      value: (?i)(?:securit(?:y|ies)|guardrail|consent|approval|authoriz(?:ation|er)|authoris(?:ation|er)|enforcement|read[ _\-]?only|allow[ _\-]?list|deny[ _\-]?list|moderation|polic(?:y|ies)[ _\-]?(?:engine|enforcement|check|decision|gate|eval))[^\n]{0,64}["']?(?:fail[ _\-]?open|failure[ _\-]?mode|failure[ _\-]?polic(?:y|ies)|failure[ _\-]?action|on[ _\-]?(?:error|failure)|error[ _\-]?behaviou?r)["']?\s*[:=]\s*["']?(?:true|open|allow|permit|bypass|continue|ignore|skip|off)\b|["']?(?:fail[ _\-]?open|failure[ _\-]?mode|failure[ _\-]?polic(?:y|ies)|on[ _\-]?(?:polic(?:y|ies)|guardrail|consent)[ _\-]?(?:error|failure))["']?\s*[:=]\s*["']?(?:true|open|allow|permit|bypass|continue|ignore|skip)["']?[^\n]{0,64}(?:securit|guardrail|consent|approval|authoriz|enforcement|polic(?:y|ies)[ _\-]?(?:engine|enforcement|check|decision|gate))
      description: Configuration sets a policy / guardrail / consent component to fail open, so an enforcement outage silently becomes an allow-all window
    - field: tool_response
      operator: regex
      value: (?i)(?:polic(?:y|ies)|read[ _\-]?only|consent|guardrail|enforcement)[^\n]{0,48}(?:check|enforcement|prompt|gate|mode)?[^\n]{0,32}(?:skipp?(?:ed|ing)|bypassed|disabled|unavailable|not[ _\-]applied|not[ _\-]enforced|never[ _\-]applied)[\s\S]{0,600}["'](?:cli_command|command)["']\s*:\s*["']aws\s+[a-z0-9\-]{2,24}\s+(?:create|delete|put|update|attach|detach|modify|terminate|remove|revoke|authorize|associate|disassociate|enable|disable|replace|restore|publish|import|upload|assume|run|start|stop|reboot|register|deregister|tag|untag|send|invoke|apply|write|copy|rm|mv|cp|sync)[a-z0-9\-]{0,32}|["'](?:cli_command|command)["']\s*:\s*["']aws\s+[a-z0-9\-]{2,24}\s+(?:create|delete|put|update|attach|detach|modify|terminate|revoke|authorize|assume|rm|publish|invoke)[a-z0-9\-]{0,32}[\s\S]{0,600}(?:polic(?:y|ies)|read[ _\-]?only|consent|guardrail)[^\n]{0,48}(?:skipp?(?:ed|ing)|bypassed|disabled|not[ _\-]enforced)
      description: MCP exchange carries a mutating AWS CLI command together with an explicit policy/consent-not-enforced marker — privileged action executed inside a fail-open window
    - field: content
      operator: regex
      value: (?i)(?:block|blackhole|drop|deny|firewall|null[ _\-]?route|disconnect|cut[ _\-]?off|disable|sever)[^\n]{0,96}(?:servicereference[\w.\-]*\.amazonaws\.com|service[ _\-]?reference[ _\-]?(?:document|endpoint|url)|read[ _\-]?only[ _\-]?operations?[ _\-]?(?:index|list))|(?:if|when|once|should)[^\n]{0,64}(?:polic(?:y|ies)|consent|approval|guardrail|read[ _\-]?only[ _\-]?(?:index|list|operations))[^\n]{0,64}(?:fail|error|unavailable|did not load|does not load|not load(?:ed)?|is missing|cannot be loaded|skip)[^\n]{0,96}(?:(?:proceed|continue|execute|run|invoke)[^\n]{0,24}(?:anyway|regardless|nonetheless|without (?:consent|approval|asking|prompting|confirmation))|do it anyway|ignore (?:it|this|that|the (?:warning|error|failure)))
      description: Injected instruction that induces the policy-index load failure or tells the agent to proceed anyway once enforcement is unavailable
response:
  actions:
    - block_tool
    - require_human_review
    - alert
    - escalate
  auto_response_threshold: high
  message_template: |
    [ATR-2026-02402] HIGH: MCP security policy enforcement is FAIL-OPEN. The policy / read-only / consent enforcement data failed to initialize and the server kept serving, so per-request checks and consent prompts are silently skipped for the lifetime of this process (CVE-2026-16584 pattern, CWE-455). Treat every mutating operation executed since the loader failure as unauthorized until reviewed. Restart the MCP server once connectivity to its policy source is restored; upgrade awslabs.aws-api-mcp-server to 1.3.47 or later; scope the agent's IAM credentials to least privilege so IAM, not the MCP server, remains the enforcing boundary.
confidence: 82
