Back to skill

Security audit

Codex Agentmemory Windows

Security checks for vulnerabilities and agentic risk

Overview

The skill is mostly aligned with repairing Agentmemory on Windows, but it installs persistent Codex hooks that can send prompts to a configurable service and inject returned memory into future sessions.

Install only if you trust the Agentmemory service and are comfortable with persistent Codex hooks capturing prompts and tool context. Keep AGENTMEMORY_URL on localhost unless you have a trusted, authenticated, TLS-protected remote service; rotate or remove AGENTMEMORY_SECRET if the Codex config or wrapper may be exposed; review the generated hooks/config before enabling them; and avoid --restart-service unless you have confirmed ports 3111 and 3113 are actually Agentmemory.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
Findings (5)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/configure_agentmemory_windows.py:168
Finding

Persistent hooks transmit sensitive Agent data to an unrestricted endpoint

Content
View full analysis
object: data = None if body is None else json.dumps(body).encode("utf-8") headers = {"Content-Type": "application/json"} if secret: headers["Authorization"] = f"Bearer {secret}" req = Request(f"{base_url.rstrip('/')}/agentmemory/{path.lstrip('/')}", data=data, headers=headers, method=method) try: with urlopen(req, timeout=180) as response: raw = response.read().decode("utf-8") ``` ### Technical Analysis The configuration accepts an unrestricted `--url` value and persists it for hooks that execute during future Codex sessions. Those hooks transmit user pr ...[truncated 1926 chars]
Remediation
View remediation

T01 · Skill Instruction Hijacking

Error
Location
scripts/configure_agentmemory_windows.py:47
Finding

Untrusted service responses are injected directly into Agent context

Content
View full analysis
\n## Relevant Past Context\n${text}\n`; ``` ### Technical Analysis The generated hooks take `context` and search-result text returned by the configurable agentmemory service and place it directly in Codex `additionalContext`. The response is not sanitized, constrained to a safe data format, or clearly enforced as non-instructional content. Markup tags provide visual delimitation but do not establish a security boundary for a language model. A compromised service or poisoned memory record can return text that resembles developer instructions, directs the Agent to access sensitive files, or attempts ...[truncated 1307 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/configure_agentmemory_windows.py:507
Finding

Agentmemory bearer credential is stored in plaintext in multiple files

Content
View full analysis
str: if '"' in secret or '"' in url: raise SystemExit('AGENTMEMORY_SECRET and AGENTMEMORY_URL must not contain double quotes for .cmd wrapper safety.') return "\n".join( [ "@echo off", f'set "AGENTMEMORY_URL={url}"', f'set "AGENTMEMORY_SECRET={secret}"', f'set "AGENTMEMORY_INJECT_CONTEXT={inject}"', 'if "%~1"=="" exit /b 2', f'"{node_exe}" "{plugin_root}\\scripts\\%~1"', "exit /b %ERRORLEVEL%", "", ] ) ``` ```python # scripts/configure_agentmemory_windows.py:561-573 def configure_mcp(config: str, url: str, secret: str) -> str: config = remove_section(config, "mcp_servers.agentmemory") config = remove_section(config, "mcp_servers.agentmemory.env") block = f""" [mcp_servers.agentmemory] command = "npx" args = ["-y", "@agentmemory/mcp"] [mcp_servers.agentmemory.env] AGENTMEMORY_URL = "{url}" AGENTMEMORY_SECRET = "{secret}" """ return config.rstrip() + "\n" + block ``` ```python # scripts/configure_agentmemory_windows.py:947-949 wrapper.write_text(wrapper_text, encoding="utf-8") hooks_path.write_text(json.dumps(final_hooks, indent=2) + "\n", encoding="utf-8") config_path.write_text(final_config, encoding="utf-8") ``` ### Technical Analysis The bearer credential is embedded in both the generated command wrapper and Codex configuration. These files are written without setting restrictive Windows access-control lists. Configuration backups may also preserve older credential values. Any process or local account capable of reading th ...[truncated 1242 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Error
Location
scripts/configure_agentmemory_windows.py:561
Finding

Runtime MCP configuration executes an unpinned package through npx

