Back to skill

Security audit

OMNI Research Verifier

Security checks for vulnerabilities and agentic risk

Overview

This fact-checking skill is coherent and non-persistent, but its credibility scoring is simplistic and one dependency pin should be updated.

Install only if you are comfortable with user claims being sent to DuckDuckGo-backed search and with heuristic confidence scores. Treat reports as research assistance, not authoritative fact-checking, and prefer a version that upgrades requests and validates source hostnames properly.

Vulnerability Patterns
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (1)

T09 · Insecure Skill Coding Practices

Warning
Location
skill_script.py.txt:24
Finding
Source Credibility Validation Bypass Through URL Substring Matching<![CDATA[ ## Vulnerability Details **File Location**: `skill_script.py.txt`, lines 24-32 **Vulnerability Type**: Improper URL hostname validation **Risk Level**: Medium ### Vulnerable Code ```python HIGH_TRUST = ['.gov', '.edu', '.org', 'reuters.com', 'apnews.com', 'bloomberg.com'] @staticmethod def score_source(url: str, title: str) -> float: score = 0.5 # Base score if any(domain in url for domain in CredibilityEngine.HIGH_TRUST): score += 0.3 if "research" in url.lower() or "journal" in url.lower(): score += 0.1 return min(score, 1.0) ``` ### Technical Analysis The credibility engine determines whether a search result is associated with a trusted source by searching for trusted-domain strings anywhere in the complete URL. It does not parse the URL, normalize its hostname, or verify that the trusted domain is the registrable domain or a legitimate subdomain. Consequently, attacker-controlled URLs such as the following can receive an unjustified trust bonus: ```text https://reuters.com.attacker.example/article https://attacker.example/article?source=.gov https://attacker.example/research/apnews.com ``` The additional `"research"` and `"journal"` substring checks have the same weakness and can grant another credibility increase based only on attacker-controlled URL text. The resulting scores are averaged at lines 97-100 and directly affect whether the report labels a claim as `Supported` or `Mixed`. This creates an integrity vulnerability in the skill's principal verification function. ### Attack Path 1. An attacker publishes misleading content on a domain under their control. 2. The attacker places a trusted substring such as `reuters.com`, `.gov`, or `.edu` in the hostname, path, or query string. They can also include `research` or `journal` for an additional score increase. 3. The attacker optimizes or promotes the page so that DuckDuckGo returns it for a targeted claim. 4. The skill accepts the result URL and pas ...[truncated 801 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Parse URLs with `urllib.parse.urlparse` and evaluate only the normalized hostname. 2. Require exact hostname matches or dot-boundary subdomain matches. For example, trust `reuters.com` and `www.reuters.com`, but reject `reuters.com.attacker.example`. 3. Maintain explicit trusted hostnames rather than broad textual markers such as `.org`, `.gov`, and `.edu`. 4. Reject malformed URLs and URLs without an expected `http` or `https` scheme. 5. Do not increase source credibility because words such as `research` or `journal` appear in a URL. Validate publisher identity and evidence quality independently. 6. Avoid interpreting domain reputation as proof that a claim is supported. Assess whether each source's content actually supports, contradicts, or merely mentions the claim. 7. Add unit tests covering deceptive hostnames, trusted strings in paths and queries, mixed-case hostnames, user-information components, and legitimate subdomains. A safer hostname check could follow this pattern: ```python from urllib.parse import urlparse TRUSTED_HOSTS = { "reuters.com", "apnews.com", "bloomberg.com", } def is_trusted_host(url: str) -> bool: parsed = urlparse(url) if parsed.scheme not in {"http", "https"}: return False hostname = (parsed.hostname or "").rstrip(".").lower() return any( hostname == trusted or hostname.endswith("." + trusted) for trusted in TRUSTED_HOSTS ) ``` ]]>
Vulnerability Patterns
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
Findings (1)

Known Vulnerable Dependency: requests==2.31.0 — 6 advisory(ies): CVE-2024-47081 (Requests vulnerable to .netrc credentials leak via malicious URLs); CVE-2024-35195 (Requests `Session` object does not verify requests after making first request wi); CVE-2026-25645 (Requests has Insecure Temp File Reuse in its extract_zipped_paths() utility func) +3 more

Medium
Category
Supply Chain
Confidence
95% confidence
Finding
The dependency pin `requests==2.31.0` matches a version with multiple published advisories, including issues involving credential leakage and improper verification behavior. Even in a simple requirements file, shipping a known vulnerable version creates real supply-chain risk because any code using this library may inherit those weaknesses when processing attacker-controlled URLs, sessions, or archive-related paths.

Static analysis

No suspicious patterns detected.