Back to skill

Security audit

Auto Research Claw

Security checks across malware telemetry and agentic risk

Overview

This skill is a real autonomous research tool, but it defaults to broad automatic code execution with weak containment in several paths.

Install only if you are comfortable running an autonomous research system that can generate and execute code, call external LLM/search services, write persistent artifacts, and use local credentials from environment variables. Prefer Docker mode with network_policy set to none where feasible, avoid --auto-approve for untrusted topics, disable OpenCode/ACP/agentic modes unless needed, and run it in a disposable workspace with minimal secrets.

SkillSpector

By NVIDIA
Vulnerability Patterns
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
Findings (140)

subprocess module call

Medium
Category
Dangerous Code Execution
Content
) -> dict[str, str]:
        """Execute script in a local subprocess (no sandbox)."""
        try:
            proc = subprocess.run(
                [self._python, str(script_path.resolve())],
                capture_output=True,
                text=True,
Confidence
99% confidence
Finding
proc = subprocess.run( [self._python, str(script_path.resolve())], capture_output=True, text=True, timeout=self._timeout,

subprocess module call

Medium
Category
Dangerous Code Execution
Content
print("  npm is not installed. Cannot install OpenCode.")
        return False
    try:
        r = subprocess.run(
            [npm_cmd, "i", "-g", "opencode-ai@latest"],
            capture_output=True, text=True, timeout=120,
        )
Confidence
87% confidence
Finding
r = subprocess.run( [npm_cmd, "i", "-g", "opencode-ai@latest"], capture_output=True, text=True, timeout=120, )

subprocess module call

Medium
Category
Dangerous Code Execution
Content
) -> subprocess.CompletedProcess[str]:
        """Run a command inside the container."""
        cmd = ["docker", "exec", container, "bash", "-c", command]
        return subprocess.run(
            cmd,
            capture_output=True,
            text=True,
Confidence
98% confidence
Finding
return subprocess.run( cmd, capture_output=True, text=True, timeout=timeout, check=False, )

subprocess module call

Medium
Category
Dangerous Code Execution
Content
workdir.mkdir(parents=True, exist_ok=True)
        start = time.monotonic()
        timed_out = False
        proc = subprocess.Popen(
            cmd,
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE,
Confidence
96% confidence
Finding
proc = subprocess.Popen( cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=workdir, env={**os.environ}, start_new

subprocess module call

Medium
Category
Dangerous Code Execution
Content
def ensure_image(image: str) -> bool:
        """Return True if *image* exists locally (does NOT pull)."""
        try:
            cp = subprocess.run(
                ["docker", "image", "inspect", image],
                capture_output=True,
                timeout=10,
Confidence
85% confidence
Finding
cp = subprocess.run( ["docker", "image", "inspect", image], capture_output=True, timeout=10, check=False, )

subprocess module call

Medium
Category
Dangerous Code Execution
Content
timed_out = False
        try:
            logger.debug("Docker run command: %s", cmd)
            completed = subprocess.run(
                cmd,
                capture_output=True,
                text=True,
Confidence
96% confidence
Finding
completed = subprocess.run( cmd, capture_output=True, text=True, timeout=timeout_sec, check=False,

subprocess module call

Medium
Category
Dangerous Code Execution
Content
result: SandboxResult
        try:
            env = {**os.environ, "PYTHONUNBUFFERED": "1"}
            completed = subprocess.run(
                command,
                capture_output=True,
                text=True,
Confidence
94% confidence
Finding
completed = subprocess.run( command, capture_output=True, text=True, timeout=timeout_sec, cwd=self.workdir,

subprocess module call

Medium
Category
Dangerous Code Execution
Content
result: SandboxResult
        try:
            env = {**os.environ, "PYTHONUNBUFFERED": "1"}
            completed = subprocess.run(
                command,
                capture_output=True,
                text=True,
Confidence
95% confidence
Finding
completed = subprocess.run( command, capture_output=True, text=True, timeout=timeout_sec, cwd=sandbox_projec

subprocess module call

Medium
Category
Dangerous Code Execution
Content
# Check if already installed
    try:
        result = subprocess.run(
            [str(python), "-c", "import torch; print(torch.__version__)"],
            capture_output=True,
            text=True,
Confidence
88% confidence
Finding
result = subprocess.run( [str(python), "-c", "import torch; print(torch.__version__)"], capture_output=True, text=True, timeout=30,

subprocess module call

Medium
Category
Dangerous Code Execution
Content
pip_cmd = [str(python), "-m", "pip", "install", "--quiet", "torch"]

    try:
        result = subprocess.run(
            pip_cmd,
            capture_output=True,
            text=True,
Confidence
92% confidence
Finding
result = subprocess.run( pip_cmd, capture_output=True, text=True, timeout=300, check=False, )

subprocess module call

Medium
Category
Dangerous Code Execution
Content
def _send_prompt_cli(self, acpx: str, prompt: str) -> str:
        """Send prompt as a CLI argument (original path)."""
        try:
            result = subprocess.run(
                [acpx, "--approve-all", "--ttl", "0", "--cwd", self._abs_cwd(),
                 self.config.agent, "-s", self.config.session_name,
                 prompt],
Confidence
98% confidence
Finding
result = subprocess.run( [acpx, "--approve-all", "--ttl", "0", "--cwd", self._abs_cwd(), self.config.agent, "-s", self.config.session_name,

subprocess module call

Medium
Category
Dangerous Code Execution
Content
)

            try:
                result = subprocess.run(
                    [acpx, "--approve-all", "--ttl", "0", "--cwd", self._abs_cwd(),
                     self.config.agent, "-s", self.config.session_name,
                     short_prompt],
Confidence
99% confidence
Finding
result = subprocess.run( [acpx, "--approve-all", "--ttl", "0", "--cwd", self._abs_cwd(), self.config.agent, "-s", self.config.session_name,

subprocess module call

Medium
Category
Dangerous Code Execution
Content
t0 = time.monotonic()
        try:
            result = subprocess.run(
                cmd,
                cwd=str(workspace),
                capture_output=True,
Confidence
87% confidence
Finding
result = subprocess.run( cmd, cwd=str(workspace), capture_output=True, text=True, timeout=self._timeout_sec,

subprocess module call

Medium
Category
Dangerous Code Execution
Content
entire compilation pipeline — bibtex never runs, all citations [?].
    """
    try:
        proc = subprocess.run(
            ["pdflatex", "-interaction=nonstopmode", tex_name],
            cwd=work_dir,
            capture_output=True,
Confidence
94% confidence
Finding
proc = subprocess.run( ["pdflatex", "-interaction=nonstopmode", tex_name], cwd=work_dir, capture_output=True, timeout=timeout, )

subprocess module call

Medium
Category
Dangerous Code Execution
Content
logger.warning("bibtex not found on PATH — citations will be [?]")
        return False
    try:
        proc = subprocess.run(
            ["bibtex", stem],
            cwd=work_dir,
            capture_output=True,
Confidence
86% confidence
Finding
proc = subprocess.run( ["bibtex", stem], cwd=work_dir, capture_output=True, timeout=timeout, )

subprocess module call

Medium
Category
Dangerous Code Execution
Content
print(f"  Running in subprocess (timeout={timeout_sec}s)...")
    try:
        proc = subprocess.run(
            [sys.executable, str(main_py)],
            cwd=str(code_dir),
            capture_output=True,
Confidence
95% confidence
Finding
proc = subprocess.run( [sys.executable, str(main_py)], cwd=str(code_dir), capture_output=True, text=True, timeout=timeout_sec,

Intent-Code Divergence

Medium
Confidence
96% confidence
Finding
The docstring implies the component prevents RCE via Docker isolation, but the implementation explicitly falls back to unsandboxed local execution. That mismatch can cause operators to deploy the agent under a false security assumption, increasing the chance that untrusted generated code runs on the host.

Intent-Code Divergence

Medium
Confidence
96% confidence
Finding
The class-level documentation presents Docker mode as protection against RCE while still supporting direct local execution of generated scripts. This creates dangerous security ambiguity around a component whose core function is executing untrusted code.

Intent-Code Divergence

Medium
Confidence
94% confidence
Finding
The method docstring states the Docker path prevents RCE, but the overall agent behavior still permits host execution elsewhere. In security-sensitive systems, such partial claims are hazardous because they can be read as an end-to-end guarantee when none exists.

Intent-Code Divergence

Medium
Confidence
72% confidence
Finding
The `dashboard` command claims to start a dashboard-only server but reuses the same application factory as the full server with only a boolean flag. If route registration or authorization inside `create_app` is incomplete or buggy, control endpoints may remain reachable, causing privilege/feature exposure contrary to operator expectations.

Context-Inappropriate Capability

High
Confidence
99% confidence
Finding
The module description explicitly states that the agent gets full shell access, can run arbitrary CLI commands, and can read and write files. In the context of a generic skill with no tightly bounded purpose, this is an overprivileged design that turns any prompt injection, model misuse, or configuration abuse into arbitrary code execution against the mounted workspace and potentially the host environment through Docker-adjacent attack surface.

Context-Inappropriate Capability

High
Confidence
99% confidence
Finding
The agent command builder enables very broad capabilities such as `Bash(*)`, file read/write/edit operations, and Codex `full-auto` approval mode. In this context, the code intentionally authorizes autonomous execution of high-risk actions without guardrails, which makes prompt injection, accidental destructive behavior, and secret exfiltration substantially more dangerous.

Intent-Code Divergence

Medium
Confidence
99% confidence
Finding
The prompts tell the model that subprocesses and shell actions are forbidden, but the Claude backend simultaneously grants the Bash tool and uses --dangerously-skip-permissions. That mismatch means untrusted prompt content or generated reasoning can still drive shell execution with reduced safeguards, undermining the stated security controls and enabling arbitrary command execution, file exfiltration, or destructive writes.

Intent-Code Divergence

Medium
Confidence
99% confidence
Finding
The comments and policy semantics claim network access is disabled before Phase 2, but the code explicitly accepts failure of the iptables step and leaves networking enabled. In a system designed to run untrusted experiment code, this is a real sandbox-break policy failure because malicious code can retain outbound connectivity despite a supposedly restrictive mode.

Intent-Code Divergence

High
Confidence
98% confidence
Finding
The module advertises 'safe experiment code execution,' but the implementation runs arbitrary Python on the host and inherits host environment variables. This misleading safety claim materially increases the chance that developers will feed it untrusted code under false assumptions, turning design weakness into exploitable exposure.

VirusTotal

VirusTotal engine telemetry is currently stale for this artifact.

View on VirusTotal

Static analysis

Detected: suspicious.dynamic_code_execution, suspicious.exposed_secret_literal

Dynamic code execution detected.

Critical
Code
suspicious.dynamic_code_execution
Location
researchclaw/prompts.py:1298

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
docs/TESTER_GUIDE_JA.md:185

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
docs/TESTER_GUIDE.md:185

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
researchclaw/agents/figure_agent/orchestrator.py:176

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
researchclaw/cli.py:741

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
researchclaw/health.py:583

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
researchclaw/llm/client.py:152

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
researchclaw/pipeline/stage_impls/_analysis.py:649

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
researchclaw/pipeline/stage_impls/_literature.py:359