Content
View full analysis
str: config = remove_section(config, "mcp_servers.agentmemory") config = remove_section(config, "mcp_servers.agentmemory.env") block = f""" [mcp_servers.agentmemory] command = "npx" args = ["-y", "@agentmemory/mcp"] [mcp_servers.agentmemory.env] AGENTMEMORY_URL = "{url}" AGENTMEMORY_SECRET = "{secret}" """ return config.rstrip() + "\n" + block ``` ### Technical Analysis The generated MCP configuration invokes `npx -y @agentmemory/mcp` without an exact package version or integrity constraint. `npx` may retrieve and execute whatever package version the registry resolves at runtime. Therefore, the effective executable can change after this Skill has been reviewed. The `-y` option removes an interactive confirmation step. The downloaded package also receives the agentmemory URL and bearer secret through its environment, increasing the consequence of a compromised or malicious dependency. This is a supply-chain risk rather than evidence that the current named package is malicious. ### Attack Path 1. The Skill writes the unpinned `npx` MCP configuration. 2. Codex starts the configured MCP server at a later time. 3. `npx` resolves the package from the configured npm registry. 4. A compromised maintainer account, registry incident, or malicious future release supplies altered package code. 5. The altered package executes under the Codex user's account and receives the agentmemory URL and bearer credential. 6. It can access user-readable resources, misuse the API credential, or establish further user-level compromise. ### Impact Assessment A compromised dependency can execute arbitrary code with the permissions of the Codex user. It can access the environment variables supplied ...[truncated 278 chars]
Remediation
View remediation
`. 2. Install the dependency during an explicit setup phase rather than downloading it whenever the MCP server starts. 3. Use a lockfile and verify the registry integrity hash. 4. Execute a known local entry point from the pinned installation. 5. Restrict npm to an approved registry and enable package-signature or provenance verification where available. 6. Remove `-y` from any workflow that may download new executable code. 7. Run the MCP component with a reduced environment and provide credentials through a scoped secret channel. 8. Review and approve dependency upgrades before changing the pinned version. ]]>

T05 · Unauthorized Access and Privilege Escalation

Error
Location
scripts/repair_agentmemory_graph_windows.py:500
Finding

Service restart forcibly terminates unverified processes based only on port ownership

Content
View full analysis
None: command = r""" $owners = Get-NetTCPConnection -LocalPort 3111,3113 -ErrorAction SilentlyContinue | Where-Object { $_.OwningProcess -ne 0 } | Select-Object -ExpandProperty OwningProcess -Unique foreach ($id in $owners) { Stop-Process -Id $id -Force -ErrorAction SilentlyContinue } Start-Sleep -Seconds 2 $cmd = Join-Path $env:APPDATA 'npm\agentmemory.cmd' Start-Process -FilePath $cmd -WorkingDirectory $env:USERPROFILE -WindowStyle Hidden for ($i = 0; $i -lt 30; $i++) { Start-Sleep -Seconds 2 try { $r = Invoke-WebRequest -Uri 'http://localhost:3111/agentmemory/health' -UseBasicParsing -TimeoutSec 5 if ($r.StatusCode -eq 200) { Write-Output 'agentmemory restarted'; exit 0 } } catch {} } Write-Error 'agentmemory did not become healthy in time' exit 1 """ if dry_run: print("would restart local agentmemory service") return subprocess.run(["powershell.exe", "-NoProfile", "-Command", command], check=True) ``` ### Technical Analysis The restart routine identifies targets solely by ownership of TCP ports 3111 or 3113 and invokes `Stop-Process -Force`. It does not verify the executable path, command line, digital signature, process owner, service name, or previously recorded process ID. Port ownership does not prove that a process is agentmemory. An unrelated local service can legitimately use one of these ports, especially when agentmemory is not running. Forceful termination can bypass graceful shutdown and cause availability or data-integrity problems. Terminating arbitrary port owners exceeds the minimum privileges required to restart a known agentmemory instance. ### Attack Path 1. An unrelated application listens on local port 3111 or 3113. 2. The user runs graph repair ...[truncated 774 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Rogue AgentSelf-Modification, Session Persistence
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (30)

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 17)May include surrounding context.

md
python scripts/configure_agentmemory_windows.py --codex-home "$env:USERPROFILE\.codex"

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 23)May include surrounding context.

md
python scripts/configure_agentmemory_windows.py --codex-home "$env:USERPROFILE\.codex"

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 24)May include surrounding context.

md
python scripts/configure_agentmemory_windows.py --codex-home "$env:USERPROFILE\.codex"

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 25)May include surrounding context.

md
python scripts/configure_agentmemory_windows.py --codex-home "$env:USERPROFILE\.codex"

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 26)May include surrounding context.

md
python scripts/configure_agentmemory_windows.py --codex-home "$env:USERPROFILE\.codex"

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 27)May include surrounding context.

md
python scripts/configure_agentmemory_windows.py --codex-home "$env:USERPROFILE\.codex"

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 28)May include surrounding context.

md
python scripts/configure_agentmemory_windows.py --codex-home "$env:USERPROFILE\.codex"

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 29)May include surrounding context.

md
python scripts/configure_agentmemory_windows.py --codex-home "$env:USERPROFILE\.codex"

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 43)May include surrounding context.

md
python scripts/repair_agentmemory_graph_windows.py --dry-run

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 49)May include surrounding context.

md
python scripts/repair_agentmemory_graph_windows.py --dry-run

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 209)May include surrounding context.

md
python scripts/repair_agentmemory_graph_windows.py --dry-run

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 228)May include surrounding context.

md
python scripts/repair_agentmemory_graph_windows.py --dry-run

Context Leakage

High
Category
Data Exfiltration
Confidence
90% confidence
Finding

The skill describes inspecting recent sessions, matching prompt content, recording session IDs, and modifying hook behavior around captured prompts and injected context. This handling touches conversation content and background sessions, creating a genuine context-leakage/privacy risk if prompts or memory context from hidden or unrelated sessions are inspected, stored, or misrouted into other conversations.

Content

Scanner excerpt · SKILL.md (reported line 134)May include surrounding context.

md
1. Inspect recent sessions. If repeated `firstPrompt` starts with `# Overview Generate 0 to 3 hyperpersonalized suggestions...`, these are Codex Desktop background recommendation jobs, not duplicate user chats.
2. Treat this as capture noise: the hook is recording every Codex session-like run, including hidden background jobs.
3. Patch `prompt-submit.mjs` to detect that exact prompt prefix, record the session id in a temp ignore file, call `/agentmemory/forget` for the pre-created background session, and return without observing.
4. Patch `pre-tool-use.mjs`, `post-tool-use.mjs`, `stop.mjs`, and `pre-compact.mjs` to skip any session id in that temp ignore file.
5. Add a service-side fallback in installed `@agentmemory/agentmemory/dist/src-*.mjs` and `dist/index.mjs`: `mem::observe` should ignore this prompt pattern and delete the pre-created session; `/agentmemory/session/start` should also ignore the pattern if it arrives as a title.
6. Restart agentmemory after service-bundle changes.

