Back to skill

Security audit

Contract Review Skill

Security checks for vulnerabilities and agentic risk

Overview

This contract-review skill mostly runs locally and matches its stated purpose, but it has serious review-accuracy and file-write issues that should be fixed before normal use.

Review carefully before installing. The skill appears intended for local contract analysis and does not show network exfiltration, but its risk labels can be wrong, and bundled helper scripts can write or import in unsafe ways. Do not rely on its legal-risk summary until the scoring logic is fixed and the maintenance/batch scripts are removed, confined, or clearly documented.

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

other

Error
Location
review_engine.py:146
Finding

Risk Scoring Logic Reports More Dangerous Contracts as Safer

Content
View full analysis
int: """Calculate overall risk score (0-100, lower is better).""" if not findings: return 10 # Low risk if no issues found weights = { RiskLevel.CRITICAL: 25, RiskLevel.HIGH: 15, RiskLevel.MEDIUM: 8, RiskLevel.LOW: 3 } total_penalty = sum(weights[f.risk_level] for f in findings) penalty = min(total_penalty, 90) return 10 + penalty ``` ```python # contract_reviewer.py:61-70 # Determine risk level label (lower score means higher risk) if risk_score >= 80: risk_label = "LOW" elif risk_score >= 60: risk_label = "MEDIUM" elif risk_score >= 40: risk_label = "HIGH" else: risk_label = "CRITICAL" ``` ```python # batch_reviewer.py:190-199 def _score_to_level(self, score: int) -> str: """Convert risk score to level label""" if score >= 80: return "LOW" elif score >= 60: return "MEDIUM" elif score >= 40: return "HIGH" else: return "CRITICAL" ``` ### Technical Analysis Each finding adds a positive penalty to the score. Consequently, more findings and more severe findings produce a higher score. The two output formatters, however, interpret higher scores as lower risk. For example, four critical findings add 100 points before capping, producing a score of `100`. Both formatters classify that result as `LOW`. Conversely, a contract with no findings receives a score of `10`, which is classified as `CRITICAL`. This is an integrity failure in a security-sensitive decision-support function. Although it does not directly grant system access, it reverses the central safety conclusion delivered t ...[truncated 789 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
batch_reviewer.py:205
Finding

Caller-Controlled Batch Report Path Allows Arbitrary File Overwrite

Content
View full analysis
str: """Save batch review results to file""" if not output_file: timestamp = datetime.now().strftime("%Y%m%d_%H%M%S") output_file = self.results_dir / f"batch_review_report_{timestamp}.json" with open(output_file, 'w', encoding='utf-8') as f: json.dump(batch_results, f, indent=2, ensure_ascii=False) return str(output_file) ``` ### Technical Analysis When `output_file` is supplied, the method passes it directly to `open(..., 'w')`. There is no canonicalization, allowed-directory check, symlink check, overwrite confirmation, or exclusive file creation. Opening an existing file in `w` mode immediately truncates it. An untrusted caller that can influence this method argument can therefore overwrite any file writable by the Skill process. The default CLI path is generated internally, but the public method remains unsafe for integrations, agent calls, or future command-line exposure. ### Attack Path 1. An attacker obtains control over the `output_file` argument through an integration or agent workflow that exposes `save_batch_report`. 2. The attacker supplies an absolute path or path-traversal value targeting a writable file. 3. The method opens the target in `w` mode without validation. 4. The existing file is truncated and replaced by serialized batch report data. 5. The affected application or user subsequently consumes the corrupted file. A symlink placed at an expected report path could also redirect a write if an attacker can modify the report directory. ### Impact Assessment The write executes with the same filesystem privileges as the Python process. Potential impact includes destruction or corruption of user configuration, application da ...[truncated 192 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
fix_json.py:71
Finding

Maintenance Script Unconditionally Overwrites an Absolute User-Profile File

Content
View full analysis
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
batch_reviewer.py:14
Finding

Ancestor Directory Import Enables Local Dependency Hijacking

Content
View full analysis
Remediation
View remediation

other

Note
Location
batch_results/batch_review_report_20260427_095105.json:14
Finding

Bundled Batch Reports Disclose Developer Username and Local Filesystem Paths

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • 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
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (7)

Context Leakage

High
Category
Data Exfiltration
Confidence
75% confidence
Finding

Code or instructions that leak agent conversation context to external services, potentially exposing sensitive user interactions.

Content

Scanner excerpt · review_engine.py (reported line 98)May include surrounding context.

python
# Simple regex search - in production, might use more sophisticated NLP
            matches = list(re.finditer(pattern, text, re.IGNORECASE))
            for match in matches:
                # Extract context around match
                start = max(0, match.start() - 50)
                end = min(len(text), match.end() + 50)
                context = text[start:end]

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
86% confidence
Finding

This JSON file contains batch processing results and metadata, but provides no explicit trigger phrases, activation constraints, or exclusion conditions. For a manifest-scope file, the absence of any invocation boundaries is overly broad and leaves unclear when the skill should activate versus not activate.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The helper is documented and used as converting a numeric risk score into a risk level label, but the implementation maps higher scores to lower severity labels: scores >= 80 return "LOW" while the lowest scores return "CRITICAL". In a contract review manager, that inverts the apparent meaning of the reported risk labels and contradicts the surrounding intent of producing risk summaries.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

This code reads the full contents of a user-supplied contract file and passes it into a review engine, which is a safety-relevant operation because contracts often contain confidential or sensitive information. The file includes no confirmation prompt, privacy notice, or user-facing disclosure about sensitive data handling beyond a generic usage string.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
90% confidence
Finding

At L71-L72, the script opens a hard-coded path for writing and overwrites the target JSON file. Although it prints success afterward, there is no disclosure before the write occurs and no confirmation step, so the file-modifying behavior is not warned about in advance.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
81% confidence
Finding

This JSON defines clause-detection patterns entirely around English legal terminology such as 'confidentiality', 'governing law', and similar phrases, but provides no natural-language indication that the skill is limited to English contracts or that users can choose another language. That can create a language-policy issue because the skill implicitly assumes one language/locale without documented opt-in or justification.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
77% confidence
Finding

The suggestion text includes fixed locale-specific examples, "State of California" and "Peoples Republic of China," as normative governing-law options. In a reusable skill/config file, naming specific jurisdictions without stating that they are merely examples or that jurisdiction should be user-selected can create an implicit locale bias contrary to language/locale neutrality expectations.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.