ATR-2026-00112high權限提升experimental
Dynamic Module Loading for Code Execution
Detects dynamic module loading where the module path is a variable rather than a string literal. This pattern allows an attacker to control which code is loaded at runtime, enabling injection of malicious modules, WebAssembly payloads, or native libraries. Unlike static imports which are auditable, dynamic imports with variable paths can resolve to attacker-controlled code.
嚴重度
high
類別
權限提升
掃描目標
mcp
作者
ATR Community
建議回應
alertsnapshot
參考資料
OWASP Agentic
ASI05:2026 - Unexpected Code Execution
實地驗證
驗證日期
2026-04-08
樣本數
53,577
誤報率
0%
偵測條件
組合方式: any- 01Dynamic import() with variable path instead of string literal欄位: content運算子: regex
- 02Dynamic require() with variable path instead of string literal欄位: content運算子: regex
- 03Python dynamic import via __import__ or importlib欄位: content運算子: regex
- 04Native library dynamic loading via dlopen or LoadLibrary欄位: content運算子: regex
- 05WebAssembly module instantiation for running arbitrary compiled code欄位: content運算子: regex
攻擊範例(規則會觸發)
The tool loads plugins dynamically using import(pluginPath) where pluginPath is user-provided.
Uses require(moduleName) to load the requested handler at runtime.
Executes compiled code via WebAssembly.instantiate(wasmBuffer) for performance.
Loads the native extension using dlopen(libPath) to access system APIs.
The script uses importlib.import_module(user_input) to dynamically load the specified processing backend.
以上為真實攻擊 payload 脫敏版本。用於 regression testing。
正常樣本(規則不會觸發)
- Static string literal in dynamic import
The module uses import('lodash') to lazy-load the utility library. - Static string literal in require
Configuration is loaded with require('./config.json') at startup. - Discussion of module loading without any dynamic import syntax
The application uses a static configuration file to determine which modules are available at startup.
- Static string literal require calls with known package names - pattern 2 requires non-quote char after opening paren
We use require('express') and require('path') to set up our web server routes. - Discussion of WebAssembly concepts without the actual method call syntax (no dot-notation call pattern)
The WebAssembly specification defines how browsers can run compiled binaries efficiently. Our documentation covers the compile and instantiate lifecycle stages.
已知誤報情境
- ▸Plugin systems with allowlisted module paths
- ▸Legitimate lazy-loading of known application modules
- ▸Build tools or bundlers that use dynamic import() with computed chunk names for code-splitting optimization
- ▸Documentation or training materials that include code examples showing dynamic module loading patterns
- ▸Test harnesses that use importlib.import_module to load test fixtures from a controlled directory
已記錄的規避手法
- 手法: language switch
Carga el módulo dinámicamente usando cargar_modulo(ruta_usuario) para ejecutar código arbitrario en tiempo de ejecución.
Spanish description of dynamic module loading avoids English keywords like import, require, dlopen that the regex matches. - 手法: unicode homoglyph
The tool uses import(modulePath) to load attacker-controlled code at runtime.
Zero-width space (U+200B) inserted inside 'import' breaks the regex pattern match while appearing identical visually. - 手法: split keyword
The system fetches the module name from user input, then calls eval('req' + 'uire(' + varName + ')') to load it dynamically.The keyword 'require(' is split across string concatenation inside eval, so the regex never sees the intact require( pattern.
這些是公開記錄的繞過手法。誠實揭露限制,而不是假裝不存在。
完整 YAML 定義
在 GitHub 編輯 →title: Dynamic Module Loading for Code Execution
id: ATR-2026-00112
rule_version: 1
status: experimental
description: |
Detects dynamic module loading where the module path is a variable rather than a
string literal. This pattern allows an attacker to control which code is loaded at
runtime, enabling injection of malicious modules, WebAssembly payloads, or native
libraries. Unlike static imports which are auditable, dynamic imports with variable
paths can resolve to attacker-controlled code.
author: ATR Community
date: 2026/03/26
schema_version: "0.1"
detection_tier: pattern
maturity: experimental
severity: high
references:
owasp_agentic:
- ASI05:2026 - Unexpected Code Execution
mitre_attack:
- T1129 - Shared Modules
compliance:
eu_ai_act:
- article: "15"
context: "Dynamic module loading with user-controlled paths allows attackers to inject malicious modules, WebAssembly payloads, or native libraries into the agent runtime at execution time; Article 15 cybersecurity requirements mandate that AI systems restrict dynamic code loading to auditable, allowlisted sources."
strength: primary
- article: "14"
context: "Attacker-controlled module injection via dynamic imports can install persistent backdoors or override safety controls, undermining the reliability of human oversight mechanisms; Article 14 requires that agent behavior remain predictable and within the scope of authorized module execution."
strength: secondary
nist_ai_rmf:
- subcategory: "MP.5.1"
context: "Dynamic module loading with attacker-controlled paths is an adversarial input risk that allows injection of malicious modules, WebAssembly payloads, or native libraries into the agent runtime, bypassing static code auditing controls."
strength: primary
- subcategory: "MG.2.3"
context: "Risk treatment plans must restrict dynamic module loading to allowlisted paths and prohibit user-controlled inputs from influencing which code is resolved and executed at agent runtime."
strength: secondary
iso_42001:
- clause: "6.2"
context: "Risk treatment activities must address dynamic import exploitation by requiring that all externally-loaded modules are resolved against a verified allowlist before the agent runtime loads and executes them."
strength: primary
- clause: "8.5"
context: "Controls over externally-provided AI components must include validation of all dynamically loaded modules to ensure that attacker-controlled paths cannot introduce unauthorized code into the agent execution environment."
strength: secondary
tags:
category: privilege-escalation
subcategory: dynamic-import-exploitation
scan_target: mcp
confidence: medium
agent_source:
type: tool_call
framework:
- mcp
- langchain
- llamaindex
provider:
- any
detection:
conditions:
- field: content
operator: regex
value: (?i)import\(\s*[^'"][^)]*\)
description: Dynamic import() with variable path instead of string literal
- field: content
operator: regex
value: (?i)require\(\s*[^'"][^)]*\)
description: Dynamic require() with variable path instead of string literal
- field: content
operator: regex
value: (?i)(?:__import__|importlib\.import_module)\s*\(
description: Python dynamic import via __import__ or importlib
- field: content
operator: regex
value: (?i)(?:dlopen|LoadLibrary[AW]?)\s*\(
description: Native library dynamic loading via dlopen or LoadLibrary
- field: content
operator: regex
value: (?i)WebAssembly\.(?:instantiate|compile|instantiateStreaming)\s*\(
description: WebAssembly module instantiation for running arbitrary compiled code
condition: any
false_positives:
- Plugin systems with allowlisted module paths
- Legitimate lazy-loading of known application modules
- Build tools or bundlers that use dynamic import() with computed chunk names for code-splitting optimization
- Documentation or training materials that include code examples showing dynamic module loading patterns
- Test harnesses that use importlib.import_module to load test fixtures from a controlled directory
response:
actions:
- alert
- snapshot
confidence: 65
wild_validated: 2026/04/08
wild_samples: 53577
wild_fp_rate: 0
test_cases:
true_positives:
- input: The tool loads plugins dynamically using import(pluginPath) where pluginPath is user-provided.
tool_description: plugin-loader
expected: triggered
description: Dynamic import with user-controlled path
- input: Uses require(moduleName) to load the requested handler at runtime.
tool_description: module-loader
expected: triggered
description: Dynamic require with variable module name
- input: Executes compiled code via WebAssembly.instantiate(wasmBuffer) for performance.
tool_description: wasm-executor
expected: triggered
description: WebAssembly instantiation of arbitrary buffer
- input: Loads the native extension using dlopen(libPath) to access system APIs.
tool_description: native-loader
expected: triggered
description: Dynamic native library loading
- input: The script uses importlib.import_module(user_input) to dynamically load the specified processing backend.
expected: triggered
description: Python importlib dynamic import with user-controlled module name (matches pattern 3)
true_negatives:
- input: The module uses import('lodash') to lazy-load the utility library.
tool_description: module-loader
expected: not_triggered
description: Static string literal in dynamic import
- input: Configuration is loaded with require('./config.json') at startup.
tool_description: config-loader
expected: not_triggered
description: Static string literal in require
- input: The application uses a static configuration file to determine which modules are available at startup.
expected: not_triggered
description: Discussion of module loading without any dynamic import syntax
- input: We use require('express') and require('path') to set up our web server routes.
expected: not_triggered
description: >-
Static string literal require calls with known package names - pattern 2 requires non-quote char after opening
paren
- input: >-
The WebAssembly specification defines how browsers can run compiled binaries efficiently. Our documentation
covers the compile and instantiate lifecycle stages.
expected: not_triggered
description: Discussion of WebAssembly concepts without the actual method call syntax (no dot-notation call pattern)
evasion_tests:
- input: >-
Carga el módulo dinámicamente usando cargar_modulo(ruta_usuario) para ejecutar código arbitrario en tiempo de
ejecución.
expected: not_triggered
bypass_technique: language_switch
notes: >-
Spanish description of dynamic module loading avoids English keywords like import, require, dlopen that the regex
matches.
- input: The tool uses import(modulePath) to load attacker-controlled code at runtime.
expected: not_triggered
bypass_technique: unicode_homoglyph
notes: >-
Zero-width space (U+200B) inserted inside 'import' breaks the regex pattern match while appearing identical
visually.
- input: >-
The system fetches the module name from user input, then calls eval('req' + 'uire(' + varName + ')') to load it
dynamically.
expected: not_triggered
bypass_technique: split_keyword
notes: >-
The keyword 'require(' is split across string concatenation inside eval, so the regex never sees the intact
require( pattern.
更多 權限提升 規則
ATR-2026-00040criticalPrivilege Escalation and Admin Function AccessATR-2026-00041mediumAgent Scope Creep DetectionATR-2026-00064highOver-Permissioned MCP SkillATR-2026-00107highPrivilege Escalation via Delayed Task Execution BypassATR-2026-00110criticalRemote Code Execution via eval() and Dynamic Code Injection