17-AI应用防止越权访问知识库

AI 应用如何防止用户越权访问知识库

系列:从零构建企业 RAG 知识库(第 17 篇)

1. 越权不只发生在向量检索

攻击路径可能出现在:

  • 猜测文档 ID 直接下载原文;
  • 缓存复用其他用户答案;
  • 关键词索引有权限、向量索引没有;
  • 调试接口返回全库候选;
  • 历史会话保留撤权前资料;
  • 模型工具接受用户提交的租户 ID。

因此需要纵深防御,而不是一个过滤条件。

2. 可信身份与资源请求分离

python 复制代码
from dataclasses import dataclass


@dataclass(frozen=True)
class Identity:
    user_id: str
    tenant_id: str
    permission_version: str
    roles: frozenset[str]


@dataclass(frozen=True)
class KnowledgeRequest:
    question: str
    requested_document_ids: frozenset[str]

请求可以表达"想查哪些文档",但不能声明"我属于哪个租户"。

3. 交集而不是信任请求范围

python 复制代码
def effective_scope(
    request: KnowledgeRequest,
    authorized_document_ids: frozenset[str],
) -> frozenset[str]:
    if not request.question.strip():
        raise ValueError("问题不能为空")
    if request.requested_document_ids:
        return request.requested_document_ids & authorized_document_ids
    return authorized_document_ids

客户端请求未授权文档时,结果只能缩小,绝不能扩大。

4. 查询后再次验证结果

预过滤是主边界,结果复核是纵深防御:

python 复制代码
@dataclass(frozen=True)
class RetrievedChunk:
    chunk_id: str
    document_id: str
    tenant_id: str
    text: str


def enforce_result_scope(
    identity: Identity,
    chunks: list[RetrievedChunk],
    authorized_document_ids: frozenset[str],
) -> list[RetrievedChunk]:
    violations = [
        item.chunk_id for item in chunks
        if item.tenant_id != identity.tenant_id
        or item.document_id not in authorized_document_ids
    ]
    if violations:
        # 不能静默丢弃后继续回答,否则安全缺陷会被掩盖
        raise PermissionError(f"检索器返回越权结果:{violations}")
    return chunks

如果结果复核失败,应阻断请求并触发安全告警。

5. 权限感知缓存

python 复制代码
from hashlib import sha256


def answer_cache_key(
    identity: Identity,
    question: str,
    scope: frozenset[str],
    knowledge_version: str,
) -> str:
    raw = "|".join([
        identity.tenant_id,
        identity.user_id,
        identity.permission_version,
        knowledge_version,
        ",".join(sorted(scope)),
        question.strip(),
    ])
    return sha256(raw.encode("utf-8")).hexdigest()

用户撤权后 permission_version 改变,旧缓存不再命中。高敏内容可不缓存。

6. 原文下载使用短时授权

python 复制代码
from datetime import datetime, timezone


@dataclass(frozen=True)
class DownloadGrant:
    user_id: str
    document_id: str
    expires_at: datetime


def validate_download_grant(
    grant: DownloadGrant,
    identity: Identity,
    authorized_document_ids: frozenset[str],
    now: datetime,
) -> None:
    if grant.user_id != identity.user_id:
        raise PermissionError("下载授权不属于当前用户")
    if now >= grant.expires_at:
        raise PermissionError("下载授权已过期")
    if grant.document_id not in authorized_document_ids:
        raise PermissionError("当前已无文档访问权限")

生产授权还要有不可伪造签名或服务端状态,数据类本身不是完整令牌方案。

7. 可复验负向测试

python 复制代码
def test_requested_scope_can_only_shrink() -> None:
    request = KnowledgeRequest("查询制度", frozenset({"allowed", "secret"}))
    scope = effective_scope(request, frozenset({"allowed"}))
    assert scope == frozenset({"allowed"})


def test_cross_tenant_result_blocks_entire_answer() -> None:
    identity = Identity("u1", "tenant-a", "pv1", frozenset())
    chunks = [RetrievedChunk("c1", "d1", "tenant-b", "秘密")]
    try:
        enforce_result_scope(identity, chunks, frozenset({"d1"}))
    except PermissionError:
        pass
    else:
        raise AssertionError("越权结果必须阻断")

8. 对抗性审查清单

  • 每个入口都从可信会话读取身份;
  • 关键词、向量、图和原文接口使用同一权限策略;
  • 缓存、会话历史和导出同样隔离;
  • 调试工具有生产禁用和审计;
  • 权限变化使缓存、下载授权和会话失效;
  • 工具参数中的租户 ID 被服务端覆盖;
  • 持续测试水平越权、垂直越权和跨租户访问。

9. 总结

防越权的原则是:身份由服务端确定、检索前限制范围、检索后检测异常、缓存和原文再次鉴权。任何一层都不能把模型当权限裁判。

相关推荐
我是Superman丶1 小时前
Arduino IDE 安装教程:Windows/macOS/Linux 开发环境搭建
ide·windows·macos
辻弋2011 小时前
自动检测硬件生成驱动清单、实时监控FPS、120秒性能记录——30+项优化模块化开关,所有改动可精确复原
服务器·windows·游戏引擎·电脑·开源软件
江湖人称菠萝包2 小时前
【Windows】《深入浅出Windows API程序设计:编程基础篇》笔记-Chapter8-子窗口控件
windows·笔记
程序员梅雨2 小时前
Linux & Shell 实用干货
linux·运维·服务器·后端·面试·php
XR1234567882 小时前
医院无线整网高密覆盖选型深度解析
运维·网络
新时代牛马2 小时前
嵌入式 Linux 蓝牙框架完整篇:从 HCI、L2CAP 到BlueZ 用户态
linux·运维·服务器
发量惊人的中年网工2 小时前
企业一体化安全网关选型:适用规模、需求架构与实施建议
网络
取啥都被占用2 小时前
两个网络供应商靠树莓派跨个域
网络·树莓派
ONLYOFFICE3 小时前
ONLYOFFICE成为Linux操作系统 – Winux的预装办公套件
linux·运维·服务器
其实防守也摸鱼3 小时前
OpenClaw Windows 踩坑实战指南
运维·服务器·数据库·windows·github·copilot