T09 · Insecure Skill Coding Practices
- Location
scripts/utils/report_generator.py:184- Finding
Spreadsheet Formula Injection in CSV and Excel Reports
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This appears to be a real CVE scanner, but its spreadsheet exports and dependency/network handling need review before use.
Use this only in an isolated Python environment. Prefer JSON or Markdown output until CSV/XLSX formula sanitization is fixed, and treat generated spreadsheets from untrusted manifests as unsafe to open. Assume package names and versions from scanned files may be sent to NVD, OSV.dev, GitHub, and package registries. Avoid passing API tokens on the command line and pin dependencies with hashes before production use.
scripts/utils/report_generator.py:184Spreadsheet Formula Injection in CSV and Excel Reports
requirements.txt:2Unpinned Third-Party Dependencies Allow Unreviewed Package Updates
The dependency pin django==3.2.0 is a genuine vulnerable version with numerous published advisories, including SQL injection and resource-exhaustion issues. In the context of a security-scanning skill, shipping a requirements file that includes known-vulnerable packages is dangerous because it can mislead users into installing an insecure environment or using it as a sample baseline without realizing the exposure.
The declared description presents a full vulnerability scanning skill with external advisory-source querying, version analysis, dependency-file ingestion, and multi-format report output. The supplied code chunk is only an init.py for a utility package that re-exports internal classes. On its own, this code does not implement or demonstrate the core declared behavior. Because the actual code shown has a materially different and much narrower purpose than the declared skill description, this is a mismatch.
이 코드 조각의 실제 역할은 CVE 스캐너의 보조 유틸리티로 보이는 '독립 소프트웨어 → CPE 정보' 매핑 DB를 제공하는 것이다. Docker, Kubernetes, 운영체제, 웹서버 등 다양한 독립 소프트웨어 항목을 사전에 정의하고, 이름 정규화, 별칭 조회, 타입별 목록화, 통계 출력만 수행한다. 선언된 설명의 핵심인 취약점 데이터 소스(NVD/OSV/GitHub Advisory) 조회, 사용자가 제공한 버전 기반 판별, 최신 버전 확인, 보안 리포트 생성, 의존성 파일 업로드 처리 등은 이 코드에 전혀 나타나지 않는다. 보조 구성요소로서 전체 스킬의 일부일 가능성은 있지만, 제공된 코드 조각 자체는 선언된 설명을 정확히 대표하지 않으며 primary behavior가 상당히 다르다.
The declared description centers on vulnerability scanning and security report generation. In contrast, this code only tests whether package names map to expected ecosystems using local detection functions. There is no network access, no advisory-source querying, no CVE analysis, no file-ingestion logic, and no output formatting beyond console test results. This is a materially different primary purpose, so the description does not accurately represent the supplied code chunk.
설명은 완전한 오픈소스 취약점 분석 스킬을 주장하지만, 실제 코드 조각은 '최신 버전 검색'과 '패키지 생태계 감지'를 시험하는 테스트 파일이다. 외부 접근도 선언된 보안 데이터베이스가 아니라 npm/PyPI/Maven/crates.io 패키지 레지스트리에 한정된다. 최신 버전 조회는 선언된 스킬의 보조 기능일 수 있으나, 이 코드의 주된 목적은 취약점 분석이 아니라 테스트 실행이다. 따라서 설명과 실제 동작 사이에 중요한 불일치가 있다.
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
'CryptoSwift': 'Swift',
'GRDB.swift': 'Swift',
'Hero': 'Swift',
'KeychainAccess': 'Swift',
'Kingfisher': 'Swift',
'Kitura': 'Swift',
'Lottie': 'Swift',
numpy==1.19.0 is flagged by multiple advisories and represents a true vulnerable dependency finding. Although NumPy issues are often less directly exploitable than web-framework flaws, vulnerable numerical/parsing code can still enable denial of service, memory-safety issues, or unsafe file handling depending on how the package is used.
tensorflow==2.4.0 has many published security advisories and is a true vulnerable dependency. TensorFlow vulnerabilities have historically included crafted-model/input parsing flaws that may lead to denial of service or memory corruption, which is especially concerning if this skill processes untrusted ML artifacts or data files.
The skill advertises capabilities that imply network access, file handling, environment-variable use, and shell execution, but it does not declare any explicit tool scope or permission boundaries. In an agent environment, missing scope declarations can allow broader-than-necessary access and make it unclear what the skill is authorized to do, increasing the chance of unintended data exposure or unsafe execution.
The description says dependency files can be uploaded and analyzed against external services, but it does not disclose that package/version data or file-derived dependency information may be transmitted to NVD, OSV.dev, or GitHub. This creates a privacy and confidentiality risk, especially for private repositories, unreleased products, or internal dependency inventories that can reveal sensitive technology choices.
The trigger terms include broad words like 'CVE', '취약점', 'vulnerability', 'security audit', and 'dependency check', which can activate the skill during ordinary discussion rather than an intentional scan request. In a skill that may read dependency files and contact external services, over-triggering can cause unintended data handling, privacy leakage, or user confusion about what was sent externally.
The scanner sends package names and versions to multiple third-party registries and advisory services without an explicit warning or consent boundary. In enterprise or private-project contexts, dependency names and pinned versions can reveal internal technology choices, unpublished components, or vulnerable stack details to external services.
The manifest describes a package/dependency vulnerability scanner for ecosystems like npm and PyPI, but this file adds separate logic to classify names such as nginx, docker, or ubuntu as independent software and scan them using NVD CPE searches. That broadens the skill from package/dependency analysis into general software vulnerability assessment, which is a meaningful behavior expansion beyond the stated description.
Accepting API secrets directly through CLI flags exposes them to shell history, process listings, audit logs, and job runners. An attacker with local multi-user access or access to CI logs/process metadata may recover the NVD or GitHub credentials and reuse them for unauthorized API access or quota exhaustion.
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
class OSVClient:
"""Client for OSV.dev API"""
BASE_URL = "https://api.osv.dev/v1"
SOURCE_NAME = "OSV"
# Ecosystem name mappings
Dynamic import() can load arbitrary modules at runtime, bypassing static analysis and potentially importing malicious code.
print(
f"[{source_name}] Attempt {attempt + 1}/{max_retries + 1} failed: {e}. "
f"Retrying in {delay:.1f}s...",
file=__import__('sys').stderr
)
time.sleep(delay)
Dynamic import() can load arbitrary modules at runtime, bypassing static analysis and potentially importing malicious code.
print(
f"[{source_name}] Attempt {attempt + 1}/{max_retries + 1} failed: {e}. "
f"Retrying in {delay:.1f}s...",
file=__import__('sys').stderr
)
time.sleep(delay)
The generated markdown report uses Korean headings and labels such as "취약점 분석 리포트" and "패키지별 상세 분석" with no indication that the user can select another language. This imposes a specific language/locale in natural-language output without user opt-in or documented justification.
The code creates CSV/XLSX files on local disk as a side effect and returns the filename, rather than only generating report content in memory. In an agent/skill context, implicit file creation can violate user expectations, leave sensitive vulnerability data behind on the host, and enable persistence of scan results without explicit consent.
When version information is missing, the function claims to behave conservatively but actually suppresses pre-2020 CVEs based only on the CVE year. In a security scanning skill, this can cause false negatives and hide still-relevant older vulnerabilities, leading users to trust incomplete results and potentially miss serious exposure.
The module docstring and multiple user-facing status messages are written in Korean, indicating a fixed locale for interaction. The file does not offer any language selection or explain that the skill is intentionally region-specific, which can violate language/locale policy requirements.
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
start = time.time()
try:
result = subprocess.run(
cmd,
capture_output=True,
text=True,
This markdown file uses Korean throughout, and there is no indication that the skill is region-specific or that users can opt into another language. Under the stated policy, forcing a specific language without user opt-in is a natural-language policy violation.
The script executes dynamically constructed shell commands with eval, which is dangerous because eval re-parses the string as shell syntax and enables command injection if any part of the command becomes attacker-controlled. In this test helper the current call sites are hardcoded, which reduces immediate exploitability, but within an agent skill context any future reuse with variable input, environment influence, or copied patterns could lead to arbitrary command execution.
The manifest describes a vulnerability-scanning skill that queries advisory sources and produces reports, but this file implements orchestration by invoking another script through subprocess.run. Executing local processes is a broader operational capability than the stated package-analysis purpose and is not explicitly declared in the manifest.