Env Variable Harvesting

High
Category
Data Exfiltration
Confidence
70% confidence
Finding

Code enumerates, copies, or searches environment variables for secrets. Bulk environment access can collect credentials unrelated to the skill's stated purpose.

Content

Scanner excerpt · scripts/configure_agentmemory_windows.py (reported line 37)May include surrounding context.

python
const INJECT_CONTEXT = process.env["AGENTMEMORY_INJECT_CONTEXT"] === "true";
const REST_URL = process.env["AGENTMEMORY_URL"] || "http://localhost:3111";
const SECRET = process.env["AGENTMEMORY_SECRET"] || "";
const INJECT_TIMEOUT_MS = 1500;
const REGISTER_TIMEOUT_MS = 800;

Env Variable Harvesting

High
Category
Data Exfiltration
Confidence
70% confidence
Finding

Code enumerates, copies, or searches environment variables for secrets. Bulk environment access can collect credentials unrelated to the skill's stated purpose.

Content

Scanner excerpt · scripts/configure_agentmemory_windows.py (reported line 102)May include surrounding context.

python
const INJECT_CONTEXT = process.env["AGENTMEMORY_INJECT_CONTEXT"] === "true";
const REST_URL = process.env["AGENTMEMORY_URL"] || "http://localhost:3111";
const SECRET = process.env["AGENTMEMORY_SECRET"] || "";
const INJECT_TIMEOUT_MS = 1500;
const REGISTER_TIMEOUT_MS = 800;

Env Variable Harvesting

High
Category
Data Exfiltration
Confidence
70% confidence
Finding

Code enumerates, copies, or searches environment variables for secrets. Bulk environment access can collect credentials unrelated to the skill's stated purpose.

Content

Scanner excerpt · scripts/configure_agentmemory_windows.py (reported line 222)May include surrounding context.

python
const INJECT_CONTEXT = process.env["AGENTMEMORY_INJECT_CONTEXT"] === "true";
const REST_URL = process.env["AGENTMEMORY_URL"] || "http://localhost:3111";
const SECRET = process.env["AGENTMEMORY_SECRET"] || "";
const INJECT_TIMEOUT_MS = 1500;
const REGISTER_TIMEOUT_MS = 800;

Env Variable Harvesting

High
Category
Data Exfiltration
Confidence
70% confidence
Finding

Code enumerates, copies, or searches environment variables for secrets. Bulk environment access can collect credentials unrelated to the skill's stated purpose.

Content

