Back to skill

Security audit

钢筋数量表核对 / Rebar Table Audit

Security checks for vulnerabilities and agentic risk

Overview

The skill appears to do the CAD audit it claims, but it needs Review because drawing text can be written into Excel cells in a way spreadsheet apps may treat as formulas.

Review before installing if you will process drawings from third parties. Treat generated XLSX files as untrusted until the package escapes strings beginning with =, +, -, or @; prefer evidence.json/report.md or open spreadsheets with external links/formulas disabled. Configure ODA_FILE_CONVERTER or LIBREDWG_DWG2DXF only to trusted converter binaries.

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
rebar_table_audit/report.py:127
Finding

Spreadsheet Formula Injection Through Untrusted CAD Text

Content
View full analysis

Vulnerability Details

File Location: rebar_table_audit/report.py:127-160; input originates from rebar_table_audit/extract.py:195-201
Vulnerability Type: Spreadsheet formula injection
Risk Level: Medium

Technical Analysis

Text extracted from externally supplied DWG or DXF entities is preserved without neutralizing spreadsheet formula prefixes:

python
raw_text = _text_string(entity)
if raw_text is None or raw_text.strip() == "":
    return
x, y = _text_position(entity)
normalized = normalize_text(raw_text)
result.texts.append(TextItem(
    text=normalized,
    raw=raw_text,
    x=x,
    y=y,
    height=_text_height(entity),
    handle_path=handle_path,
    layout=layout_name,
))

Parsed drawing values, including the table title, mark, and position, are then passed directly to openpyxl worksheet cells:

python
for row in _grade_summary(evidence["tables"]):
    ws_sum.append([
        row["table_id"],
        row["title"],
        row["grade"],
        row["row_sum_kg"],
        row["declared_kg"],
        row["diff_kg"],
    ])
python
for t in evidence["tables"]:
    for r in t["rows"]:
        p = r["parsed"]
        handles = ";".join(sorted({h for c in r["cells"] for h in c["handles"]}))
        ws_detail.append([
            t["id"], p["mark"], p["position"], p["grade"], p["grade_source"],
            p["diameter_mm"], p["single_length_m"], p["count"],
            p["total_length_m"], p["weight_kg"],
            p["unit_weight_kg_per_m"], handles,
        ])

openpyxl treats strings beginning with = as formulas when saving a workbook. The code performs Unicode normalization but does not neutralize formula-leading characters before placing drawing-derived strings into spreadsheet cells.

This crosses a trust boundary because content authored by an independent CAD document provider is transferred into an interpretation-ca ...[truncated 1761 chars]

Remediation
View remediation

Remediation Suggestions

Introduce a centralized function for all externally derived spreadsheet strings and apply it before every worksheet write:

python
def spreadsheet_literal(value):
    if not isinstance(value, str):
        return value
    if value.startswith(("=", "+", "-", "@")):
        return "'" + value
    return value

Apply the function to table titles, marks, positions, grades, finding messages, gap messages, symbol mappings, raw text, and every other value derived from a drawing or custom mapping file.

For stronger guarantees, explicitly set externally derived cells to the string data type rather than relying solely on prefix handling. Keep numeric values generated by trusted parsing logic numeric where calculations or sorting are required.

Add regression tests that generate a workbook from drawing fields beginning with =, +, -, and @, reload it with openpyxl, and verify that the resulting cells are literal strings rather than formulas. Tests should include representative payloads such as =HYPERLINK(...) and confirm that legitimate negative numeric values remain numeric.

Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • YARA SignaturesMalware Match, Webshell Match, Cryptominer Match
Findings (24)

YARA rule 'agent_skill_remote_bootstrap_execution': Remote script or code download followed by execution/bootstrap installation [agent_skills]

High
Category
YARA Match
Confidence
85% confidence
Finding

YARA rule matched a known malware signature (reverse shell, backdoor, ransomware, C2 framework, or info stealer).

Content

Scanner excerpt · README.md (reported line 17)May include surrounding context.

� evidence.json + 钢筋数量表.xlsx + report.md。 每个单元格值、每条疑点都带图元 handle,可以点回原图核实。

