Skip to content
KitploitKITPLOIT
工具漏洞利用博客
Log in
提交
工具漏洞利用博客
提交

黑客、渗透测试和网络安全工具,武装您的安全武器库!

Kitploit 是一个黑客、网络安全和渗透测试工具的目录。发现最新的项目更新,查找漏洞、分析系统、自动化测试并加强你的安全。

··订阅源·联系·隐私·© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
gha-lab-e8902eccd3 — 安全研究实验室:复现 CVE-2025-52467(pgai pull_request_target 工作流代码执行 / GITHUB_TOKEN 泄露)——timescale/pgai 快照 | Kitploit
工具/GitHubGitHub/pvharmo2/gha-lab-e8902eccd3
漏洞分析漏洞利用学习与教育精选资源
GitHubpvharmo2/gha-lab-e8902eccd3

gha-lab-e8902eccd3

安全研究实验室:复现 CVE-2025-52467(pgai pull_request_target 工作流代码执行 / GITHUB_TOKEN 泄露)——timescale/pgai 快照

查看仓库
820天前尚未审核

最受欢迎

查看全部 →

发现我们社区最常用的工具。

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享

自动化研究产物 — 非上游项目。

本仓库是由自动化工具链构建的一次性实验环境,用于拉瓦尔大学(Université Laval)硕士论文中复现已公开的 GitHub Actions 工作流漏洞。它是 timescale/pgai 在提交 2a209b058c60823b57e8b7775b10244ff340eb8b(2025-05-14)时的逐字快照,依据该项目自身的许可证重新分发,该许可证文件已原样包含在本快照中。

上游项目未参与其中,也从未成为攻击目标,此处研究的漏洞已公开。本仓库中的每个密钥和变量均为随机生成的虚拟值——不包含任何真实凭据。操作引用和运行器镜像均固定为其在 2025-05-14 解析到的版本;有关对快照所做的每项更改,请参阅工具链输出中的 pinning.md。

如有疑问或异议:[email protected]


pgai pgai

借助 PostgreSQL 为您的 RAG 与 Agentic 应用赋能

文档 · 加入 pgai Discord 社区! · 免费试用 Timescale! · 更新日志

一个 Python 库,可将 PostgreSQL 转变为适用于 RAG 和 Agentic 应用的稳健、生产级检索引擎。

  • 🔄 自动从 PostgreSQL 数据和 S3 文档创建并同步向量嵌入。嵌入会随数据变化自动更新。

  • 🔍 借助 pgvector 和 pgvectorscale 实现强大的向量与语义搜索。

  • 🛡️ 开箱即用、生产就绪:支持批量处理以高效生成嵌入,并内置对模型故障、速率限制和延迟突增的处理机制。

  • 🐘 适用于任何 PostgreSQL 数据库,包括 Timescale Cloud、Amazon RDS、Supabase 等。

基本架构: 该系统由您编写的应用程序、一个 PostgreSQL 数据库以及无状态向量化工作进程组成。应用程序定义向量化配置,以从 PostgreSQL 或 S3 等来源嵌入数据。工作进程读取该配置,将数据队列处理为嵌入和分块文本,并将结果写回。随后,应用程序查询这些数据,为 RAG 和语义搜索提供支持。

该架构的关键优势在于其韧性:应用程序所做的数据修改与嵌入过程解耦,确保嵌入服务的故障不会影响核心数据操作。

Pgai 架构:应用程序、数据库、向量化工作进程

安装

首先,安装 pgai 包。``` pip install pgai

root@kitploit:~
然后,安装 pgai 数据库组件。你可以通过终端使用 CLI 来完成此操作,也可以在 Python 应用程序代码中使用 pgai Python 包来完成。```
# from the cli
pgai install -d <database-url>

# or from the python package, often done as part of your application setup
import pgai
pgai.install(DB_URL)

快速入门

本快速入门演示了 pgai Vectorizer 如何通过自动创建和同步嵌入(embeddings),在数据发生变化时实现对 PostgreSQL 数据的语义搜索和 RAG。

