Back to skill

Security audit

论文专利交底

Security checks for vulnerabilities and agentic risk

Overview

This skill fits its patent-writing purpose, but weak protections for saved API keys and redirected requests warrant review.

Start with fictional demo material. Before using paid credentials, require private key-file permissions and authenticated requests restricted to approved HTTPS destinations with safe redirect handling; avoid sending keys through chat. Review PatentMax's [privacy policy](https://www.ip930.com/legal/privacy) before uploading unpublished research, since the supplied paper text leaves your computer.

Vulnerability Patterns
  • 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
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Output HandlingUnvalidated Output Injection, Cross-Context Output, Unbounded Output
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (26)

Tainted flow: 'req' from os.environ.get (line 166, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/patentmax_disclosure.py (reported line 170)May include surrounding context.

python
req.add_header("Content-Type", "application/json")
    req.add_header("Accept", "application/json")
    try:
        with urllib.request.urlopen(req, timeout=30) as response:
            payload = json.loads(response.read().decode("utf-8"))
    except urllib.error.HTTPError as exc:
        _, message = _server_error(exc.read().decode("utf-8", "replace"))

Tainted flow: 'req' from os.environ.get (line 246, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
94% confidence
Finding

Authenticated API calls are expected, but request unconditionally attaches the bearer key without enforcing HTTPS or an approved destination origin. An HTTP-configured endpoint exposes credentials and research material to interception, and urllib's default redirect handling can forward the Authorization header to another origin if the endpoint redirects there.

Content

Scanner excerpt · scripts/patentmax_disclosure.py (reported line 255)May include surrounding context.

python
req.add_header(key, value)

    try:
        with urllib.request.urlopen(req, timeout=TIMEOUT) as response:
            payload = response.read()
            return payload if raw else json.loads(payload.decode("utf-8"))
    except urllib.error.HTTPError as exc:

The paper-submission workflow lacks a warning that research content is sent to a third-party service.

High
Category
Output Handling
Confidence
94% confidence
Finding

The workflow directs the agent to submit the user's paper through a service-backed generation script without explicitly explaining that research content will leave the local environment or obtaining informed consent to that transfer. Confirmation of the case details and price does not establish consent to disclose unpublished research to a third party; unauthorized transfer could expose confidential inventions and trade secrets, although the actual transmission scope and service handling cannot be verified from SKILL.md alone. This is especially sensitive because the skill specifically solicits unpublished, potentially patentable research.

Content

No source excerpt is available for this finding.

Code capability 'env' detected in scripts/patentmax_disclosure.py but not covered by declared permissions.

High
Category
MCP Least Privilege
Confidence
75% confidence
Finding

The skill uses 'env' capability that is not covered by the declared 'allowed-tools' preapproval. Review the host runtime's actual enforcement policy; runtime permissions are unknown unless separately verified, and this declaration alone does not establish a permission ceiling.

Content

No source excerpt is available for this finding.

Code capability 'network' detected in scripts/patentmax_disclosure.py but not covered by declared permissions.

High
Category
MCP Least Privilege
Confidence
75% confidence
Finding

The skill uses 'network' capability that is not covered by the declared 'allowed-tools' preapproval. Review the host runtime's actual enforcement policy; runtime permissions are unknown unless separately verified, and this declaration alone does not establish a permission ceiling.

Content

No source excerpt is available for this finding.

Paper contents are submitted to an external commercial service, although the manifest only describes patent analysis and Word generation.

High
Category
Excessive Agency
Confidence
96% confidence
Finding

The client submits assembled paper and invention contents to an external commercial service, while the supplied skill description does not disclose that transfer. The --yes gate confirms payment rather than informed consent to external processing; unpublished patent material makes unauthorized disclosure especially consequential, although uploading alone does not establish public publication or loss of patent rights.

Content

No source excerpt is available for this finding.

The submission workflow sends invention materials to PatentMax without a privacy warning.

Medium
Category
Output Handling
Confidence
95% confidence
Finding

The fallback workflow instructs submission of invention materials and ideas without a privacy warning or an explicit approval checkpoint in the supplied file. Because this skill specifically handles potentially unpublished research, uncertainty about the provider's retention, access, and reuse practices is more consequential than for ordinary public text.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
87% confidence
Finding

This POST transmits the supplied research body to PatentMax when populated and executed. External processing is consistent with the documented service, but the supplied workflow lacks an informed-consent safeguard for sensitive research; this is the same underlying exposure identified by SDI-1 and SQP-2, not evidence of a separate malicious channel.

Content

Scanner excerpt · references/faq.md (reported line 60)May include surrounding context.

bash
# 提交交底书
curl -s -X POST "https://api.ip930.com/api/v1/reports" \
  -H "Authorization: Bearer $PATENTMAX_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 任取一个唯一串" \

External Transmission

Medium
Category
Data Exfiltration
Confidence
87% confidence
Finding

The URL is the destination for the research-submission POST, so the relevant risk is sending confidential invention content without an explicit approval checkpoint. This finding duplicates the other findings on the same POST; HTTPS protects transport but does not establish permission to share the content with the provider.

Content

Scanner excerpt · references/faq.md (reported line 60)May include surrounding context.

bash
# 提交交底书
curl -s -X POST "https://api.ip930.com/api/v1/reports" \
  -H "Authorization: Bearer $PATENTMAX_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 任取一个唯一串" \

L60–L64 transmit research material to an external PatentMax API, although the manifest only describes analyzing papers and generating a Word disclosure.

Medium
Category
Excessive Agency
Confidence
90% confidence
Finding

The documented submission sends research text and an invention title to a third-party service, while the supplied skill description does not disclose external processing. Unpublished inventions can contain valuable confidential information, so following this workflow without informed authorization creates a significant confidentiality risk; the example itself contains only placeholders.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
87% confidence
Finding

The idea-generation POST sends user-provided idea text to the external service. Early invention ideas may be confidential even before a disclosure is drafted, so this endpoint needs the same authorization safeguards as the full research submission; there is no evidence that the destination is malicious.

Content

Scanner excerpt · references/faq.md (reported line 67)May include surrounding context.

md
-d '{"report_type":"technical_disclosure","input":{"supplement":"材料正文……","title_hint":"案件名称"}}'

# 出方向
curl -s -X POST "https://api.ip930.com/api/v1/reports" \
  -H "Authorization: Bearer $PATENTMAX_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 任取一个唯一串" \

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · references/faq.md (reported line 75)May include surrounding context.

md
# 查状态
curl -s -H "Authorization: Bearer $PATENTMAX_API_KEY" \
  "https://api.ip930.com/api/v1/operations/<operation_id>"

# 取结果
curl -s -H "Authorization: Bearer $PATENTMAX_API_KEY" \

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · references/faq.md (reported line 79)May include surrounding context.

md
# 取结果
curl -s -H "Authorization: Bearer $PATENTMAX_API_KEY" \
  "https://api.ip930.com/api/v1/reports/<report_id>"

# 下载交底书 / 核对说明
curl -s -H "Authorization: Bearer $PATENTMAX_API_KEY" -o 技术交底书.docx \

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · references/faq.md (reported line 83)May include surrounding context.

下载交底书 / 核对说明

curl -s -H "Authorization: Bearer $PATENTMAX_API_KEY" -o 技术交底书.docx
"https://api.ip930.com/api/v1/reports/<report_id>/files/report.docx" curl -s -H "Authorization: Bearer $PATENTMAX_API_KEY" -o 核对说明.docx
"https://api.ip930.com/api/v1/reports/<report_id>/files/report.docx?kind=notes"

text

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · references/faq.md (reported line 85)May include surrounding context.

curl -s -H "Authorization: Bearer $PATENTMAX_API_KEY" -o 技术交底书.docx
"https://api.ip930.com/api/v1/reports/<report_id>/files/report.docx" curl -s -H "Authorization: Bearer $PATENTMAX_API_KEY" -o 核对说明.docx
"https://api.ip930.com/api/v1/reports/<report_id>/files/report.docx?kind=notes"

text

**`Idempotency-Key` 必填。** 同一个键重试不会重复扣费,但同一个键配不同的材料会被拒绝。

The workflow submits invention materials to a remote service without warning users about the disclosure of potentially confidential information.

Medium
Category
Output Handling
Confidence
96% confidence
Finding

The workflow directs the agent to submit invention documents and supplemental technical details to a server, but its confirmation step discloses only cost and processing time, not the transfer of confidential research to a third party. Unpublished patent materials can contain trade secrets and commercially sensitive implementation details, making uninformed transmission particularly consequential in this skill's context. The supplied file does not establish the service's confidentiality or retention safeguards; transmission alone does not necessarily constitute public disclosure or invalidate patent rights.

Content

No source excerpt is available for this finding.

The error-handling instructions require the agent to relay Chinese messages verbatim without offering a language choice.

Medium
Category
Output Handling
Confidence
93% confidence
Finding

The docstring explicitly tells the AI to repeat the Chinese user-facing error message unchanged and not rewrite it. This imposes Chinese on error responses regardless of the user's language, without an opt-in or a documented regional compliance justification; the same requirement also appears at L017.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · references/faq.md (reported line 7)May include surrounding context.

md
| 现象 | 处理 |
| --- | --- |
| `免费试用额度已用完` / `免费试用只开通了……` | 免费试用的额度用完了,或者想用别的功能。注册 PatentMax 再送 ¥50 体验额度,创建密钥后 `export PATENTMAX_API_KEY=pm_live_xxx`:https://api.ip930.com/features/api-platform |
| `免费试用密钥已过期或失效` | 本地缓存已自动清掉,重跑同一条命令会领新的;或者换成正式密钥 |
| `HTTP 401` | 密钥无效或已撤销,到控制台重新创建 |
| `HTTP 402` | 余额不足,到控制台充值 |

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/patentmax_disclosure.py (reported line 128)May include surrounding context.

python
# 密钥版(TRIAL_SOURCE 为空):必须设 PATENTMAX_API_KEY,不领试用。
TRIAL_SOURCE = "patent-disclosure-cn"
TRIAL_GROUP = "disclosure"
TRIAL_REGISTER_URL = "https://api.ip930.com/features/api-platform"
KEY_FROM_TRIAL = False

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/patentmax_disclosure.py (reported line 207)May include surrounding context.

python
if API_KEY:
        return API_KEY
    if not TRIAL_SOURCE:
        die("还没有设置 PatentMax 密钥。到 https://api.ip930.com/features/api-platform 注册(新用户送 ¥50 体验额度)"
            "并创建密钥,设成环境变量 PATENTMAX_API_KEY=pm_live_xxx 后,再运行同一条命令。", EXIT_INPUT)
    API_KEY = _load_trial_key() or _claim_trial_key()
    KEY_FROM_TRIAL = True

Tainted flow: 'path' from os.environ.get (line 183, credential/environment) → open (file write)

Medium
Category
Data Flow
Confidence
88% confidence
Finding

Persisting a trial key is legitimate, but the file is opened and populated before its permissions are restricted to 0600. With a permissive umask or a preexisting broadly readable file, another local user could read the credential before chmod; the cache-directory environment variable is not itself the vulnerability.

Content

Scanner excerpt · scripts/patentmax_disclosure.py (reported line 186)May include surrounding context.

python
path = _trial_key_path()
    try:
        os.makedirs(os.path.dirname(path), exist_ok=True)
        with open(path, "w", encoding="utf-8") as fh:
            json.dump({
                "api_key": key,
                "expires_at": data.get("expires_at"),

Tainted flow: 'operation' from os.environ.get (line 641, credential/environment) → open (file write)

Medium
Category
Data Flow
Confidence
65% confidence
Finding

Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Content

Scanner excerpt · scripts/patentmax_disclosure.py (reported line 318)May include surrounding context.

python
record.update({k: v for k, v in fields.items() if v is not None})
    try:
        os.makedirs(os.path.dirname(_task_path(operation)), exist_ok=True)
        with open(_task_path(operation), "w", encoding="utf-8") as fh:
            json.dump(record, fh, ensure_ascii=False, indent=2)
    except OSError:
        pass

Progress reporting invents percentages despite a docstring explicitly promising not to do so.

Medium
Category
Excessive Agency
Confidence
99% confidence
Finding

The L494 docstring promises to show only status and elapsed time when the server supplies no stepped progress, explicitly stating that percentages are not invented. However, L503-L504 unconditionally calls shown_progress() for running operations, whose L478-L488 logic advances percentages using elapsed-time estimates even without corresponding server progress, presenting synthetic progress as an ordinary completion percentage.

Content

No source excerpt is available for this finding.

Tainted flow: 'saved' from os.environ.get (line 588, credential/environment) → open (file write)

Medium
Category
Data Flow
Confidence
65% confidence
Finding

Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Content

Scanner excerpt · scripts/patentmax_disclosure.py (reported line 589)May include surrounding context.

python
path += "?kind=notes"
        payload = request(path, raw=True)
        saved = unique_path(os.path.join(target, name))
        with open(saved, "wb") as handle:
            handle.write(payload)
        files[kind] = saved
    full = unique_path(os.path.join(target, f"{DOC_NAME}_{stem}_结果.json"))

Tainted flow: 'full' from os.environ.get (line 592, credential/environment) → open (file write)

Medium
Category
Data Flow
Confidence
65% confidence
Finding

Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Content

Scanner excerpt · scripts/patentmax_disclosure.py (reported line 593)May include surrounding context.

python
handle.write(payload)
        files[kind] = saved
    full = unique_path(os.path.join(target, f"{DOC_NAME}_{stem}_结果.json"))
    with open(full, "w", encoding="utf-8") as handle:
        json.dump(result, handle, ensure_ascii=False, indent=2)

    figures = result.get("figures") or []

Static analysis

No suspicious patterns detected.