T1.1: SanitizeFilter 请求规整化(解码检查 ..///控制字符裸 400,只拒不修;attribute 契约 sanitized.uri/stripped.path)

This commit is contained in:
chenxing
2026-09-21 00:34:11 +08:00
parent a45a180008
commit 949296eb67
2 changed files with 165 additions and 0 deletions
@@ -0,0 +1,61 @@
package com.yunhai.platform.gateway.filter;
import com.yunhai.platform.gateway.envelope.EnvelopeWriter;
import org.junit.jupiter.api.Test;
import org.springframework.mock.web.MockFilterChain;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import static org.assertj.core.api.Assertions.assertThat;
/**
* SanitizeFilter 五用例(T1.1 TDD):路径穿越(明文/编码)、双斜杠、控制字符均裸 400;
* 正常路径放行且两个 attribute 契约已设。
*/
class SanitizeFilterTest {
private MockHttpServletResponse run(String uri) throws Exception {
MockHttpServletRequest req = new MockHttpServletRequest("GET", uri);
MockHttpServletResponse res = new MockHttpServletResponse();
MockFilterChain chain = new MockFilterChain();
new SanitizeFilter().doFilter(req, res, chain);
return res;
}
@Test
void 路径穿越_裸400() throws Exception {
assertThat(run("/userbase/oapi/a/../b").getStatus()).isEqualTo(400);
}
@Test
void 编码形态路径穿越_裸400() throws Exception {
assertThat(run("/userbase/oapi/%2e%2e/b").getStatus()).isEqualTo(400);
assertThat(run("/userbase/oapi/%2E%2E%2Fetc").getStatus()).isEqualTo(400);
}
@Test
void 路径双斜杠_裸400() throws Exception {
assertThat(run("/userbase//oapi/x").getStatus()).isEqualTo(400);
assertThat(run("/userbase/oapi//list").getStatus()).isEqualTo(400);
}
@Test
void 控制字符与空字节_裸400() throws Exception {
assertThat(run("/userbase/oapi/a\u0000b").getStatus()).isEqualTo(400);
assertThat(run("/userbase/oapi/a\u001fb").getStatus()).isEqualTo(400);
}
@Test
void 正常路径放行且attribute已设() throws Exception {
MockHttpServletRequest req = new MockHttpServletRequest("GET", "/userbase/oapi/x");
MockHttpServletResponse res = new MockHttpServletResponse();
MockFilterChain chain = new MockFilterChain();
new SanitizeFilter().doFilter(req, res, chain);
assertThat(res.getStatus()).as("正常路径放行").isEqualTo(200);
assertThat(chain.getRequest()).as("链条继续").isNotNull();
assertThat(req.getAttribute(SanitizeFilter.ATTR_SANITIZED_URI))
.as("sanitized.uri = 原始 URI(逐字节不改写)").isEqualTo("/userbase/oapi/x");
assertThat(req.getAttribute(SanitizeFilter.ATTR_STRIPPED_PATH))
.as("stripped.path = 剥 target 首段").isEqualTo("/oapi/x");
}
}