Scanner excerpt · scripts/configure_agentmemory_windows.py (reported line 636)May include surrounding context.

python
const INJECT_CONTEXT = process.env["AGENTMEMORY_INJECT_CONTEXT"] === "true";
const REST_URL = process.env["AGENTMEMORY_URL"] || "http://localhost:3111";
const SECRET = process.env["AGENTMEMORY_SECRET"] || "";
const INJECT_TIMEOUT_MS = 1500;
const REGISTER_TIMEOUT_MS = 800;

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/repair_agentmemory_graph_windows.py (reported line 171)May include surrounding context.

python
def read_agentmemory_env() -> dict[str, str]:
    path = Path.home() / ".agentmemory" / ".env"
    if not path.exists():
        return {}
    env: dict[str, str] = {}

Env Variable Harvesting

High
Category
Data Exfiltration
Confidence
60% confidence
Finding

Code enumerates, copies, or searches environment variables for secrets. Bulk environment access can collect credentials unrelated to the skill's stated purpose.

Content

Scanner excerpt · scripts/repair_agentmemory_graph_windows.py (reported line 532)May include surrounding context.

python
if args.all or not selected:
        args.patch_hooks = args.patch_service = args.backfill = True

    env = {**read_agentmemory_env(), **read_codex_agentmemory_env(args.codex_home), **os.environ}
    base_url = args.url or env.get("AGENTMEMORY_URL") or "http://localhost:3111"
    secret = args.secret or env.get("AGENTMEMORY_SECRET") or ""
    package_roots = discover_package_roots(args.agentmemory_package_root)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
97% confidence
Finding

The skill directs file modification, shell execution, environment-variable use, and localhost network access, but it declares no explicit tool scope or permissions boundaries. That mismatch is a real security issue because it enables broad, high-impact actions without least-privilege signaling or policy constraints, making accidental or unsafe execution more likely.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
93% confidence
Finding

The skill instructs persistent modification of ~/.codex hooks, trusted hashes, wrapper scripts, and related config so behavior survives across sessions. Persistent hook and trust configuration changes are security-sensitive because they can outlive the repair task, expand future execution surface, and normalize long-lived command execution on every Codex event.

Content

Scanner excerpt · SKILL.md (reported line 3)May include surrounding context.

md
---
name: codex-agentmemory-windows
description: Configure, repair, and validate agentmemory integration for Codex App on Windows. Use when Codex needs to set up agentmemory hooks, fix Windows PowerShell hook failures, create an agentmemory-hook.cmd wrapper, update ~/.codex/hooks.json and trusted_hash entries, fix missing Codex additionalContext memory injection, repair stale/frozen agentmemory knowledge graph updates, backfill graph nodes/edges, or troubleshoot Codex App agentmemory MCP/hook configuration.
---

# Codex Agentmemory Windows

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The generated hook code sends full prompt contents to the local/configured agentmemory service via /agentmemory/observe and also uses prompt text for search and context enrichment, with no user-facing consent or warning in this installer script. Prompt contents may include secrets, credentials, proprietary code, or other sensitive data, so silently forwarding them expands the trust boundary and creates privacy and data-exposure risk.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
91% confidence
Finding

The script validates hooks by passing a dynamically constructed command string into powershell.exe -Command. That command string contains paths and configuration-derived values that ultimately influence execution flow, so using PowerShell's command parser introduces command-injection risk and can execute unintended commands if the wrapper path or related values are crafted maliciously.

Content

Scanner excerpt · scripts/configure_agentmemory_windows.py (reported line 872)May include surrounding context.

python
results = []
    for event, entries in agent_hooks["hooks"].items():
        command = entries[0]["hooks"][0]["command"]
        proc = subprocess.run(
            ["powershell.exe", "-NoProfile", "-Command", command],
            input=payload,
            text=True,

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The script persists AGENTMEMORY_SECRET into config.toml and a generated .cmd wrapper on disk, without warning the user or restricting exposure. Storing bearer secrets in plaintext files increases the chance of credential theft by local users, malware, backups, logs, or accidental sharing of the Codex home directory.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/configure_agentmemory_windows.py (reported line 667)May include surrounding context.

python
def npm_global_root() -> Path | None:
    try:
        proc = subprocess.run(
            ["npm.cmd", "root", "-g"],
            text=True,
            stdout=subprocess.PIPE,

Static analysis

Detected: suspicious.env_credential_access, suspicious.potential_exfiltration

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
scripts/configure_agentmemory_windows.py:30

Sensitive-looking file read is paired with a network send.

Warn
Code
suspicious.potential_exfiltration
Location
scripts/configure_agentmemory_windows.py:326