Back to skill

Security audit

regulation-monitor / 监管动态追踪

Security checks for vulnerabilities and agentic risk

Overview

The skill is a legitimate regulator-news crawler, but its network fetching is under-scoped enough that untrusted pages could cause unexpected outbound requests.

Install only in an isolated environment with limited network reach. Treat summary mode as higher risk until URL allowlisting, HTTPS-only fetching, and redirect validation are added, and prefer pinned dependencies or a reviewed lockfile.

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
crawler.py:181
Finding

Untrusted listing data can trigger arbitrary outbound requests in summary mode

Content
View full analysis

Vulnerability Details

File Location: crawler.py:181-190, crawler.py:351-354, crawler.py:415, and crawler.py:421
Vulnerability Type: Server-Side Request Forgery and insecure plaintext transport
Risk Level: High

Vulnerable Code

python
def _csrc(self, days):
    return self._html([
        'http://www.csrc.gov.cn/csrc/c100028/common_list.shtml',
        'http://www.csrc.gov.cn/csrc/c100028/common_list2.shtml',
    ], 'csrc', '中国证券监督管理委员会', 'http://www.csrc.gov.cn', days)

def _pboc(self, days):
    return self._html([
        'http://www.pbc.gov.cn/goutongjiaoliu/113456/113469/index.html',
    ], 'pboc', '中国人民银行', 'http://www.pbc.gov.cn', days)
python
@staticmethod
def _abs(href, base):
    if href.startswith('http://') or href.startswith('https://'):
        return href
    if href.startswith('//'):
        return 'http:' + href
    if href.startswith('/'):
        return base.rstrip('/') + '/' + href.lstrip('/')
    return base.rstrip('/') + '/' + href
python
if summary and uniq:
    print('\n📝 抓取摘要…', file=sys.stderr)
    for i, it in enumerate(uniq):
        print(f'  [{i+1}/{len(uniq)}] {it["title"][:40]}', file=sys.stderr)
        it['summary'] = self._sum(it['url'])
        time.sleep(1)
python
def _sum(self, url, n=200):
    try:
        r = self.s.get(url, timeout=15)
        r.encoding = r.apparent_encoding or 'utf-8'
        soup = BeautifulSoup(r.text, 'lxml')
        for t in soup(['script', 'style', 'nav', 'footer', 'header']):
            t.decompose()
        for sel in ['.article-content', '.content', '.main-text', '#content',
                    '.detail-content', '.news-content', 'article', 'body']:
            b = soup.select_one(sel)
            if b:
                t = re.sub(r'\s+', ' ', b.get_text(strip=True))
                if len(t) > 50:
                    return t[:n] + ('…' if len(t) > n else '')
        return ''
    except Exception:
        return ''

Technical Anal

...[truncated 2779 chars]

Remediation
View remediation

Remediation Suggestions

  1. Replace all plaintext source URLs and base URLs with verified HTTPS endpoints.
  2. Reject every URL whose scheme is not HTTPS.
  3. Maintain an explicit hostname allowlist for each regulator and reject links outside the expected official domains.
  4. Resolve target hostnames before connecting and reject loopback, private, link-local, multicast, unspecified, and reserved IP ranges for both IPv4 and IPv6.
  5. Disable automatic redirects or validate the scheme, hostname, and resolved address of every redirect destination before following it.
  6. Apply the same validation immediately before the request to reduce DNS rebinding and time-of-check/time-of-use risks.
  7. Consider removing arbitrary linked-page retrieval entirely. If summaries are required, retrieve articles only from predefined official origins.
  8. Escape or sanitize untrusted titles and URLs before embedding them in Markdown.
  9. Add tests covering absolute external URLs, protocol-relative URLs, redirects, private addresses, IPv6 literals, encoded hostnames, and DNS rebinding scenarios.

T08 · Insecure Dependencies

Warning
Location
SKILL.md:46
Finding

Third-party dependencies are installed without version or integrity constraints

Content
View full analysis

Vulnerability Details

File Location: SKILL.md:46
Vulnerability Type: Unpinned and unverifiable third-party dependencies
Risk Level: Medium

Vulnerable Code

bash
pip install requests beautifulsoup4 lxml cloudscraper

Technical Analysis

The documented installation command retrieves mutable versions of four third-party packages without exact version pins, cryptographic hashes, or a lock file. Consequently, two installations performed at different times can resolve to different package versions.

If a dependency's publishing account or distribution channel is compromised, installation may retrieve a malicious release. Python packages can execute code during installation or when imported by crawler.py. Even without a malicious compromise, an incompatible future release could alter security-sensitive networking, parsing, proxy, or TLS behavior.

The reviewed package names do not exhibit evidence of typographical package substitution. The risk arises from unconstrained dependency resolution and absent artifact integrity verification.

Attack Path

  1. A maintainer account, package release, dependency distribution path, or package index is compromised.
  2. A malicious version of one of the named packages becomes the latest version accepted by pip.
  3. A user follows the documented installation command.
  4. pip resolves and installs the malicious release because no reviewed version or hash is required.
  5. Malicious package code executes during installation or when the crawler imports the package.
  6. The code runs with the privileges and data access of the user or automation account performing the installation or running the crawler.

Impact Assessment

A compromised dependency can execute arbitrary Python code with the privileges of the installing or executing account. Depending on that account's environment, this could expose local files, environment variables, proxy credentials, network access, or other process-accessible re ...[truncated 185 chars]

Remediation
View remediation

Remediation Suggestions

  1. Pin every direct dependency to an exact, reviewed version.
  2. Generate and commit a dependency lock file that includes transitive dependencies.
  3. Use pip --require-hashes with SHA-256 hashes for every resolved distribution.
  4. Install only from an explicitly configured trusted package index over HTTPS.
  5. Review and update dependencies through a controlled process with automated vulnerability and provenance checks.
  6. Prefer verified wheel artifacts and avoid source builds where they are unnecessary.
  7. Run dependency installation and the crawler in an isolated virtual environment or container with minimal filesystem and network privileges.
  8. Add automated dependency auditing, such as pip-audit, to the release and update workflow.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (5)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding

The skill instructs the agent to invoke a network-capable crawler, but the manifest does not declare any explicit tool scope such as permissions or allowed-tools. This creates a governance gap where network access may occur without clear restriction or review, increasing the chance of unintended outbound requests, scraping against unapproved domains, or misuse if the skill is triggered unexpectedly.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The trigger phrases are broad and map to common requests about recent policy, news, or announcements, so the skill may activate in situations where the user did not intend web scraping or regulator-specific monitoring. Because the skill then performs live network collection, accidental activation can lead to unnecessary external requests, unexpected data retrieval, and reduced user control over agent behavior.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The crawler sets the Accept-Language header to prefer zh-CN for outbound requests, which imposes a specific language/locale behavior in the skill without offering any user choice. This matches the policy category for language or locale constraints that are not opt-in or otherwise clearly justified in the file.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The requests session is configured with an Accept-Language header preferring zh-CN, enforcing a locale choice across requests without an explicit user opt-in. The file does not provide a language-selection mechanism or document a justified locale restriction.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

A separate cloudscraper session used for NFRA requests also hardcodes Accept-Language to zh-CN, repeating the same locale-policy issue. This creates a mandatory Chinese-language preference in network behavior with no user-selectable alternative.

Content

No source excerpt is available for this finding.