大语言模型输出安全过滤与攻击防范

1. 防止意外执行

在使用大语言模型(LLM)应用时,除非该应用专门针对软件开发人员的用例(如 GitHub Copilot),否则需要警惕其生成可执行代码输出,因为这些代码可能会在某些环境中执行,成为攻击链的一部分。以下是一些缓解此类风险的方法:
1. HTML 编码 :在 Web 环境中使用 LLM 输出之前,对内容进行 HTML 编码,以中和可能导致跨站脚本(XSS)攻击的任何活动代码。
2. 安全上下文插入 :如果 LLM 输出是 SQL 查询的一部分,确保将其视为数据而非可执行代码。可以使用预准备语句或参数化查询来实现这一点,从而降低 SQL 注入风险。
3. 限制语法和关键字 :设置一个过滤层,从 LLM 的输出中移除或转义可能危险的特定编程语言语法或关键字。
4. 禁用 shell 可解释输出 :如果输出与 shell 命令交互,移除或转义在 shell 脚本中有特殊含义的字符,以减少 shell 注入攻击的可能性。
5. 分词处理 :对输出进行分词,并过滤掉不安全的标记。例如,过滤掉 <script> HTML 标签或像 DROP TABLE 这样的 SQL 命令。

2. 构建输出过滤器

为了确保 LLM 输出的安全性,可以使用 OpenAI API 和其他常用包来监控输出。以下是一些具体的操作步骤和示例代码:

2.1 使用正则表达式查找个人身份信息(PII)

某些类型的 PII 遵循常见的格式模式,因此正则表达式是验证的好起点。以下是一个检测字符串是否包含标准美国社会安全号码(SSN)的函数示例:

import re

def contains_ssn(input_string):
    # Define a regular expression pattern for a U.S. Social Security Number
    ssn_pattern = r'\b\d{3}-\d{2}-\d{4}\b'

    # Search for the pattern in the input string
    match = re.search(ssn_pattern, input_string)

    # Check if a match was found
    if match:
        print(f"Found a Social Security Number: {match.group(0)}")
        return True
    else:
        print("No Social Security Number found.")
        return False

# Test the function
contains_ssn("My Social Security Number is 123-45-6789.")
contains_ssn("No number here!")

需要注意的是,这只是简单的模式匹配,没有考虑无效号码(如 000 - 00 - 0000),如果需要,可以扩展此函数以包含额外的验证。对于更全面的 PII 检测,可以使用商业 API,如 Google Cloud Natural Language API 或 Amazon Comprehend,但这些 API 可能会产生相关费用。

2.2 评估毒性

检测毒性语言比查找标准字符串格式要复杂得多。可以使用 OpenAI API 中的 Moderation API 来评估字符串的可能毒性。以下是一个使用该 API 的示例代码:

import openai

def check_toxicity(text):
    """
    Checks the toxicity of a text using the OpenAI Moderation API.
    Args:
        text: The text to check for toxicity.
    Returns:
        A toxicity score between 0 and 1, where a higher score indicates a 
        higher probability of the text being toxic.
    """
    response = openai.Moderation.create(input=text)
    toxicity_score = response["results"][0]["confidence"]
    return toxicity_score

# Test the function
check_toxicity("You are stupid.")

2.3 将过滤器与 LLM 关联

以下是一个将上述过滤器集成到简单工作流程的示例代码:

import openai
import json
import re

# Initialize the OpenAI API client
openai.api_key = "your_openai_api_key_here"

def check_toxicity(text):
    response = openai.Moderation.create(input=text)
    toxicity_score = response["results"][0]["confidence"]
    return toxicity_score

def check_for_PII(text):
    ssn_pattern = r"\b\d{3}-\d{2}-\d{4}\b"
    return bool(re.search(ssn_pattern, text))

def get_LLM_response(prompt):
    model_engine = "text-davinci-002"  # You can use other engines
    response = openai.Completion.create(
        engine=model_engine,
        prompt=prompt,
        max_tokens=100  # Limiting to 100 tokens for this example
    )
    return response.choices[0].text.strip()

def log_results(prompt, llm_output, is_safe):
    with open("llm_safety_log.txt", "a") as log_file:
        log_file.write(f"Prompt: {prompt}\n")
        log_file.write(f"LLM Output: {llm_output}\n")
        log_file.write(f"Is Safe: {is_safe}\n")
        log_file.write("=" * 50 + "\n")

if __name__ == "__main__":
    prompt = "Tell me your thoughts on universal healthcare."
    llm_output = get_LLM_response(prompt)
    toxicity_level = check_toxicity(llm_output)
    contains_PII = check_for_PII(llm_output)
    is_safe = True
    if toxicity_level > 0.7 or contains_PII:
        print("Warning: The output is not safe to return to the user.")
        is_safe = False
    else:
        print("The output is safe to return to the user.")
    log_results(prompt, llm_output, is_safe)

