T09 · Insecure Skill Coding Practices
- Location
scripts/generate_excel.py:91- Finding
Spreadsheet Formula Injection Through Student Names
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill mostly matches its homework grading purpose, but its Excel/PDF report generation can unsafely carry student-controlled data into files teachers may trust.
Install only in an isolated environment and treat all student names, answers, photos, JSON files, Excel files, and PDFs as sensitive. Do not use this for untrusted student-supplied names or answers unless the report generators are fixed to escape HTML, neutralize spreadsheet formulas, pin dependencies, and document where student data is stored and how it should be deleted.
scripts/generate_excel.py:91Spreadsheet Formula Injection Through Student Names
scripts/generate_pdf.py:146Unescaped HTML Injection During PDF Generation
正确答案: {kq['correct_answer']}
讲解建议: 该题错误人数较多,建议老师在课堂上详细讲解此题目。
""" ``` Student names are also inserted without escaping: ```python for student in student_stats: html_content += f""" {student['name']} {student['correct_count']} {student['incorrect_count']} {100 - student['error_rate']}% """ ``` The resulting attacker-influenced HTML is parsed by WeasyPrint: ```python HTML(string=html_content).write_pdf(output_path) ``` ### Technical Analysis Student names and correct answers originate from supplied JSON or OCR-derived data and are interpolated directly into an HTML document. The code does not apply HTML escaping or use a template engine with automatic escaping. An attacker can terminate the expected text context and insert arbitrary HTML elements. Because WeasyPrint resolves resources referenced by elements and styles during rendering, injected markup can potentially cause the PDF-generation process to request attacker-selected URLs. Depending on the WeasyPrint version, operating environment, and URL-fetcher configuration, the injected content may also attempt to access local resources. Even when resource access is blocked, arbitrary markup can alter the report structure, conceal legitimate information, impersonate report sections, or place deceptive content in the generated PDF. ### Attack Path 1. An attacker influences a student name o ...[truncated 1350 chars]scripts/requirements.txt:1Unpinned and Incomplete Third-Party Dependency Declaration
The documented behavior materially overstates the implemented functionality, including bulk grading, class-wide analytics, Excel/PDF generation, and direct grading from student photos. This mismatch can cause operators to trust outputs that are incomplete, fabricated, or based on different inputs than expected, which is especially risky in educational workflows involving student records and grading decisions.
Referenced artifact was not completely inspected
pip install -r scripts/requirements.txt
Referenced artifact was not completely inspected
pip install -r scripts/requirements.txt
The skill advertises file read/write-capable behavior but does not declare any explicit tool scope or permission boundaries. In an agent environment, this increases the chance of overbroad filesystem access, unintended reads of unrelated files, or writes to arbitrary locations during report generation and intermediate data handling.
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.
# Ubuntu/Debian
sudo apt install tesseract-ocr
# macOS
brew install tesseract
The skill explicitly handles student homework photos, names, grading results, and generated reports without any privacy notice, retention policy, or guidance on sensitive educational data handling. This creates a risk of exposing personally identifiable student information and assessment data through stored images, spreadsheets, or PDFs.
This code file contains its title, docstrings, usage instructions, and runtime messages exclusively in Chinese, including the command help and dependency guidance. Under the policy rule, forcing a specific language without opt-in or an explicit justified locale constraint is a natural-language policy violation.
The manifest description, headings, trigger phrases, and example commands are all presented in Chinese, including required user utterances like '生成统计表' and '设置阈值为 30%'. This can be a natural-language policy issue if the skill effectively forces a specific language without user opt-in or an explicitly documented regional justification.
The HTML template hard-codes major user-facing labels and the report title in Chinese, such as the page title and section headings, while only the footer includes limited English text. This can violate a language/locale policy when a skill imposes one language by default without explicit user opt-in or documented regional justification.
This markdown file contains user-facing instructions exclusively in Chinese, which can constitute a language/locale policy issue when no opt-in, alternative language, or justification is provided. The policy specifically calls for flagging skills that force a specific language without user choice.
This markdown file presents the output format exclusively in Chinese, beginning with the title and continuing throughout the document. Under the policy rule, forcing a specific language without offering a choice or documenting a justified locale constraint can be a natural-language policy violation.
The module docstring, dependency message, function-facing status output, and CLI usage text are written only in Chinese. This imposes a specific language on users without any opt-in or indication that the skill is intentionally limited to a Chinese-speaking context, which matches the language/locale policy concern.
The dependency 'pillow' is unpinned, so installs are not reproducible and may unexpectedly pull a vulnerable or breaking release. In this skill, Pillow processes uploaded homework images, making dependency integrity and version control more important because image parsing libraries have a long history of memory-safety and denial-of-service issues.
pillow
pytesseract
openpyxl
Pillow has multiple historical advisories, including code execution and resource-consumption issues, and the manifest does not pin a version, so the deployed release could be vulnerable. This is more concerning here because the skill processes untrusted uploaded images from students and teachers, which directly exercises Pillow's attack surface.
The dependency 'pytesseract' is unpinned, which allows different environments to resolve different versions with potentially unreviewed behavior or transitive dependency changes. In a grading workflow that handles teacher- and student-supplied files at scale, this weakens supply-chain assurance and can complicate patch validation and incident response.
pillow
pytesseract
openpyxl
The dependency 'openpyxl' is unpinned, creating supply-chain uncertainty and making it impossible to guarantee that deployment will use a patched release. Because this skill generates Excel reports and may consume spreadsheet-related data, predictable and patched XML/office-file handling is important to reduce exposure to parser-related vulnerabilities.
pillow
pytesseract
openpyxl
Openpyxl has known XXE-related advisories, and because the dependency is unpinned, there is no assurance that the installed version includes the relevant fixes. In this skill, spreadsheet generation and possible spreadsheet handling increase the relevance of XML parser hardening, though the risk is somewhat lower if the application only writes XLSX files and never ingests attacker-controlled spreadsheets.