pgai Vectorizer 的关键“秘诀”在于其声明式的嵌入生成方法。只需定义你的流水线,让 Vectorizer 处理保持嵌入同步的运维复杂性,即使嵌入端点不可靠也能正常工作。你可以按如下方式定义流水线的简单版本:```sql CREATE TABLE IF NOT EXISTS wiki ( id INTEGER PRIMARY KEY GENERATED ALWAYS AS IDENTITY, url TEXT NOT NULL, title TEXT NOT NULL, text TEXT NOT NULL )

SELECT ai.create_vectorizer( 'wiki'::regclass, loading => ai.loading_column(column_name=>'text'), destination => ai.destination_table(target_table=>'wiki_embedding_storage'), embedding => ai.embedding_openai(model=>'text-embedding-ada-002', dimensions=>'1536') )

root@kitploit:~
向量化器会自动为`wiki`表中的所有行创建嵌入,更重要的是,它会随着底层数据的变化保持嵌入的同步更新。**可以把它想象成在`wiki`表上声明一个索引**,只不过不是由数据库替你管理索引数据结构,而是由Vectorizer来管理嵌入。

## 运行快速入门

**前提条件:**
- 一个PostgreSQL数据库([Docker安装说明](https://docs.timescale.com/self-hosted/latest/install/installation-docker/))。
- 一个OpenAI API密钥(快速入门中我们使用openai进行嵌入,但你也可以使用[多种提供商](#supported-embedding-models))。

创建一个包含以下内容的`.env`文件:```
OPENAI_API_KEY=<your-openai-api-key>
DB_URL=<your-database-url>

你可以从快速入门示例中下载完整的 python 代码 和 requirements.txt,并在与 .env 文件相同的目录下运行它。

点击此处获取用于运行快速入门的 bash 脚本```bash curl -O https://raw.githubusercontent.com/timescale/pgai/main/examples/quickstart/main.py curl -O https://raw.githubusercontent.com/timescale/pgai/main/examples/quickstart/requirements.txt python -m venv venv source venv/bin/activate pip install -r requirements.txt python main.py ```
示例输出:
点击展开示例输出``` Search results 1: [WikiSearchResult(id=7, url='https://en.wikipedia.org/wiki/Aristotle', title='Aristotle', text='Aristotle (; Aristotélēs, ; 384–322\xa0BC) was an ' 'Ancient Greek philosopher and polymath. His writings ' 'cover a broad range of subjects spanning the natural ' 'sciences, philosophy, linguistics, economics, ' 'politics, psychology and the arts. As the founder of ' 'the Peripatetic school of philosophy in the Lyceum in ' 'Athens, he began the wider Aristotelian tradition that ' 'followed, which set the groundwork for the development ' 'of modern science.\n' '\n' "Little is known about Aristotle's life. He was born in " 'the city of Stagira in northern Greece during the ' 'Classical period. His father, Nicomachus, died when ' 'Aristotle was a child, and he was brought up by a ' "guardian. At 17 or 18 he joined Plato's Academy in " 'Athens and remained there till the age of 37 (). ' 'Shortly after Plato died, Aristotle left Athens and, ' 'at the request of Philip II of Macedon, tutored his ' 'son Alexander the Great beginning in 343 BC. He ' 'established a library in the Lyceum which helped him ' 'to produce many of his hundreds of books on papyru', chunk='Aristotle (; Aristotélēs, ; 384–322\xa0BC) was an ' 'Ancient Greek philosopher and polymath. His writings ' 'cover a broad range of subjects spanning the natural ' 'sciences, philosophy, linguistics, economics, ' 'politics, psychology and the arts. As the founder of ' 'the Peripatetic school of philosophy in the Lyceum in ' 'Athens, he began the wider Aristotelian tradition ' 'that followed, which set the groundwork for the ' 'development of modern science.', distance=0.22242502364217387)] Search results 2: [WikiSearchResult(id=41, url='https://en.wikipedia.org/wiki/pgai', title='pgai', text='pgai is a Python library that turns PostgreSQL into ' 'the retrieval engine behind robust, production-ready ' 'RAG and Agentic applications. It does this by ' 'automatically creating vector embeddings for your data ' 'based on the vectorizer you define.', chunk='pgai is a Python library that turns PostgreSQL into ' 'the retrieval engine behind robust, production-ready ' 'RAG and Agentic applications. It does this by ' 'automatically creating vector embeddings for your ' 'data based on the vectorizer you define.', distance=0.13639101792546204)] RAG response: The main thing pgai does right now is generating vector embeddings for data in PostgreSQL databases based on the vectorizer defined by the user, enabling the creation of robust RAG and Agentic applications. ```

代码走查

安装 pgai 数据库组件