2.4 安全清理

如果通过 Web 界面将输出返回给用户,需要对字符串进行清理,以避免 XSS 等问题。以下是一个简单的清理函数示例:

import html

def sanitize_output(text):
    return html.escape(text)

可以将清理步骤添加到上述工作流程中:

if toxicity_level > 0.7 or contains_PII:
    print("Warning: The output is not safe to return to the user.")
    is_safe = False
else:
    print("The output is safe to return to the user.")
    llm_output = sanitize_output(llm_output)

log_results(prompt, llm_output, is_safe)

2.5 工作流程流程图

graph TD;
    A[输入提示] --> B[获取 LLM 输出];
    B --> C[检查毒性];
    B --> D[检查 PII];
    C --> E{毒性是否大于 0.7};
    D --> F{是否包含 PII};
    E -- 是 --> G[标记为不安全并记录];
    F -- 是 --> G;
    E -- 否 --> H{是否包含 PII};
    F -- 否 --> I{毒性是否大于 0.7};
    H -- 否 --> J[清理输出];
    I -- 否 --> J;
    J --> K[标记为安全并记录];
    G --> L[结束];
    K --> L;

3. 拒绝服务(DoS)、拒绝钱包(DoW)和模型克隆攻击

3.1 攻击概述

DoS 攻击旨在使计算机系统、网络或应用程序对其预期用户不可用,通常是通过用大量请求淹没应用程序。随着先进计算和人工智能时代的到来,DoS 攻击的影响已经扩展到包括 LLMs 在内的更复杂技术。DoW 攻击是 DoS 的一种高度危险的变体,专门针对组织的经济资源,通过利用基于云的 AI 服务的按使用付费模式,导致服务提供商产生不可持续的成本。模型克隆攻击则是攻击者通过向系统发送大量问题、记录答案,然后使用这些答案来训练自己的模型,从而窃取模型的知识产权。

3.2 DoS 攻击类型

DoS 攻击主要分为以下三类:
| 攻击类型 | 描述 | 示例 |
| ---- | ---- | ---- |
| 基于流量的攻击 | 用大量流量淹没目标,消耗目标站点或应用程序的带宽,使合法流量无法访问。 | UDP 洪水、ICMP 洪水和其他伪造数据包洪水。 |
| 协议攻击 | 针对网络连接的网络层或传输层,利用运行互联网的协议中的弱点,通过发送相对少量的流量来创建不成比例的大负载,从而有效破坏目标的通信能力。 | SYN 洪水、死亡之 ping 和 Smurf 攻击。 |
| 应用层攻击 | 更复杂的攻击,针对应用层,攻击者请求服务器的大量资源,使服务器无法为合法用户请求提供服务。 | HTTP 洪水和 Slowloris 攻击。 |

3.3 史诗级 DoS 攻击:Dyn

2016 年 10 月,互联网因对 Dyn(一家领先的域名系统(DNS)提供商)的复杂大规模 DoS 攻击而面临重大中断。攻击者使用受 Mirai 恶意软件感染的物联网设备(如数码相机和 DVR)组成僵尸网络,向 Dyn 的服务器发送大量恶意流量,估计流量达到约 1.2 Tbps。这次攻击导致欧洲和北美各地的主要互联网平台和服务无法使用,包括 Twitter、Netflix、PayPal 和 Amazon 等知名网站。

3.4 针对 LLMs 的模型 DoS 攻击

与主要针对网络和服务器基础设施漏洞的传统 DoS 攻击不同,模型 DoS 攻击侧重于利用 LLMs 固有的独特漏洞。LLMs 由于其生成复杂文本响应的架构,资源密集,容易受到旨在过度负担其处理能力的攻击。例如,攻击者可以反复要求 LLM 翻译大文档或生成长篇内容,这种类型的请求如果通过自动化或机器人扩大规模,会迅速耗尽 LLM 可用的计算资源。

以下是一个针对 LLMs 的稀缺资源攻击的示例:

graph TD;
    A[攻击者] --> B[发送大量翻译请求];
    B --> C[LLM 翻译服务];
    C --> D[消耗计算资源];
    D --> E[LLM 性能下降];
    E --> F[服务不可用];

综上所述,为了确保 LLM 应用的安全性和可靠性,需要采取一系列措施来防止意外执行、构建输出过滤器,并防范 DoS、DoW 和模型克隆等攻击。通过合理运用上述技术和方法,可以在充分发挥 LLM 强大功能的同时,有效降低各种风险。

