Back to skill

Security audit

AI Tech Intelligence Briefing

Security checks for vulnerabilities and agentic risk

Overview

This briefing skill is not malware, but it needs Review because it can read unexpected Markdown files and its documentation overstates what the code actually does.

Review this package before installing in shared or sensitive workspaces. Treat generated briefings as demo content, expect an embedded donation/footer unless modified, and avoid passing untrusted values to the fetch command until date validation and path containment are added.

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 (3)

other

Error
Location
scripts/briefing.py:83
Finding
Forced Promotional Content in Every Generated Briefing<![CDATA[ ## Vulnerability Details **File Location**: `scripts/briefing.py`, lines 83-91 **Vulnerability Type**: Forced promotional output **Risk Level**: High ### Vulnerable Code ```python footer = f""" {'-' * 40} END OF BRIEFING {'=' * 60} 💰 Support this project: PayPal: https://paypal.me/greatworks888 📦 GitHub: https://github.com/greatworks/ai-tech-intelligence-briefing 🚀 Published on ClawHub by @greatworks """ ``` ### Technical Analysis The generator unconditionally appends a donation destination, repository address, and publisher branding to every English briefing. Equivalent promotional content is also present in the Chinese output branch. This content is unrelated to the requested news summary and cannot be disabled through configuration or command-line options. Because the Skill describes generated briefings as shareable content, the embedded footer can be propagated automatically into team channels, community posts, or other downstream destinations. This does not modify the Agent's safety rules or install persistent system state, so it is categorized as forced promotional output rather than instruction hijacking. ### Attack Path 1. A user or Agent invokes `python scripts/briefing.py generate`. 2. `generate_briefing()` creates a fixed promotional footer. 3. The footer is concatenated with the generated briefing. 4. The complete output is printed or saved. 5. If the briefing is copied or forwarded, the external payment link and publisher branding are distributed with it. ### Impact Assessment The issue does not grant system privileges or access to private data. Its scope is manipulation of generated content and downstream communications. It can cause Agents to distribute unsolicited advertising or payment links under the user's identity, reducing output integrity and user control. ]]>
Remediation
<![CDATA[ ## Remediation Suggestions - Remove donation and promotional links from generated briefing content. - Keep attribution and donation information in `README.md`, `SKILL.md`, or package metadata. - If attribution in generated output is desired, make it explicitly opt-in through a disabled-by-default option such as `--include-attribution`. - Clearly separate user-requested briefing content from optional metadata. - Add tests confirming that default output contains no unrelated promotional material. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/briefing.py:140
Finding
Path Traversal Allows Reading Markdown Files Outside the Briefings Directory<![CDATA[ ## Vulnerability Details **File Location**: `scripts/briefing.py`, lines 140-144 and 192-198 **Vulnerability Type**: Path traversal and unauthorized local file disclosure **Risk Level**: Medium ### Vulnerable Code ```python def fetch_briefing(self, date: str) -> str: """Fetch saved briefing.""" filename = self.briefings_dir / f"{date}.md" if filename.exists(): return filename.read_text(encoding='utf-8') return None ``` The unvalidated argument is passed directly to the vulnerable method: ```python elif command == 'fetch': if len(args) < 2: print("❌ Error: Please specify date (YYYY-MM-DD)") sys.exit(1) briefing = generator.fetch_briefing(args[1]) if briefing: print(briefing) ``` ### Technical Analysis Although the command documentation requires a date in `YYYY-MM-DD` format, the implementation does not validate the argument. `pathlib.Path` preserves traversal components such as `../`, allowing the constructed path to escape `self.briefings_dir`. The forced `.md` suffix limits exploitation to filenames ending in `.md`, but does not prevent access to Markdown files elsewhere in the current workspace or filesystem. The code only checks whether the resulting path exists; it does not resolve the path and verify that it remains under the intended briefing directory. ### Attack Path 1. An attacker influences the argument supplied to the `fetch` command. 2. The attacker supplies traversal input such as: ```text fetch ../../private/notes ``` 3. The code constructs: ```text <output-directory>/briefings/../../private/notes.md ``` 4. The operating system normalizes the traversal components. 5. If the target exists and is readable by the process, its contents are loaded. 6. The command prints the contents to standard output, potentially exposing them to an Agent transcript or downstream user. ### Impact Assessment An attacker can read arbitrary accessible files whose names end ...[truncated 402 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Validate the input against a strict date format before constructing a path: ```python from datetime import datetime datetime.strptime(date, "%Y-%m-%d") ``` - Reject path separators, traversal components, and values that are not valid calendar dates. - Resolve both the base directory and target path, then verify containment: ```python base = self.briefings_dir.resolve() target = (base / f"{date}.md").resolve() if target.parent != base: raise ValueError("Invalid briefing date") ``` - Read only regular files and reject symbolic links if they are not required. - Add regression tests using values such as `../secret`, `../../notes`, absolute paths, URL-encoded traversal sequences, and invalid dates. ]]>

T08 · Insecure Dependencies

Note
Location
setup.py:28
Finding
Unused and Unlocked HTTP Dependency Expands the Supply-Chain Attack Surface<![CDATA[ ## Vulnerability Details **File Location**: `setup.py`, lines 28-30; `package.json`, lines 33-35 **Vulnerability Type**: Unnecessary and non-reproducible third-party dependency **Risk Level**: Low ### Vulnerable Code ```python install_requires=[ "requests>=2.28.0", ], ``` The package manifest also declares the dependency using nonstandard npm dependency notation: ```json "dependencies": { "requests>=2.31.0": "Python package for HTTP requests" }, ``` ### Technical Analysis The executable does not import or use `requests`; it generates hard-coded demo stories and performs no network retrieval. Installing the library therefore provides no functionality while introducing additional third-party and transitive code into the environment. The Python requirement specifies only a lower bound, so installations can resolve to different future releases rather than a reviewed, reproducible dependency set. The `package.json` declaration is also malformed for an npm dependency map: the package name contains a Python-style version constraint, while the value is a description rather than a package version. No evidence shows that the currently referenced `requests` package is malicious. The risk arises from unnecessary dependency installation, inconsistent package-manager metadata, and the absence of a reviewed lock file or hashes. ### Attack Path 1. A user installs the project through its Python packaging metadata. 2. The resolver downloads `requests` and its transitive dependencies despite the application not using them. 3. Dependency versions are selected according to the state of the package index at installation time. 4. If a future resolved package or transitive component is compromised, malicious installation or runtime behavior could execute with the installer's privileges. 5. The malformed `package.json` declaration may additionally cause installation failure or unexpected package-manager behavior. ### Impact Assessment The issue unnecessarily ...[truncated 293 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Remove `requests` from `setup.py`, `package.json`, `SKILL.md`, and OpenClaw requirement metadata until networking is actually implemented. - Do not represent Python dependencies inside the npm `dependencies` object. - If HTTP functionality is later added, define the dependency in the appropriate Python packaging file. - Use a reviewed lock file and hashes to make installations reproducible. - Establish an update process that tests and reviews dependency upgrades. - Ensure documentation and security metadata accurately reflect actual runtime network behavior. ]]>
Vulnerability Patterns
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • 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
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (3)

Vague Triggers

Medium
Confidence
94% confidence
Finding
The trigger phrase "daily briefing" is broad and generic, making it likely to match ordinary user requests that are not specifically intended to invoke this skill. This can cause unintended activation and execution of network-fetching behavior, which increases the risk of user confusion, overreach, and accidental data handling beyond user expectations.

Intent-Code Divergence

Medium
Confidence
98% confidence
Finding
The top-level docstring states that the script generates daily AI/tech briefings using public RSS feeds and APIs. In practice, generate_briefing calls _generate_demo_stories, and the code explicitly notes it is generating demo content instead of fetching real data, so the documentation materially misrepresents the tool's actual behavior.

Intent-Code Divergence

Low
Confidence
76% confidence
Finding
The comment '# Get name' suggests the code is retrieving the package name, but the jq expression reads '.description | split(":")[0]' from package.json. This is an intent/documentation mismatch because the inline comment states one behavior while the code performs a different metadata extraction.

Static analysis

No suspicious patterns detected.