Pgai 需要在数据库中安装一些目录表和函数。这通过 pgai.install 函数完成,该函数会将必要的组件安装到数据库的 ai 模式中。```python pgai.install(DB_URL)

root@kitploit:~
### 创建向量化器

这里定义了向量化器,它告诉系统如何根据 `wiki` 表中的 `text` 列创建嵌入。向量化器会创建一个 `wiki_embedding` 视图,我们可以通过查询该视图来获取嵌入(如下所示)。```python
async def create_vectorizer(conn: psycopg.AsyncConnection):
    async with conn.cursor() as cur:    
        await cur.execute("""
            SELECT ai.create_vectorizer(
                'wiki'::regclass,
                if_not_exists => true,
                loading => ai.loading_column(column_name=>'text'),
                embedding => ai.embedding_openai(model=>'text-embedding-ada-002', dimensions=>'1536'),
                destination => ai.destination_table(view_name=>'wiki_embedding')
            )
        """)   
    await conn.commit()

运行向量化工作进程

在此示例中,我们运行一次向量化工作进程,为现有数据创建嵌入。```python worker = Worker(DB_URL, once=True) worker.run()

root@kitploit:~
在真实应用中,我们不会像这样每次创建嵌入时都手动调用 worker。相反,我们会让 worker 在后台运行,并持续运行,轮询 vectorizer 分配的工作。

你可以从应用程序、CLI 或 Docker 中在后台运行 worker。有关更多详细信息,请参阅 [vectorizer worker](https://github.com/pvharmo2/gha-lab-e8902eccd3/blob/main/docs/vectorizer/worker.md) 文档。


### 使用语义搜索检索 wiki 文章

这是 PostgreSQL 中标准的 pgvector 语义搜索。搜索针对 `wiki_embedding` 视图执行,该视图由 vectorizer 创建,包含 `wiki` 表中的所有列,外加 `embedding` 列和分块文本。此函数返回 `wiki` 表中完整的 `text` 列,以及与查询最相关的较小文本块。```python
@dataclass
class WikiSearchResult:
    id: int
    url: str
    title: str
    text: str
    chunk: str
    distance: float

async def _find_relevant_chunks(client: AsyncOpenAI, query: str, limit: int = 1) -> List[WikiSearchResult]:
    # Generate embedding for the query using OpenAI's API
    response = await client.embeddings.create(
        model="text-embedding-ada-002",
        input=query,
        encoding_format="float",
    )
    
    embedding = np.array(response.data[0].embedding)
    
    # Query the database for the most similar chunks using pgvector's cosine distance operator (<=>)
    async with pool.connection() as conn:
        async with conn.cursor(row_factory=class_row(WikiSearchResult)) as cur:
            await cur.execute("""
                SELECT w.id, w.url, w.title, w.text, w.chunk, w.embedding <=> %s as distance
                FROM wiki_embedding w
                ORDER BY distance
                LIMIT %s
            """, (embedding, limit))
            
            return await cur.fetchall()

向 wiki 表中插入新文章

这段代码值得注意的地方在于它没有做什么。这只是向 wiki 表中简单插入一篇新文章。我们无需做任何额外操作来创建嵌入,向量化工作进程会在数据变化时自动负责更新嵌入。```python def insert_article_about_pgai(conn: psycopg.AsyncConnection): async with conn.cursor(row_factory=class_row(WikiSearchResult)) as cur: await cur.execute(""" INSERT INTO wiki (url, title, text) VALUES ('https://en.wikipedia.org/wiki/pgai', 'pgai', 'pgai is a Python library that turns PostgreSQL into the retrieval engine behind robust, production-ready RAG and Agentic applications. It does this by automatically creating vector embeddings for your data based on the vectorizer you define.') """) await conn.commit()

root@kitploit:~
### 使用 LLM 执行 RAG

此代码使用 LLM 执行 RAG。它使用上面定义的 `_find_relevant_chunks` 函数从 `wiki` 表中查找最相关的文本块,然后使用 LLM 生成响应。```python
    query = "What is the main thing pgai does right now?"
    relevant_chunks = await _find_relevant_chunks(client, query)
    context = "\n\n".join(
        f"{chunk.title}:\n{chunk.text}" 
        for chunk in relevant_chunks
    )
    prompt = f"""Question: {query}

Please use the following context to provide an accurate response:   

{context}

Answer:"""

    response = await client.chat.completions.create({
        model: "gpt-3.5-turbo",
        messages: [{ role: "user", content: prompt }],
    })
    print("RAG response:")
    print(response.choices[0].message.content)

后续步骤

查看其他快速入门指南:

  • 使用 FastAPI 和 psycopg 的快速入门指南 在此

深入了解 vectorizer:

  • 了解更多关于 vectorizer 和 vectorizer worker 的信息
  • 深入了解 vectorizer API 参考文档

功能特性

我们的 pgai Python 库让您能够处理从数据生成的嵌入向量:

  • 使用 vectorizer 自动创建并同步数据的向量嵌入。
  • 从表中的列或文件、s3 存储桶等 加载数据。
  • 针对同一数据,使用不同模型和参数创建多个嵌入,用于测试和实验。
  • 自定义 嵌入管道解析、分块、格式化及嵌入数据的方式。