不做什么:不从配筋图几何独立算钢筋(翻样);不处理扫描件/PDF/BIM 模型; 算术不一致只报「疑点 + 证据」,不下"设计错误"结论。

安装

从 GitHub 直接安装(需要 git):

bash
python -m pip install git+https://github.com/dongsheng123132/rebar-table-audit@v0.1.0

装好后命令是 rebar-audit;也可以不装命令、只装依赖后在仓库目录里用 python -m rebar_table_audit ...(参数相同)。

本地开发安装(克隆仓库后):

bash
python -m venv .venv
# Windows
./.venv/Scripts/python.exe -m pip install -e .
# macOS/Linux
./.venv/bin/python -m pip install -e .

依赖:Python ≥3.10、ezdxf>=1.4、openpyxl>=3.1(跑测试再加 pytest: pip install -e ".[dev]")。

DWG 转换器(自行安装,二选一)

本包**�

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The entire skill description and operational guidance are written in Chinese, with no indication that users may choose another language or that the skill is intentionally limited to a Chinese-speaking or China-specific audience. Under the stated policy, forcing a specific language without opt-in is a natural-language policy violation.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding

The skill documentation indicates operational capabilities that include reading files, writing outputs, invoking Python, and potentially executing external converters, but it does not declare any explicit tool restrictions such as allowed-tools or permissions. This creates a trust and containment gap: an agent runtime may grant broader shell, filesystem, or environment access than is actually required, increasing the blast radius if the skill is abused, misconfigured, or later modified.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The package description is written entirely in Chinese and specifies outputs such as evidence.json, xlsx, and report.md in that context, indicating the skill may be constrained to Chinese-language operation. There is no accompanying note that the language choice is optional, user-selectable, or justified as a region-specific tool.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

This code embeds user-facing help text, status messages, and summaries entirely in Chinese, and the parser description/help strings continue that pattern throughout the file. Under the policy rule, forcing a specific language without user opt-in is a natural-language policy violation unless the locale constraint is explicitly documented and justified.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
83% confidence
Finding

The module-level docstring is entirely in Chinese and describes the skill behavior only in that language. Under the policy for natural-language violations, forcing a specific language without user opt-in or a documented region-specific justification is a reportable locale/language constraint.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · rebar_table_audit/convert.py (reported line 66)May include surrounding context.

python
def _libredwg_version(path: Path) -> Optional[str]:
    try:
        out = subprocess.run([str(path), "--version"], capture_output=True, text=True, timeout=15)
        text = (out.stdout or "") + (out.stderr or "")
        m = re.search(r"(\d+\.\d+(?:\.\d+)?)", text)
        return m.group(0) if m else None

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · rebar_table_audit/convert.py (reported line 100)May include surrounding context.

python
out_dir.mkdir(parents=True, exist_ok=True)
        cmd = [info.path, str(tmp_in_path), str(out_dir), "ACAD2018", "DXF", "0", "1", dwg_path.name]
        try:
            proc = subprocess.run(cmd, capture_output=True, text=True, timeout=timeout)
        except subprocess.TimeoutExpired as exc:
            raise ConversionError(f"ODAFileConverter 超时(>{timeout}s),可能弹出了 GUI 或卡死:{exc}") from exc
        expected = out_dir / (dwg_path.stem + ".dxf")

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · rebar_table_audit/convert.py (reported line 118)May include surrounding context.

python
out_dir.mkdir(parents=True, exist_ok=True)
        cmd = [info.path, str(tmp_in_path), str(out_dir), "ACAD2018", "DXF", "0", "1", dwg_path.name]
        try:
            proc = subprocess.run(cmd, capture_output=True, text=True, timeout=timeout)
        except subprocess.TimeoutExpired as exc:
            raise ConversionError(f"ODAFileConverter 超时(>{timeout}s),可能弹出了 GUI 或卡死:{exc}") from exc
        expected = out_dir / (dwg_path.stem + ".dxf")

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The natural-language docstring states the skill reads DXF and produces outputs using Chinese filenames/content, and the implementation consistently emits Chinese sheet names and report text. This indicates a fixed language/locale behavior without any visible opt-in or user choice, which matches the language/locale policy violation criteria.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

