Back to skill

Security audit

Agent Office

Security checks for vulnerabilities and agentic risk

Overview

This skill matches its local multi-agent office purpose, but it exposes powerful local agents through under-protected HTTP, mutable runtime installs, broad tool access, and unsafe path handling.

Install only if you are comfortable running persistent local AI workers that can call local CLIs, access workspaces, and potentially run shell-enabled DeerFlow tasks. Use it in a dedicated, low-sensitivity workspace, avoid external upstream URLs unless you fully trust them, keep MEMORY_CLI disabled for sensitive work, and do not use custom worker IDs or DeerFlow runtime updates without reviewing the exact paths and code source.

Vulnerability Patterns
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
Findings (5)

T05 · Unauthorized Access and Privilege Escalation

Error
Location
worker_server.py:220
Finding
Unauthenticated HTTP Task API Can Invoke Privileged Local Agents<![CDATA[ ## Vulnerability Details **File Location**: `worker_server.py:220-250`, `worker_server.py:314` **Vulnerability Type**: Missing authentication and authorization **Risk Level**: High ### Vulnerable Code ```python def do_POST(self): if self.path == "/tasks": length = int(self.headers.get("Content-Length", 0)) body = self.rfile.read(length).decode("utf-8", errors="replace") try: payload = json.loads(body) if body else {} except json.JSONDecodeError: self.send_json(400, {"error": "invalid json"}) return task_id = payload.get("task_id") or str(uuid.uuid4()) description = payload.get("description", "") title = payload.get("title") or description[:40] or "未命名任务" task_state = { "task_id": task_id, "status": "pending", "title": title, "created_at": now(), "updated_at": now() } with TASK_LOCK: ACTIVE_TASKS[task_id] = task_state thread = threading.Thread( target=self.server.execute_task, args=(task_id, title, description) ) thread.daemon = True thread.start() self.send_json(202, {"task_id": task_id, "status": "pending"}) ``` ```python super().__init__(("127.0.0.1", port), WorkerHandler) ``` ### Technical Analysis The task submission endpoint does not authenticate callers or check whether they are authorized to use the selected worker. Submitted task descriptions are subsequently passed to OpenClaw, Hermes, DeerFlow, an arbitrary configured CLI, or an external worker. Although the server binds to loopback, loopback binding is not an authentication boundary. Other local processes can access the endpoint. A malicious website may also be able to issue a simple cross-origin request by using a permitted content type, because the server parses the body as JSON without validating `Content-Type` or `Origin`. Th ...[truncated 1618 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Generate a cryptographically random authentication token for each worker. 2. Require `Authorization: Bearer <token>` for task submission, task status, task results, and state endpoints. 3. Store tokens with restrictive filesystem permissions and never place them in logs. 4. Reject requests with unexpected `Origin` headers and require `Content-Type: application/json`. 5. Generate task identifiers exclusively on the server; do not accept caller-selected IDs. 6. Add maximum request-body sizes, task concurrency limits, and rate limits. 7. Run each worker under a restricted operating-system identity or sandbox. 8. Restrict each engine to the minimum filesystem and command capabilities required for its role. 9. Consider using a Unix-domain socket with filesystem permissions instead of an unauthenticated TCP endpoint. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
worker_server.py:733
Finding
External Worker Bridge Can Disclose Tasks and Shared Memory to Arbitrary Destinations<![CDATA[ ## Vulnerability Details **File Location**: `scripts/add_worker.py:241-271`, `worker_server.py:472-500`, `worker_server.py:733-778` **Vulnerability Type**: Unrestricted outbound destination and plaintext sensitive-data forwarding **Risk Level**: High ### Vulnerable Code ```python def normalize_external_upstream_url(url: str, port: int = 0) -> str: raw = (url or "").strip() if not raw and port: raw = f"http://127.0.0.1:{port}" if not raw: return "" if "://" not in raw: raw = f"http://{raw}" return raw.rstrip("/") ``` ```python def _build_external_description(self, title, description, memory_matches=None): sections = [ f"这是 Agent Office 转发给外部员工 {self.worker_name} 的任务。", "请保持你原有身份、设定和长期记忆,不要把自己重置成新的角色。", "", "任务标题:" + (title or "(无标题)"), "任务描述:" + (description or "(无描述)"), "", "办公室补充上下文:", self._build_shared_memory_context(memory_matches), ] return "\n".join(sections).strip() ``` ```python def _external_request(self, method, path, payload=None, timeout=15): if not self.external_upstream_url: raise RuntimeError("external upstream url 未配置") url = f"{self.external_upstream_url}{path}" body = None headers = {} if payload is not None: body = json.dumps(payload, ensure_ascii=False).encode("utf-8") headers["Content-Type"] = "application/json" req = request.Request(url, data=body, headers=headers, method=method.upper()) with request.urlopen(req, timeout=timeout) as resp: raw = resp.read().decode("utf-8") return resp.status, json.loads(raw) if raw else {} ``` ```python _, submit_payload = self._external_request( "POST", "/tasks", { "title": title or "Agent Office 转发任务", "description": forwarded_description, }, timeout=min(15, self.external_timeout), ) ``` ### Technical Analysis The external-worker feature is documented primarily as a b ...[truncated 1966 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Restrict external upstreams to loopback addresses by default. 2. Resolve hostnames and validate every resolved address before connecting. 3. Reject remote, link-local, metadata-service, multicast, and other special-purpose addresses unless explicitly authorized. 4. Disable redirects or revalidate the destination after every redirect. 5. Require HTTPS for non-loopback destinations. 6. Add authenticated upstream communication, such as bearer tokens or mutual TLS. 7. Make shared-memory forwarding disabled by default and require explicit per-worker consent. 8. Redact likely secrets before forwarding tasks or memory. 9. Display the final normalized destination and the data categories that will be sent before creating the bridge. 10. Store a destination allowlist in protected local configuration rather than accepting unrestricted URLs. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/add_worker.py:572
Finding
Unvalidated Worker Identifiers Allow Directory Traversal and Recursive Deletion<![CDATA[ ## Vulnerability Details **File Location**: `scripts/add_worker.py:572-593`, `deerflow_runtime.py:46-47`, `scripts/remove_worker.py:102-114` **Vulnerability Type**: Path traversal and unsafe recursive deletion **Risk Level**: High ### Vulnerable Code ```python worker_id = worker_id_override or pinyin(name) print(f"🔍 检查 {engine} 运行环境...") state = load_state() check_duplicate(state, name, worker_id, engine) ``` ```python worker_dir = OFFICE_DIR / "workers" / worker_id worker_dir.mkdir(parents=True, exist_ok=True) (worker_dir / "logs").mkdir(exist_ok=True) ``` ```python def worker_home(worker_id: str, base_dir: Path | None = None) -> Path: return runtime_homes_root(base_dir) / worker_id ``` ```python worker_dir = OFFICE_DIR / "workers" / wid if worker_dir.exists(): import shutil shutil.rmtree(worker_dir) print(f"✅ 目录已删除: {worker_dir}") if engine == "deerflow": home_dir = Path(worker.get("deerflow_home") or worker_home(wid)) if home_dir.exists(): import shutil shutil.rmtree(home_dir) print(f"✅ DeerFlow home 已删除: {home_dir}") ``` ### Technical Analysis The command-line option `--worker-id` is used directly as a filesystem path component. It is not validated against an identifier grammar and is not rejected when it contains path separators, `..` components, or an absolute path. With `pathlib`, joining a base path with an absolute child discards the base. Relative traversal components can likewise resolve outside the intended worker directory. The escaped path is persisted in state and is later trusted during worker removal. The removal logic calls `shutil.rmtree()` without resolving the target and checking that it remains under the expected office root. For DeerFlow workers, the persisted `deerflow_home` value is also used directly as a recursive-deletion target. ### Attack Path 1. An attacker or unsafe automation invokes worker creation with a crafted value such as `--worker-id ../../target`. 2. ...[truncated 1012 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Validate every worker ID with a strict expression such as `^[a-z0-9][a-z0-9_-]{0,63}$`. 2. Reject absolute paths, path separators, empty identifiers, `.` components, and `..` components. 3. Resolve every target before filesystem operations: ```python root = (OFFICE_DIR / "workers").resolve() target = (root / worker_id).resolve() if target.parent != root: raise ValueError("Invalid worker ID") ``` 4. Apply equivalent containment checks to DeerFlow home directories. 5. Never recursively delete a path loaded directly from mutable state. 6. Derive deletion targets from a validated identifier and a fixed root. 7. Refuse to delete the root directory itself or any path outside the expected root. 8. Use atomic and permission-restricted state files to reduce local state tampering. 9. Add regression tests covering absolute paths, nested paths, traversal sequences, symlink edge cases, and tampered state. ]]>

T03 · Remote Payload Retrieval and Execution

Error
Location
deerflow_runtime.py:79
Finding
Mutable DeerFlow Runtime Is Retrieved and Executed Without Revision Verification<![CDATA[ ## Vulnerability Details **File Location**: `deerflow_runtime.py:11-14`, `deerflow_runtime.py:79-104` **Vulnerability Type**: Unpinned remote payload retrieval and execution **Risk Level**: High ### Vulnerable Code ```python DEERFLOW_REPO_URL = os.environ.get( "AGENT_OFFICE_DEERFLOW_REPO_URL", "https://github.com/bytedance/deer-flow.git", ) ``` ```python def ensure_deerflow_runtime(update: bool = False) -> dict[str, str]: base_dir = office_dir() shared_root = base_dir / "deerflow-runtime" root = runtime_root(base_dir) backend_dir = runtime_backend_dir(base_dir) python_bin = runtime_python(base_dir) shared_root.mkdir(parents=True, exist_ok=True) missing = missing_prerequisites() if missing: raise RuntimeError( "DeerFlow 自动安装缺少依赖: " + ", ".join(missing) ) if not root.exists(): _run_checked(["git", "clone", "--depth=1", DEERFLOW_REPO_URL, str(root)]) elif update: _run_checked(["git", "-C", str(root), "pull", "--ff-only"]) if not backend_dir.exists(): raise RuntimeError(f"DeerFlow backend 目录缺失: {backend_dir}") if update or not python_bin.exists(): _run_checked(["uv", "sync"], cwd=backend_dir) ``` ### Technical Analysis The Skill clones the current head of a remote Git repository and installs its dependencies with `uv sync`. The effective runtime payload can therefore change after this Skill has been reviewed. The source URL is controlled through `AGENT_OFFICE_DEERFLOW_REPO_URL`, and no origin allowlist is enforced. The implementation does not pin an audited commit, verify a signed tag, validate a commit hash, check a lockfile digest, or require approval for the exact revision being installed. The update path performs `git pull --ff-only`, which protects against non-fast-forward history changes but does not establish that the new commit is trusted. Fetched DeerFlow code is later imported and executed by `deerflow_runtime_runner.py` ...[truncated 1169 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Pin DeerFlow to an audited immutable commit hash. 2. Check out that exact commit after cloning and verify `HEAD` before installation or execution. 3. Restrict repository origins to an explicit allowlist. 4. Verify signed tags or commits against a bundled trusted key. 5. Require a locked dependency graph and verify lockfile or package hashes. 6. Do not automatically pull mutable branches during worker creation. 7. Present the repository URL, commit hash, signer, and dependency changes to the user before updates. 8. Perform installation in a restricted build environment without access to user credentials. 9. Run the resulting runtime in a sandbox with limited filesystem and network permissions. 10. Record the installed revision in worker state and logs for reproducibility and incident response. ]]>

T05 · Unauthorized Access and Privilege Escalation

Error
Location
deerflow_runtime.py:174
Finding
DeerFlow Agents Receive Host Bash, Network Tools, and Writable Host Mounts<![CDATA[ ## Vulnerability Details **File Location**: `deerflow_runtime.py:174-249` **Vulnerability Type**: Excessive agent capabilities and insufficient sandbox isolation **Risk Level**: High ### Vulnerable Code ```python mounts: list[tuple[Path, str, bool]] = [ (resolved_workspace, "/mnt/workspace", False), # Expose only the current worker's local files, not the whole office. (resolved_worker_dir, "/mnt/worker", True), *_optional_mounts(), ] ``` ```python "tool_groups:", " - name: web", " - name: file:read", " - name: file:write", " - name: bash", "", "tools:", " - name: web_search", " group: web", " use: deerflow.community.ddg_search.tools:web_search_tool", " max_results: 5", " - name: web_fetch", " group: web", " use: deerflow.community.jina_ai.tools:web_fetch_tool", " timeout: 10", ``` ```python " - name: write_file", " group: file:write", " use: deerflow.sandbox.tools:write_file_tool", " - name: str_replace", " group: file:write", " use: deerflow.sandbox.tools:str_replace_tool", " - name: bash", " group: bash", " use: deerflow.sandbox.tools:bash_tool", "", "sandbox:", " use: deerflow.sandbox.local:LocalSandboxProvider", " allow_host_bash: true", " mounts:", *mount_lines, ``` ### Technical Analysis The generated DeerFlow configuration combines several high-risk capabilities: - Host Bash is explicitly enabled. - The configured workspace is mounted read-write. - File-write tools are enabled. - Web search and web fetch tools are enabled. - Additional arbitrary existing host paths can be mounted through `AGENT_OFFICE_DEERFLOW_EXTRA_MOUNTS`. A prompt-driven agent is therefore able to interpret untrusted task content while holding command execution, filesystem, and network capabilities. This combination breaks least privilege and creates a direct route from prompt injection to host compromise or data exfiltration. The worker-specific directory is read-only, which reduces cross-worker exposu ...[truncated 1493 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Set `allow_host_bash` to `false` by default. 2. Run DeerFlow inside a container or virtual machine with a restricted user and no host namespace access. 3. Mount workspaces read-only unless a specific task requires modification. 4. Provide a dedicated writable output directory rather than writable access to the source workspace. 5. Disable web tools by default and enable them only through explicit per-task approval. 6. Remove unrestricted extra mounts or enforce a protected allowlist of non-sensitive directories. 7. Reject mounts containing home directories, credential stores, SSH configuration, browser profiles, or system directories. 8. Apply outbound network filtering to the sandbox. 9. Require user confirmation before executing shell commands or writing outside the dedicated output area. 10. Separate worker roles into capability profiles so research or publishing workers do not automatically receive Bash and write access. 11. Add audit logging for tool invocation, accessed paths, commands, writes, and outbound destinations. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (79)

Ae1

High
Category
analysis-evasion
Content
python3 scripts/add_worker.py --list-cli-profiles
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
python3 scripts/add_worker.py --list-cli-profiles
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ssd 3

High
Confidence
98% confidence
Finding
This code forwards both task descriptions and shared-memory snippets to an external worker while also encouraging retention of prior long-term memory. In an office-worker setting, that combination significantly increases the chance of data leakage, cross-context contamination, and uncontrolled persistence outside the local environment.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The README explicitly states that adding a deerflow worker will automatically install or reuse a shared runtime, which implies network access, code retrieval, dependency installation, and persistent filesystem changes. In an agent skill context, undocumented or weakly warned side effects can cause users to execute setup steps that modify their machine state and pull third-party code without fully informed consent.

Missing User Warnings

Medium
Confidence
89% confidence
Finding
The README says shared memory context is injected when forwarding tasks to external workers, but it does not present this as a clear security/privacy warning. This can expose sensitive local context, prompts, or internal state to an upstream service that may be separately configured, less trusted, or operated with broader retention/logging than the office layer.

Lp3

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding
The skill declares substantial capabilities—shell execution, local file read/write, environment access, network use, and background worker management—but does not define any explicit tool scope such as permissions or allowed-tools. This creates an authorization ambiguity where an invoking agent may grant broader-than-necessary access, increasing the chance of unintended filesystem changes, process spawning, or network interactions.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The skill description states that it manages local HTTP workers, writes under ~/.hermes/office, supports external and CLI engines, and can use shared runtimes, but it does not prominently warn that it will spawn background services, bind ports, persist state, and potentially fetch/update external code. Users may invoke it without understanding the system-impacting behavior, reducing informed consent for risky operations.

Vague Triggers

Medium
Confidence
94% confidence
Finding
The documented search/trigger keywords include broad phrases like 'agent office', 'office worker', and 'AI employee', which can overlap with ordinary user requests. Because this skill can create workers, write files, and start HTTP services, accidental invocation is more dangerous than with a read-only skill and could lead to unintended local changes or background processes.

Session Persistence

Medium
Category
Rogue Agent
Content
### Step 2:创建目录

```bash
mkdir -p ~/.hermes/office/workers/{worker_id}/logs
```

### Step 3:生成 SOUL.md
Confidence
86% confidence
Finding
The skill intentionally creates and maintains persistent state under ~/.hermes/office, including worker identities, configs, logs, and status. While persistence is core to the feature, it still introduces security and privacy risk because long-lived local state and background workers can outlast the initiating session, accumulate sensitive task data, and be reused unexpectedly.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
def _run_checked(cmd: list[str], cwd: Path | None = None) -> subprocess.CompletedProcess:
    result = subprocess.run(
        cmd,
        cwd=str(cwd) if cwd else None,
        capture_output=True,
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Description-Behavior Mismatch

Medium
Confidence
97% confidence
Finding
This code automatically clones and optionally updates executable code from a remote Git repository at runtime, then prepares its Python environment with uv sync. That creates a software supply-chain risk: compromise of the repo, dependency set, environment variables, or network path could result in unreviewed code being fetched and later executed on the user's machine.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The clone/pull and dependency-sync path performs network access and modifies the local system state without any user confirmation or disclosure in this file. Even if intended for convenience, silent installation/update behavior is risky in an agent framework because users may not expect code retrieval, environment creation, or package changes as a side effect of adding a worker.

Natural-Language Policy Violations

Medium
Confidence
98% confidence
Finding
The file writes Chinese-only agent instructions such as `你是 ...` and other role guidance into `SOUL.md`. This enforces a specific language for downstream agent behavior without presenting a language choice or documenting a justified locale restriction.

Context-Inappropriate Capability

Medium
Confidence
96% confidence
Finding
The generated runtime config enables broad capabilities including web access, file read/write, and especially host bash execution via a local sandbox provider with allow_host_bash: true. In the context of a 'local AI employee' system that auto-creates autonomous workers, this materially increases the chance of arbitrary command execution, data exfiltration, persistence, or destructive host actions if a prompt, tool call, or upstream runtime is compromised.

Missing User Warnings

Medium
Confidence
97% confidence
Finding
The worker configuration silently grants powerful capabilities including file write access and host bash execution, which exceed a typical low-risk 'office worker' expectation. In an autonomous multi-agent setting, undisclosed command execution and filesystem modification significantly raise the blast radius of prompt injection, model misuse, or logic errors.

Natural-Language Policy Violations

Medium
Confidence
96% confidence
Finding
When JSON parsing fails, the code constructs multiple user-facing fallback strings in Chinese, including the default team summary and scope notes. This imposes a specific language on output regardless of user preference, and the file does not provide a language choice or justify a region-specific locale restriction.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
The file’s display name, description, slot labels, and all step titles/descriptions are written entirely in Chinese, which imposes a specific language on use of the skill. There is no indication that users can opt into another language or that the locale restriction is required for a region-specific purpose, which fits the language/locale policy-violation criteria.

Natural-Language Policy Violations

Medium
Confidence
97% confidence
Finding
The display name, description, slot labels, and all step titles/descriptions are written exclusively in Chinese, which imposes a specific language on users and downstream workers. The file does not offer any language choice or document that this flow is intentionally limited to a Chinese-language context, so it creates a natural-language locale policy concern.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
This code initializes and rewrites persistent JSON state on disk, including office_state.json and later worker config files, but provides no user-facing warning that running the script will modify files under the Hermes office directory. The script prints general progress messages, but those do not disclose the file-writing side effects before they occur.

Tainted flow: 'STATE_FILE' from os.environ.get (line 42, credential/environment) → open (file write)

Medium
Category
Data Flow
Content
"available": list(range(5011, 5021))
            }
        }
        with open(STATE_FILE, "w", encoding="utf-8") as f:
            json.dump(data, f, ensure_ascii=False, indent=2)
Confidence
88% confidence
Finding
Initial creation of the state file has the same environment-driven path risk as later saves: a hostile `HERMES_OFFICE_DIR` can redirect where the application initializes state. This can overwrite arbitrary writable files or create misleading state used by other parts of the system.

Tainted flow: 'STATE_FILE' from os.environ.get (line 42, credential/environment) → open (file write)

Medium
Category
Data Flow
Content
def save_state(data: dict):
    with open(STATE_FILE, "w", encoding="utf-8") as f:
        json.dump(data, f, ensure_ascii=False, indent=2)
Confidence
88% confidence
Finding
`STATE_FILE` is derived from `HERMES_OFFICE_DIR`, so an attacker controlling the environment can redirect state writes to arbitrary filesystem locations accessible to the process. In an agent-management skill that auto-creates and updates files, this can enable unauthorized overwrite of user data or poisoning of future worker state.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
# ── 层2:openclaw agents(仅openclaw/hermes)──────
    if engine in ("openclaw", "hermes"):
        try:
            r = subprocess.run(
                ["openclaw", "agents", "list", "--json"],
                capture_output=True, text=True, timeout=3
            )
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
# ── 层2:openclaw agents(仅openclaw/hermes)──────
    if engine in ("openclaw", "hermes"):
        try:
            r = subprocess.run(
                ["openclaw", "agents", "list", "--json"],
                capture_output=True, text=True, timeout=3
            )
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
return True

    if engine == "openclaw":
        if subprocess.run(["which", "openclaw"], capture_output=True).returncode == 0:
            v = subprocess.run(["openclaw", "--version"],
                             capture_output=True, text=True, timeout=3)
            print(f"✅ openclaw 已安装: {v.stdout.strip() or 'ok'}")
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
if engine == "openclaw":
        if subprocess.run(["which", "openclaw"], capture_output=True).returncode == 0:
            v = subprocess.run(["openclaw", "--version"],
                             capture_output=True, text=True, timeout=3)
            print(f"✅ openclaw 已安装: {v.stdout.strip() or 'ok'}")
            return True
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Static analysis

No suspicious patterns detected.