OleksandrVelychko/genai-security-assistant

GitHub: OleksandrVelychko/genai-security-assistant

基于 OWASP 官方文档构建的 GenAI 安全知识库流水线,将多格式原始文档自动转换为带有结构化元数据和智能分块的高质量数据集,为 RAG 安全问答助手提供可溯源的底层知识支撑。

Stars: 0 | Forks: 0

# GenAI 安全助手 — 知识库 这是一个用于检索增强生成聊天机器人的知识库,用于回答有关保护生成式 AI 和 LLM 应用程序的问题,基于官方 OWASP 来源构建。 本仓库是端到端 RAG 助手的第一阶段 (HW1): `原始来源 → 标准化文档 → 数据块 → 元数据 → 已处理的知识库`。 ## 主题领域 **GenAI / LLM 应用程序安全。** 该助手旨在回答实际问题,例如*“我该如何防止 prompt injection?”*,*“什么是过度代理以及如何缓解?”* 或*“在部署 LLM 应用程序之前,治理检查清单应包含哪些内容?”* 范围被刻意缩小:六份涵盖三个风险领域的 OWASP 文档(prompt injection、敏感信息泄露、过度代理)以及跨领域的治理。 ## 来源 所有来源均由 OWASP 在 **CC-BY-SA 4.0** 许可下发布,并在每个数据块的元数据(`publisher`、`source_url`、`license`)中注明出处。 | 文档 | 类型 | 格式 | 风险类别 | |---|---|---|---| | LLM01:2025 Prompt Injection | security_risk | HTML | prompt_injection | | LLM02:2025 Sensitive Information Disclosure | security_risk | HTML | sensitive_information_disclosure | | LLM06:2025 Excessive Agency | security_risk | HTML | excessive_agency | | LLM Prompt Injection Prevention Cheat Sheet | cheat_sheet | Markdown | prompt_injection | | AI Agent Security Cheat Sheet | cheat_sheet | Markdown | excessive_agency | | LLM Applications Cybersecurity and Governance Checklist | checklist | PDF | governance | 来源在 `configs/sources.yaml` 中声明,而不是在代码中,因此 pipeline 不依赖于任何特定的文档集。 ## 项目结构 ``` src/genai_security_assistant/ config.py # settings + source manifest loading models/documents.py # typed pydantic contracts ingestion/ loaders/ # markdown / html / pdf -> sections base.py # loader interface markdown.py html.py pdf.py normalization.py # sections + manifest -> NormalizedDocument chunking.py # structure-aware chunking metadata.py # chunk ids and metadata assembly pipeline.py # orchestration validation.py # quality checks scripts/ prepare_knowledge_base.py # thin CLI: build the knowledge base validate_knowledge_base.py # thin CLI: quality report data/ raw/ # original source documents normalized/documents.jsonl processed/chunks.jsonl # final deliverable configs/ base.yaml # pipeline parameters sources.yaml # source manifest + controlled vocabularies tests/ unit/ingestion/ integration/ ``` 业务逻辑位于包中;`scripts/` 仅负责将其组装并打印。 ## Pipeline ``` data/raw/*.{md,html,pdf} │ ▼ loaders format-specific parsing into sections │ ▼ normalization + manifest metadata, content_hash, retrieved_at data/normalized/documents.jsonl │ ▼ chunking structure-aware splitting with overlap │ ▼ metadata chunk_id + flattened provenance data/processed/chunks.jsonl │ ▼ validation quality report / CI gate ``` ## 元数据结构 `data/processed/chunks.jsonl` 的每一行都是一个 chunk: ``` { "chunk_id": "...", "text": "...", "metadata": { ... } } ``` | 字段 | 来源 | 用途 | |---|---|---| | `chunk_id` | 生成 | `{document_id}_chunk_{index:03d}`,稳定且可排序 | | `document_id`, `source_file`, `source_type` | 清单 | chunk 的出处 | | `source_url`, `publisher`, `license` | 清单 | 版权归属(CC-BY-SA 要求) | | `title`, `section`, `heading_path` | 加载器 | chunk 在文档中的位置 | | `chunk_index` | 生成 | 文档内的顺序 | | `language`, `domain` | 清单 | 语料库级别的过滤 | | `document_type`, `risk_category` | 策展人 | 用于元数据过滤的受控词汇 | | `doc_version` | 文档 | 发布者标记的版本,如果没有则为 `null` | | `retrieved_at`, `content_hash` | pipeline | 新鲜度跟踪(原始文件的 SHA-256) | 元数据按来源分为四种类型: - 从来源**观察得到**(`source_url`, `title`, `language`, `source_type`) - 由策展人**分配**(`document_type`, `risk_category` — 在 `configs/sources.yaml` 顶部记录的受控词汇) - 文档**固有**(`doc_version`,当发布者未标记时为 `null`) - **机器生成**(`chunk_id`, `chunk_index`, `content_hash`, `retrieved_at`) 存在 `content_hash` 和 `retrieved_at` 是为了使未来的重新摄取能够检测哪些上游文档实际发生了更改,并仅对它们进行重新分块。 受控词汇是强制执行的,而不仅仅是记录在文档中:`document_type` 和 `risk_category` 是 `models/documents.py` 中的 `Literal` 类型,因此在验证时会拒绝未知值,而不是将其静默存储。 ## 分块策略 `chunk_size = 700`,`chunk_overlap = 150`,`min_chunk_size = 200`,策略为 `structure_aware`。规则按优先级顺序如下: 1. **章节边界是硬性的。** 两个文档章节永远不会共享同一个 chunk。 2. 在一个章节内,累积整个段落/列表项直到达到 `chunk_size`。 3. 过长的段落按**句子**边界拆分。 4. 过长的句子按**单词**边界拆分 — 绝不会在单词中间拆分。 5. 围栏代码块保持**原子性**;如果太长,则按**行**边界拆分。 6. 重叠部分由前一个 chunk 的**最后几个完整句子**构成,因此没有 chunk 会从句子中间开始。 7. 过小的片段在三个级别被折叠回去:分块前的整个章节、累积期间的中间流片段以及末尾片段。 这取代了简单的固定宽度切片(`text[start:end]`),后者会将单词、句子和代码示例切成两半。 ## 示例 chunk #### owasp_llm01_prompt_injection_chunk_001 (html) HTML 来源:去除页面边框元素后的干净提取 ``` { "chunk_id": "owasp_llm01_prompt_injection_chunk_001", "text": "A Prompt Injection Vulnerability occurs when user prompts alter the LLM’s behavior or output in unintended ways. These inputs can affect the model even if they are imperceptible to humans, therefore prompt injections do not need to be human-visible/readable, as long as the content is parsed by the model.", "metadata": { "document_id": "owasp_llm01_prompt_injection", "source_file": "data/raw/owasp_llm01_prompt_injection.html", "source_type": "html", "source_url": "https://genai.owasp.org/llmrisk/llm01-prompt-injection/", "title": "LLM01:2025 Prompt Injection", "section": "LLM01:2025 Prompt Injection", "heading_path": [ "LLM01:2025 Prompt Injection" ], "chunk_index": 1, "language": "en", "domain": "genai_security", "document_type": "security_risk", "risk_category": "prompt_injection", "publisher": "OWASP Gen AI Security Project", "doc_version": "2025", "retrieved_at": "2026-07-18T15:51:25.931554Z", "content_hash": "82f21555ca25c2a31989d2f482feefe3856b1344f29e0154210fdf8f176f6827" } } ``` #### owasp_llm01_prompt_injection_chunk_002 (html) 同一文档的下一个 chunk:注意句子对齐的重叠 ``` { "chunk_id": "owasp_llm01_prompt_injection_chunk_002", "text": "are imperceptible to humans, therefore prompt injections do not need to be human-visible/readable, as long as the content is parsed by the model.\nPrompt Injection vulnerabilities exist in how models process prompts, and how input may force the model to incorrectly pass prompt data to other parts of the model, potentially causing them to violate guidelines, generate harmful content, enable unauthorized access, or influence critical decisions. While techniques like Retrieval Augmented Generation (RAG) and fine-tuning aim to make LLM outputs more relevant and accurate, research shows that they do not fully mitigate prompt injection vulnerabilities.", "metadata": { "document_id": "owasp_llm01_prompt_injection", "source_file": "data/raw/owasp_llm01_prompt_injection.html", "source_type": "html", "source_url": "https://genai.owasp.org/llmrisk/llm01-prompt-injection/", "title": "LLM01:2025 Prompt Injection", "section": "LLM01:2025 Prompt Injection", "heading_path": [ "LLM01:2025 Prompt Injection" ], "chunk_index": 2, "language": "en", "domain": "genai_security", "document_type": "security_risk", "risk_category": "prompt_injection", "publisher": "OWASP Gen AI Security Project", "doc_version": "2025", "retrieved_at": "2026-07-18T15:51:25.931554Z", "content_hash": "82f21555ca25c2a31989d2f482feefe3856b1344f29e0154210fdf8f176f6827" } } ``` #### owasp_cs_prompt_injection_prevention_chunk_001 (markdown) Markdown 来源:标题路径保留作为章节上下文 ``` { "chunk_id": "owasp_cs_prompt_injection_prevention_chunk_001", "text": "Prompt injection is a vulnerability in Large Language Model (LLM) applications that allows attackers to manipulate the model's behavior by injecting malicious input that changes its intended output. Unlike traditional injection attacks, prompt injection exploits the common design of most LLMs where natural language instructions and data are processed together without clear separation.\n**Key impacts include:**\n- Bypassing safety controls and content filters\n- Unauthorized data access and exfiltration\n- System prompt leakage revealing internal configurations\n- Unauthorized actions via connected tools and APIs\n- Persistent manipulation across sessions", "metadata": { "document_id": "owasp_cs_prompt_injection_prevention", "source_file": "data/raw/owasp_llm_prompt_injection_prevention_cheat_sheet.md", "source_type": "markdown", "source_url": "https://raw.githubusercontent.com/OWASP/CheatSheetSeries/master/cheatsheets/LLM_Prompt_Injection_Prevention_Cheat_Sheet.md", "title": "LLM Prompt Injection Prevention Cheat Sheet", "section": "Introduction", "heading_path": [ "LLM Prompt Injection Prevention Cheat Sheet", "Introduction" ], "chunk_index": 1, "language": "en", "domain": "genai_security", "document_type": "cheat_sheet", "risk_category": "prompt_injection", "publisher": "OWASP Cheat Sheet Series", "doc_version": null, "retrieved_at": "2026-07-18T15:51:25.964538Z", "content_hash": "581a9bb96bc934fa277fde7610b6e05fdd485d79ff617851de99fc1262f56f74" } } ``` #### owasp_llm_governance_checklist_chunk_001 (pdf) PDF 来源:修复了连字,页面级章节 ``` { "chunk_id": "owasp_llm_governance_checklist_chunk_001", "text": "Overview\nEvery internet user and company should prepare for the upcoming wave of powerful generative\nartificial intelligence (GenAI) applications. GenAI has enormous promise for innovation, efficiency,\nand commercial success across a variety of industries. Still, like any powerful early stage technology,\nit brings its own set of obvious and unexpected challenges.\nArtificial intelligence has advanced greatly over the last years, inconspicuously supporting a\nvariety of corporate processes until ChatGPT’s public appearance drove the development and use of\nLarge Language Models (LLMs) among both individuals and enterprises. Initially, these technologies", "metadata": { "document_id": "owasp_llm_governance_checklist", "source_file": "data/raw/owasp_llm_governance_checklist.pdf", "source_type": "pdf", "source_url": "https://genai.owasp.org/resource/llm-applications-cybersecurity-and-governance-checklist-english/", "title": "LLM Applications Cybersecurity and Governance Checklist", "section": "Page 5", "heading_path": [ "Page 5" ], "chunk_index": 1, "language": "en", "domain": "genai_security", "document_type": "checklist", "risk_category": "governance", "publisher": "OWASP Gen AI Security Project", "doc_version": null, "retrieved_at": "2026-07-18T15:51:26.504796Z", "content_hash": "583457f34081dc4487ffc72530aa80e32edef8086637e3d7e3a59cb1a4511426" } } ``` ## 质量报告 由 `scripts/validate_knowledge_base.py` 生成: ``` Chunks parsed : 264 Parse errors : 0 Length min/avg/max: 190 / 491 / 920 Chunks per document: owasp_cs_ai_agent_security 58 owasp_cs_prompt_injection_prevention 50 owasp_llm01_prompt_injection 26 owasp_llm02_sensitive_information_disclosure 19 owasp_llm06_excessive_agency 25 owasp_llm_governance_checklist 86 Chunks per source type: html 70 markdown 108 pdf 86 duplicate chunk_id : OK empty text : OK below min_chunk_size : 1 found above 1000 characters: OK unmapped glyphs : OK RESULT: PASS ``` 阻塞性失败(格式错误的 JSON、重复的 ID、空文本)会使脚本以非零状态退出,因此它可以用作 CI 门控。软质量信号(略低于最小值的 chunk、可疑的字形)会被报告,但不会导致构建失败。 ## 效果良好的方面 - **结构感知分块。** 没有 chunk 在单词或句子中间开始或结束,并且代码示例完好无损。长度保持在 190–920 个字符之内。 - **清单驱动的摄取。** 添加来源只需编辑 YAML,无需更改代码。 - **类型化契约。** 受控词汇是 `Literal` 类型,因此无效的 `risk_category` 在验证时会被拒绝,而不是被静默存储。 - **从第一天起就有出处记录。** 每个 chunk 都带有其 URL、许可证、版本、检索时间戳和内容哈希。 - **通过测量发现问题,而不是靠猜测。** 一个重叠过大 bug(一个 chunk 达到了 1915 个字符)和支离破碎的代码块都是通过检查长度分布和最短的 chunk 发现的,然后通过回归测试将其锁定。 ## 待改进之处 - **PDF 提取是最薄弱的环节。** 源 PDF 嵌入了没有 Unicode 映射的字体,因此 `fi`/`fl` 连字和一些数字被解码为 `U+FFFF`。连字通过启发式方法修复,但丢失的数字是无法恢复的 — “Figure 1:” 变成了 “Figure .:”。使用不同的提取器或 OCR 回退将是正确的解决方法。 - **PDF 分页是基于页面的。** 没有可靠的标题检测,`section` 只是 `Page N`,这比 HTML/Markdown 的标题路径上下文更弱。 - **未检测到缩进代码块。** 只有围栏(```)块保持原子性;四空格缩进的代码仍被视为散文并按单词拆分。 - **没有去重。** LLM01 风险页面和 prompt injection 速查表的内容有重叠,因此在检索时近似重复的 chunk 可能会产生竞争。 - **尚无增量重新摄取。** 存储了 `content_hash` 但尚未用于跳过未更改的文档 — 这是朝向计划刷新的自然下一步。 - **平均 chunk 长度 (491) 低于 700 的目标值**,因为章节边界提前结束了 chunk。这是一个旨在牺牲统一大小以换取可读性的刻意权衡。 - **目录过滤器是一种启发式方法。** 它以点引导符(句号比例超过 0.15)为关键点,如果目录页的样式不同,则会漏掉它。 ## 复现 ``` uv sync uv run python scripts/prepare_knowledge_base.py uv run python scripts/validate_knowledge_base.py uv run pytest -q ``` ## 许可证和归属 源文档归 © OWASP Foundation 所有,许可为 **CC-BY-SA 4.0**。归属信息按 chunk 保存在 `metadata.publisher`、`metadata.source_url` 和 `metadata.license` 中。本仓库中的 pipeline 代码为作者本人的作品。
标签:DLL 劫持, RAG, Ruby, 后端开发, 大语言模型, 文档处理, 生成式AI安全, 知识库, 虚拟机, 逆向工具