Back to skill

Security audit

Safe-Web

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly does what it says, but needs review because it can fetch any address your machine can reach and its setup can alter system Python and create a system-wide command.

Install only if you are comfortable with a command that can fetch any URL reachable from your machine. Prefer running it in a restricted network environment, avoid the sudo symlink unless needed, use a virtual environment with pinned dependencies instead of --break-system-packages, and treat Brave search as sending your query and API key to Brave.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
Findings (2)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/safe-web.py:71
Finding

Unrestricted URL Fetching Enables Server-Side Request Forgery

Content
View full analysis
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
README.md:23
Finding

Unpinned Dependencies Are Installed into the System-Managed Python Environment

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
Findings (10)

Tainted flow: 'headers' from os.environ.get (line 109, credential/environment) → requests.get (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/safe-web.py (reported line 71)May include surrounding context.

python
}
    
    try:
        response = requests.get(url, headers=headers, timeout=timeout, allow_redirects=True)
        response.raise_for_status()
    except requests.RequestException as e:
        print(f"Error fetching URL: {e}", file=sys.stderr)

Tainted flow: 'headers' from os.environ.get (line 109, credential/environment) → requests.get (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/safe-web.py (reported line 120)May include surrounding context.

python
}
    
    try:
        response = requests.get(
            'https://api.search.brave.com/res/v1/web/search',
            headers=headers,
            params=params,

Instruction Override

High
Category
Prompt Injection
Confidence
80% confidence
Finding

This pattern attempts to override system instructions or ignore safety constraints. Without LLM analysis, manual review is recommended.

Content

Scanner excerpt · README.md (reported line 13)May include surrounding context.

md
By default, OpenClaw's native `web_fetch` and `web_search` tools fetch content directly without security scanning. Safe-web provides the same functionality but adds a critical security layer that scans all content for:

- Instruction override attempts ("ignore previous instructions")
- Role manipulation attacks ("you are now DAN")
- System impersonation patterns
- Hidden malicious payloads in web pages

YARA rule 'agent_skill_prompt_injection_hidden_instructions': Prompt injection or hidden instructions embedded in AI agent skill text [agent_skills]

High
Category
YARA Match
Confidence
80% confidence
Finding

YARA rule matched a hack tool or exploit indicator (offensive tools, reconnaissance, privilege escalation, or exploit frameworks).

Content

Scanner excerpt · README.md (reported line 13)May include surrounding context.

ning to detect and block prompt injection attacks hidden in web content, emails, PDFs, and documents before they reach the AI.

Why Use This?

By default, OpenClaw's native web_fetch and web_search tools fetch content directly without security scanning. Safe-web provides the same functionality but adds a critical security layer that scans all content for:

  • Instruction override attempts ("ignore previous instructions")
  • Role manipulation attacks ("you are now DAN")
  • System impersonation patterns
  • Hidden malicious payloads in web pages

Installation

1. Install Dependencies

bash
# Install PromptGuard first
cd /home/linuxbrew/.openclaw/workspace/skills/prompt-guard
pip3 install --break-system-packages -e .

# Install web dependencies
pip3 install --break-system-packages requests beautifulsoup4

2. Create Symlink (Optional but Recommended)

bash
sudo ln -s /home/linuxbrew/.openclaw/workspace/skills/safe-web/scripts/safe-web.py /usr/local/bin/safe-web

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · README.md (reported line 34)May include surrounding context.

2. Create Symlink (Optional but Recommended)

bash
sudo ln -s /home/linuxbrew/.openclaw/workspace/skills/safe-web/scripts/safe-web.py /usr/local/bin/safe-web

3. Configure Brave API Key (for search)

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

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

2. Create Symlink (Optional but Recommended)

bash
sudo ln -s /home/linuxbrew/.openclaw/workspace/skills/safe-web/scripts/safe-web.py /usr/local/bin/safe-web

3. Configure Brave API Key (for search)

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/safe-web.py (reported line 121)May include surrounding context.

python
try:
        response = requests.get(
            'https://api.search.brave.com/res/v1/web/search',
            headers=headers,
            params=params,
            timeout=30

Dynamic attribute access via getattr()

Low
Category
Dangerous Code Execution
Confidence
50% confidence
Finding

Dynamic getattr() with a non-literal attribute name can access arbitrary object attributes, potentially bypassing access controls.

Content

Scanner excerpt · scripts/safe-web.py (reported line 151)May include surrounding context.

python
for result in results:
        # Scan title
        title_result = scan_with_promptguard(result['title'])
        if title_result.severity.value >= getattr(title_result.severity, severity_threshold).value:
            threats_found.append({
                'field': 'title',
                'url': result['url'],

Dynamic attribute access via getattr()

Low
Category
Dangerous Code Execution
Confidence
50% confidence
Finding

Dynamic getattr() with a non-literal attribute name can access arbitrary object attributes, potentially bypassing access controls.

Content

Scanner excerpt · scripts/safe-web.py (reported line 162)May include surrounding context.

python
# Scan description
        desc_result = scan_with_promptguard(result['description'])
        if desc_result.severity.value >= getattr(desc_result.severity, severity_threshold).value:
            threats_found.append({
                'field': 'description',
                'url': result['url'],

Dynamic attribute access via getattr()

Low
Category
Dangerous Code Execution
Confidence
50% confidence
Finding

Dynamic getattr() with a non-literal attribute name can access arbitrary object attributes, potentially bypassing access controls.

Content

Scanner excerpt · scripts/safe-web.py (reported line 201)May include surrounding context.

python
result = scan_with_promptguard(content)
    
    severity_threshold = "MEDIUM" if args.strict else "HIGH"
    should_block = result.severity.value >= getattr(result.severity, severity_threshold).value
    
    if args.json:
        output = {

Static analysis

Detected: suspicious.prompt_injection_instructions

Prompt-injection style instruction pattern detected.

Warn
Code
suspicious.prompt_injection_instructions
Location
README.md:13