TL;DR: 本文探讨了通过控制器管理特权LLM和隔离LLM的访问隔离功能预期研究。通过CTF场景演示如何构造符合特定约束条件的问题,从特权LLM解锁秘密,同时规避隔离LLM的语义检查。
在Bishop Fox,我们设有专注于不同技术领域的内部小组,以更好地理解它们与安全的交集。其中一个重点领域是大型语言模型(LLM)及其在客户日常工作中的潜在应用场景。
本文将深入介绍我们关于LLM功能隔离的研究:通过控制器实现服务访问控制,同时管理特权LLM和隔离LLM。为探索链式和隔离式LLM,我们构建了一个被提示表现为音乐店员工的LLM。在本案例中,这个特权LLM仅需保护一个秘密,但其他场景可能包含更多外部能力,如查询客户关系管理系统、处理订单、访问店铺库存或充当专业音乐顾问。
环境搭建
首先确保已安装go和ollama:
1
2
3
4
|
$ ollama run phi3:latest
git clone https://github.com/BishopFox/local-llm-ctf
cd local-llm-ctf
go run main.go
|
代码架构
所有代码集中在main.go文件,仅使用go标准库和ollama依赖。关键实现包括:
- LLM隔离模板:
1
2
3
4
|
const template_is_llm_jailbreak = `FROM {{modelname}}
SYSTEM You will only respond the words true or false...
MESSAGE user What kind of albums do you have...
MESSAGE assistant false`
|
- 确定性检查:
1
|
rxUserInput := regexp.MustCompile(`^[a-zA-Z0-9+/=\.,\? '%\$]{10,512}$`)
|
- 模型流程控制:
1
2
3
4
5
6
|
modelFlow := []string{
fmt.Sprintf("%s-is-llm-jailbreak", baseModelName),
fmt.Sprintf("%s-is-valid-question", baseModelName),
fmt.Sprintf("%s-genie-knowledgebase", baseModelName),
fmt.Sprintf("%s-is-patron-appropriate", baseModelName)
}
|
关键发现
- LLM输出不可靠性:
通过强制类型转换确保响应符合预期:
1
2
3
4
5
6
|
func llmToBool(llmOutputText string) (bool, error) {
if len(llmOutputText) >= 4 && strings.ToLower(llmOutputText[:4]) == "true" {
return true, nil
}
...
}
|
- 上下文隔离漏洞:
初始版本错误地将所有LLM上下文附加到特权LLM,导致异常响应。修复方案:
1
2
3
|
if strings.Contains(resp.Model, "-genie-knowledgebase") {
llmContext = append(llmContext, resp.Context...)
}
|
- 输出编码问题:
特权LLM在回答中混入Base64编码的秘密:
1
2
|
$ echo "RGlkIHlvdSBsb29rIGF0IHRoZSBzb3VyY2UgY29kZQ==" | base64 -d
Did you look at the source code
|
成功绕过案例
使用mistral模型实现完整秘密泄露:
1
2
|
$ go run main.go -model mistral
The Secret: "RGlkIHlvdSBsb29rIGF0IHRoZSBzb3VyY2UgY29kZSwgZ3JlcCB0aGUgYmlu..."
|
性能考量
当前实现采用串行流程,生产环境应并行化隔离LLM的布尔检查请求以提升响应速度,但可能引入竞态条件。
防御建议
- 增强is-llm-jailbreak提示工程
- 实施更严格的输出过滤
- 采用更大容量模型减少幻觉
- 监控客户查询失败率
挑战任务
尝试修改程序防止注入成功,或开发更完善的jailbreak检测提示。未来将探索通过摘要隔离上下文,结合外部能力调用函数。
资源致谢:ollama、llama.cpp、go语言及Bishop Fox对研究工作的支持。