您可以使用向量嵌入来:

  • 使用 pgvector 执行语义搜索。
  • 实现检索增强生成(RAG)。
  • 借助 pgvectorscale(pgvector 的补充扩展),在大型向量工作负载上执行高性能、高性价比的 ANN 搜索。

我们还提供了一款 PostgreSQL 扩展,可直接从 SQL 中调用 LLM 模型。这对于分类、摘要以及对现有数据进行数据增强等用例通常非常有用。

可配置的 vectorizer 管道

vectorizer 的设计灵活且可定制。每个 vectorizer 都定义了一个从数据创建嵌入的管道。该管道由一系列按顺序应用于数据的组件组成:

  • 加载: 首先,定义要嵌入的数据来源。它可以是源表列中直接存储的数据,也可以是源表列中引用的 URI(指向文件、s3 存储桶等)。
  • 解析: 然后,如果数据是非文本文档(如 PDF、HTML 或 markdown 文件),定义数据的解析方式。
  • 分块: 接下来,定义文本数据如何拆分为块。
  • 格式化: 然后,针对每个块,定义数据在发送进行嵌入之前的格式化方式。例如,您可以将文档标题添加为块的第一行。
  • 嵌入: 最后,指定生成嵌入时要使用的 LLM 提供商、模型及参数。

支持的嵌入模型

以下模型支持用于嵌入:

  • Ollama
  • OpenAI
  • Voyage AI
  • Cohere
  • Huggingface
  • Mistral
  • Azure OpenAI
  • AWS Bedrock
  • Vertex AI

细节决定成败:错误处理

简单地创建向量嵌入是容易且直接的。挑战在于 LLM 在一定程度上并不可靠,且端点会表现出间歇性 故障和/或性能下降。正确处理故障的一个关键点是, 您的主要数据修改操作(INSERT、UPDATE、 DELETE)不应依赖于嵌入操作。否则,每当端点变慢或失败时, 您的应用程序就会宕机,用户体验也会受到影响。

通常,您需要实现一个自定义的 MLops 管道来正确处理 端点故障。这通常涉及 Kafka 之类的队列系统、专门的 worker,以及其他用于处理队列和重试失败请求的基础设施。这是 大量的工作,而且很容易出错。

使用 pgai,您可以跳过所有这些,专注于构建您的应用程序,因为 vectorizer 正在为您管理嵌入。我们内置了队列和 重试逻辑,以处理您可能遇到的各种故障模式。由于我们在 后台执行这项工作,因此主要的数据修改操作不会 依赖于嵌入操作。这就是 pgai 开箱即用即可投入生产的原因。

许多专门的向量数据库会为您创建嵌入。然而,当嵌入端点宕机或性能下降时,它们通常会失败,从而将错误处理和重试的负担重新抛回给您。

资源

我们构建它的原因

  • 向量数据库是错误的抽象
  • pgai:赋予 PostgreSQL 开发者 AI 工程超能力

快速入门指南

  • 上述使用 Ollama 的快速入门指南
  • 使用 OpenAI 快速入门
  • 使用 VoyageAI 快速入门

关于 pgai vectorizer 的教程

  • 如何通过一条 SQL 查询在 PostgreSQL 中自动创建和更新嵌入
  • [视频] 用一行 SQL 自动创建和同步向量嵌入
  • 哪个 OpenAI 嵌入模型最适合您的基于 Pgvector 的 RAG 应用?
  • 哪种 RAG 分块和格式化策略最适合您的基于 Pgvector 的应用
  • 使用开源工具解析所有数据:Unstructured 和 Pgai

贡献

我们欢迎对 pgai 的贡献!请参阅 贡献指南 页面了解更多信息。

参与其中

pgai 仍处于早期阶段。现在是帮助塑造该项目方向的绝佳时机; 我们目前正在确定优先级。请查看我们正在考虑开发的 功能列表。 欢迎发表评论、扩充列表,或加入 Discussions 论坛。

要开始使用,请查看 如何贡献 以及 如何搭建开发/测试环境。

关于 Timescale

Timescale 是一家 PostgreSQL 数据库公司。要了解更多信息,请访问 timescale.com。

Timescale Cloud 是一个高性能、面向开发者、提供 PostgreSQL 服务的云平台, 适用于要求最严苛的 AI、时间序列、分析和事件工作负载。Timescale Cloud 非常适合生产应用程序,并提供高可用性、流式备份、持续升级、角色和权限管理以及出色的安全性。

下载工具