3.5 不同攻击类型的对比

为了更清晰地了解 DoS、DoW 和模型克隆攻击的特点,下面通过表格进行对比:
| 攻击类型 | 攻击目标 | 攻击方式 | 攻击后果 |
| ---- | ---- | ---- | ---- |
| DoS 攻击 | 计算机系统、网络或应用程序 | 用大量请求淹没应用,包括基于流量、协议和应用层攻击 | 服务不可用,导致经济损失、信任受损,可能掩盖其他恶意活动 |
| DoW 攻击 | 组织的经济资源 | 利用云 AI 服务按使用付费模式,产生大量查询或操作 | 服务提供商承担不可持续成本,造成财务压力 |
| 模型克隆攻击 | 模型的知识产权 | 向系统发送大量问题,记录答案用于训练自己的模型 | 模型知识产权被盗用 |

3.6 缓解 DoS 攻击的措施

针对不同类型的 DoS 攻击,可以采取以下缓解措施:
1. 基于流量的攻击
- 流量过滤 :使用防火墙或入侵检测系统(IDS)过滤掉异常流量,如 UDP 洪水、ICMP 洪水等。
- 速率限制 :限制每个 IP 地址或用户的请求速率,防止单个源发送过多流量。
- 内容分发网络(CDN) :利用 CDN 分散流量,减轻源服务器的负担。
2. 协议攻击
- 协议加固 :更新和修复网络协议中的漏洞,确保系统使用最新的安全协议。
- 会话管理 :对 TCP 会话进行严格管理,防止 SYN 洪水等攻击。
- 网络监控 :实时监控网络流量,及时发现和阻止异常的协议请求。
3. 应用层攻击
- 负载均衡 :使用负载均衡器将请求均匀分配到多个服务器上,避免单个服务器过载。
- 请求验证 :对用户请求进行验证,过滤掉恶意请求,如 HTTP 洪水中的异常请求。
- 限流策略 :为应用层设置合理的限流策略,防止过多资源被占用。

3.7 缓解 DoW 攻击的措施

  1. 成本监控 :实时监控云服务的使用成本,设置成本阈值,当达到阈值时及时发出警报。
  2. 使用限制 :对每个用户或账户的查询次数和操作量进行限制,防止过度使用。
  3. 合约管理 :与云服务提供商签订合理的合约,明确成本上限和使用规则。

3.8 缓解模型克隆攻击的措施

  1. 访问控制 :严格控制对模型的访问权限,只允许授权用户进行查询和交互。
  2. 水印技术 :在模型输出中添加水印,以便追踪和识别非法使用。
  3. 数据加密 :对模型的输入和输出数据进行加密,防止数据泄露和滥用。

4. 总结与建议

4.1 总结

在使用大语言模型(LLM)时,需要全面考虑各种安全风险,包括意外执行、DoS、DoW 和模型克隆攻击等。通过构建输出过滤器,可以有效防止输出中的危险代码、毒性语言和个人身份信息泄露。对于 DoS、DoW 和模型克隆攻击,了解其攻击类型和特点,并采取相应的缓解措施,可以降低攻击带来的损失。

4.2 建议

  1. 持续监控 :建立实时监控系统,对 LLM 的输入输出、资源使用和成本进行持续监控,及时发现和处理异常情况。
  2. 安全更新 :定期更新 LLM 应用和相关软件,修复已知的安全漏洞,提高系统的安全性。
  3. 员工培训 :对使用 LLM 的员工进行安全培训,提高他们的安全意识和防范能力。
  4. 应急响应 :制定完善的应急响应计划,当发生安全事件时,能够迅速采取措施,减少损失。

4.3 安全措施流程图

graph TD;
    A[LLM 应用] --> B[输出过滤];
    B --> C[检查毒性和 PII];
    C --> D{是否安全};
    D -- 是 --> E[正常使用];
    D -- 否 --> F[标记不安全并处理];
    A --> G[DoS 防护];
    G --> H[流量过滤和速率限制];
    G --> I[协议加固和会话管理];
    G --> J[负载均衡和请求验证];
    A --> K[DoW 防护];
    K --> L[成本监控和使用限制];
    K --> M[合约管理];
    A --> N[模型克隆防护];
    N --> O[访问控制和水印技术];
    N --> P[数据加密];
    E --> Q[持续监控];
    Q --> R{是否异常};
    R -- 是 --> S[应急响应];
    R -- 否 --> E;
    F --> S;

通过以上措施,可以构建一个全面的安全防护体系,确保 LLM 应用的安全可靠运行。在享受 LLM 带来的强大功能的同时,也要时刻保持警惕,防范各种安全风险。

更多推荐