Back to skill

Security audit

Loan Calculator 贷款真相计算器

Security checks for vulnerabilities and agentic risk

Overview

This is a disclosed local loan-cost calculator with no evidence of data theft, persistence, or privilege abuse, but its financial outputs and input handling need caution.

Install only if you are comfortable with a Chinese-language, China-market loan calculator that runs local Python scripts. Treat the reports as estimates, especially for daily-interest products, and avoid feeding extreme or adversarial numeric inputs until validation limits are added.

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
scripts/parser.py:391
Finding

Unbounded Loan Period Input Can Cause Resource Exhaustion

Content
View full analysis

Vulnerability Details

File Location: scripts/parser.py:391-399, with affected allocation and iteration sinks in scripts/calculator.py:122, 180, 227, 279, 296, 388, 392, 439, 443-449, 479, 482
Vulnerability Type: Uncontrolled resource consumption and insufficient numeric input validation
Risk Level: Medium

Vulnerable Code

python
# scripts/parser.py:391-399

# Period count
m = re.search(r'分?(\d+)\s*期', text)
if m:
    return int(m.group(1))

# Months
m = re.search(r'(\d+)\s*个月', text)
if m:
    return int(m.group(1))

The resulting unbounded value is used directly in memory allocations and loops. Representative sinks include:

python
# scripts/calculator.py:275-296

total_fee = monthly_fee * months
total_payment = principal + total_fee

# Calculate the actual annualized rate using IRR
cash_flows = [-principal] + [monthly_payment] * months
irr = calculate_irr(cash_flows)

if irr is None:
    return {
        'error': 'IRR calculation failed',
        'monthly_payment': round(monthly_payment, 2),
        'total_fee': round(total_fee, 2),
        'total_payment': round(total_payment, 2),
    }

# Compound annualized APR = (1+irr)^12 - 1
apr = (1 + irr) ** 12 - 1
nominal_rate = monthly_fee_rate * 12
fee_multiplier = apr / nominal_rate if nominal_rate > 0 else float('inf')

schedule = []
for i in range(1, months + 1):
    schedule.append({
        'period': i,
        'payment': round(monthly_payment, 2),
        'principal': round(monthly_principal, 2),
        'fee': round(monthly_fee, 2),
        'remaining': round(principal - monthly_principal * i, 2),
    })

Technical Analysis

The natural-language parser accepts any sequence of digits as a loan period and converts it to an integer without checking whether the value is positive or within a practical maximum. The calculator subsequently uses this user-controlled value for list multiplication, cash-flow construction, repayment-schedule generation, and repeated numerical o ...[truncated 1915 chars]

Remediation
View remediation

Remediation Suggestions

  1. Validate parsed period counts immediately after extraction:
python
MAX_MONTHS = 1200

def _validate_months(months: int) -> int:
    if not isinstance(months, int) or isinstance(months, bool):
        raise ValueError("The period count must be an integer.")
    if not 1 <= months <= MAX_MONTHS:
        raise ValueError(
            f"The period count must be between 1 and {MAX_MONTHS}."
        )
    return months
  1. Apply equivalent validation inside every public calculator function. Parser-side validation alone is insufficient because callers may invoke calculator functions directly.

  2. Impose practical bounds on all user-controlled numeric inputs, including actual_days, principal, rates, payment amounts, and iteration limits. Reject non-finite values by using math.isfinite().

  3. Return a controlled validation error rather than allowing division-by-zero, OverflowError, or MemoryError to terminate report generation.

  4. Avoid generating complete schedules when they are not required. Since reports display only the first six and last periods, calculate those entries directly or enforce a strict schedule-size limit.

  5. Add regression tests for:

    • months = 0
    • Negative direct API values
    • Extremely large period counts
    • Values just below, at, and above the configured maximum
    • Excessively large actual_days
    • Non-finite direct inputs such as float("inf") and float("nan")
  6. Run calculations under process-level CPU and memory limits as defense in depth.

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

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The README presents all instructions, examples, and disclaimers only in Chinese, which can amount to a language/locale policy violation when no user opt-in or alternative language is offered. Although the subject matter is China-specific, the file does not explicitly state that the skill is limited to Chinese-speaking users or region-specific use.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The trigger section includes broad everyday intents such as '对比多个贷款方案', '不理解某个贷款术语', and any input containing generic loan-related keywords. It does not define clear boundaries or exclusion conditions, so ordinary conversation about loans could activate the skill unintentionally.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill explicitly instructs the agent to execute Python code derived from user input, creating a code-execution pathway without any trust boundary discussion or user-facing warning. Even though the shown snippet embeds input as data, normalizing script execution as mandatory increases the chance of unsafe implementation patterns elsewhere and can lead to command/code injection, local file access, or execution of unreviewed helper modules in the scripts directory.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The entire skill file is written in Chinese and does not indicate that users may choose another language or that the content is intentionally restricted to a China-specific audience. Under the policy, language or locale constraints should either be optional for the user or clearly documented and justified.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

This file contains user-facing descriptions, docstrings, error messages, and terminology exclusively in Chinese, which effectively enforces a specific language/locale. Under the policy, language constraints should either offer user choice or be clearly documented as region-specific and justified.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The function for daily-interest loans labels its output as a 'real APR' but only computes daily_rate × 365, which is a nominal linear annualization rather than an IRR-based effective cost calculation. In a financial calculator whose stated purpose is to expose disguised loan costs, this can mislead users about the true borrowing cost and cause materially incorrect lending comparisons or consumer decisions.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The module docstring and embedded natural-language handling are explicitly Chinese-focused, and the file contains no indication that users can opt into another language or that the restriction is a documented regional requirement. Under the policy rule, forcing a specific language without user choice is a natural-language policy concern.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The module docstring explicitly says it generates Chinese reports, which is a natural-language locale constraint. Under the policy, forcing a specific language without user opt-in is a violation unless the locale restriction is clearly documented and justified as region-specific.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
80% confidence
Finding

The skill content is written to operate in Chinese and is framed specifically around the Chinese loan market and regulatory context, but it does not explicitly state that the skill is limited to Chinese-language or China-specific use. This can amount to a language/locale restriction without opt-in or clear justification in the activation or usage policy.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

This file contains user-facing instructional content only in Chinese, which can be a natural-language policy issue if organizational policy requires language neutrality or user opt-in for locale-specific content. There is no indication that the skill is region-specific or that users can choose their preferred language.

Content

No source excerpt is available for this finding.