Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add replay protection plugin #1672

Open
wants to merge 19 commits into
base: main
Choose a base branch
from

Conversation

yunmaoQu
Copy link
Contributor

Ⅰ. Describe what this PR did

This plugin prevents replay attacks by validating request nonce. Key features:

  • Nonce validation
  • Redis-based replay detection
  • Configurable TTL and validation rules"

Ⅱ. Does this pull request fix one issue?

close #1609

Ⅲ. Why don't you add test cases (unit test/integration test)?

Ⅳ. Describe how to verify it

Ⅴ. Special notes for reviews

This plugin prevents replay attacks by validating request nonce.
Key features:
- Nonce validation
- Redis-based replay detection
- Configurable TTL and validation rules"
@codecov-commenter
Copy link

codecov-commenter commented Jan 14, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 43.61%. Comparing base (ef31e09) to head (ed33204).
Report is 283 commits behind head on main.

Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main    #1672      +/-   ##
==========================================
+ Coverage   35.91%   43.61%   +7.70%     
==========================================
  Files          69       76       +7     
  Lines       11576    12358     +782     
==========================================
+ Hits         4157     5390    +1233     
+ Misses       7104     6630     -474     
- Partials      315      338      +23     

see 70 files with indirect coverage changes

@yunmaoQu
Copy link
Contributor Author

@hanxiantao 哪里还需要改吗

@hanxiantao hanxiantao self-requested a review January 17, 2025 03:59
@hanxiantao
Copy link
Collaborator

hanxiantao commented Jan 17, 2025

@hanxiantao 哪里还需要改吗

我这边没什么了,e2e的报错你看下,或者后面再加也可以

@yunmaoQu
Copy link
Contributor Author

yunmaoQu commented Jan 17, 2025

@johnlanni @CH3CHO 方便review下吗

@johnlanni
Copy link
Collaborator

@yunmaoQu e2e测试没过,麻烦先修一下

| 配置项 | 类型 | 必填 | 默认值 | 说明 |
|-------------------|--------|------|-----------------|---------------------------------|
| `force_nonce` | bool | 否 | `true` | 是否强制要求请求携带 nonce 值。 |
| `nonce_header` | string | 否 | `X-Mse-Nonce` | 指定携带 nonce 值的请求头名称。 |
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mse 建议可以改名为 higress

func onHttpRequestHeaders(ctx wrapper.HttpContext, config ReplayProtectionConfig, log wrapper.Log) types.Action {
nonce, _ := proxywasm.GetHttpRequestHeader(config.NonceHeader)
if config.ForceNonce && nonce == "" {
// 强制模式下,缺失 nonce 拒绝请求
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

注释统一改成英文吧

reject_code: 429 # 拒绝请求时返回的状态码
reject_msg: "Duplicate nonce" # 拒绝请求时返回的错误信息
redis:
serviceName: "redis.higress" # Redis 服务名称
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这个serviceName的例子给的不对 ,用 redis.dns 吧,下面README_EN也相应调整下

servicePort: 6379
timeout: 1000
keyPrefix: "replay-protection"
url: oci://higress-registry.cn-hangzhou.cr.aliyuncs.com/plugins/replay-protection:1.0.0
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

目前只有已经release的插件可以用这种方式引用,开发中的需要创建一个 VERSION 目录,指定版本为 1.0.0-alpha:
https://github.com/alibaba/higress/blob/main/plugins/wasm-go/extensions/ai-agent/VERSION

同时这里修改为:

url: file:///opt/plugins/wasm-go/extensions/reply-protection/plugin.wasm

@yunmaoQu
Copy link
Contributor Author

改好了

@johnlanni
Copy link
Collaborator

image
e2e 没过,看上去yaml格式有问题

Path: "/get", // Or your test path
UnfollowRedirect: true,
},
ExpectedRequest: &http.ExpectedRequest{
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ExpectedRequest和带body的ExpectedResponse只能选一个,这里应该只比ExpectedResponse就可以了,ExpectedResponse这里需要指定ContentType: http.ContentTypeApplicationJson,可以参考下这个,我今天改了下跑通了

{
				Meta: http.AssertionMeta{
					TestCaseName:  "minimax case 1: proxy completion V2 API, non-streaming request",
					CompareTarget: http.CompareTargetResponse,
				},
				Request: http.AssertionRequest{
					ActualRequest: http.Request{
						Host:        "api.minimax.chat-v2-api",
						Path:        "/v1/chat/completions",
						Method:      "POST",
						ContentType: http.ContentTypeApplicationJson,
						Body:        []byte(`{"model":"gpt-3","messages":[{"role":"user","content":"你好,你是谁?"}],"stream":false}`),
					},
				},
				Response: http.AssertionResponse{
					ExpectedResponse: http.Response{
						StatusCode:  200,
						ContentType: http.ContentTypeApplicationJson,
						Body:        []byte(`{"id":"chatcmpl-llm-mock","choices":[{"index":0,"message":{"role":"assistant","content":"你好,你是谁?"},"finish_reason":"stop"}],"created":10,"model":"abab6.5s-chat","object":"chat.completion","usage":{"prompt_tokens":9,"completion_tokens":1,"total_tokens":10}}`),
					},
				},
			}

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

本地也可以注释掉其他的单独跑下这个试下,看下这个文章
教程:如何在本地进行higress调试和端到端测试

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

好的,谢谢

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Provide Request Replay Protection WASM Plugin
4 participants