SQP-3 applies to all file types and covers language or locale policy violations in natural-language content, including code comments and docstrings. This file begins with a Chinese-only module docstring and continues with Chinese-only explanatory comments, which forces a specific language for maintainers or users without any opt-in or stated regional justification.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · tests/test_cli.py (reported line 16)May include surrounding context.

python
def _run_cli(*args):
    cmd = [sys.executable, "-m", "rebar_table_audit.cli", *args]
    return subprocess.run(cmd, capture_output=True, text=True, timeout=60)


def test_clean_table_exit_0_and_json_stdout_clean(tmp_path):

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

This code file includes top-level natural-language documentation entirely in Chinese, and many subsequent comments/docstrings are also Chinese-only. Under the stated policy, forcing a specific language without user opt-in is a natural-language locale violation unless the constraint is explicitly justified or optional.

Content

No source excerpt is available for this finding.

Unverifiable Dependency: setuptools has 10 known advisory(ies) (CVE-2013-1633 (Setuptools vulnerable to Man-in-the-middle attacks); CVE-2025-47273 (setuptools has a path traversal vulnerability in PackageIndex.download that lead); CVE-2024-6345 (setuptools vulnerable to Command Injection via package URL) +7 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
40% confidence
Finding

Dependency has known vulnerabilities (CVEs). Using packages with unpatched security flaws exposes the environment to known exploits.

Content

No source excerpt is available for this finding.

Unverifiable Dependency: openpyxl has 2 known advisory(ies) (CVE-2017-5992 (Improper Restriction of XML External Entity Reference in Openpyxl); CVE-2017-5992 (Openpyxl 2.4.1 resolves external entities by default, which allows remote attack)), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
40% confidence
Finding

Dependency has known vulnerabilities (CVEs). Using packages with unpatched security flaws exposes the environment to known exploits.

Content

No source excerpt is available for this finding.

Unverifiable Dependency: pytest has 2 known advisory(ies) (CVE-2025-71176 (pytest has vulnerable tmpdir handling); CVE-2025-71176 (pytest has vulnerable tmpdir handling)), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
40% confidence
Finding

Dependency has known vulnerabilities (CVEs). Using packages with unpatched security flaws exposes the environment to known exploits.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
79% confidence
Finding

The only natural-language description in the file is written entirely in Chinese and presents the skill purpose in that language without any indication that users may choose another language or locale. Under the policy, language constraints should not be imposed implicitly without user opt-in or clear justification.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

This manifest-style JSON contains all descriptive natural-language fields in Chinese, with no indication of language choice or opt-in. Under the policy rule for language or locale constraints, this can be considered a forced locale for users or operators who may not read Chinese.

Content

No source excerpt is available for this finding.

Vague Triggers

Low
Category
Not specified by scanner
Confidence
78% confidence
Finding

This JSON manifest-like file includes only a schema identifier and data payload, with no explicit activation scope, trigger phrases, or exclusion conditions. If this file is used as part of skill metadata, the lack of trigger specificity could contribute to ambiguous invocation behavior.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
91% confidence
Finding

The natural-language strings are entirely in Chinese and do not indicate that the skill is region-specific or that users may choose another language. This can violate language/locale policy expectations when a skill implicitly forces one language without opt-in or justification.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
83% confidence
Finding

The file’s natural-language documentation is entirely in Chinese, including the top-level docstring and explanatory comments. Per the policy, forcing a specific language without offering a choice or documenting a justified locale constraint can be a language/locale policy violation.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

The file’s primary natural-language instructions are written exclusively in Chinese and present the skill behavior in that locale/language without any indication of user choice or opt-in. Under the policy rule, forcing a specific language can be a locale/language policy violation when no alternative or opt-in is offered.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
85% confidence
Finding

The natural-language docstring is written entirely in Chinese and presents the test description in a single fixed language. Under the policy, forcing a specific language without user opt-in can be a locale-policy violation unless the constraint is explicitly justified, which is not stated here.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

The module docstring is written entirely in Chinese, which can impose a language requirement on users or maintainers without any opt-in or explanation of a region-specific purpose. Under the policy, locale or language constraints should either be optional or clearly justified.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.