You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot/Webflux应用日志异常HTTP请求排查求助

异常HTTP请求排查:来源与成因分析

我开发了一个基于Spring Boot v2.7.4、spring-boot-starter-webflux和Spring Batch v4.3.7的应用,通过定时方法运行作业,整体运行正常,但日志中偶尔出现异常HTTP请求,具体日志如下:

异常请求日志示例

WARN 1 --- [or-http-epoll-2] r.n.http.server.HttpServerOperations     : [4fc791dd, L:/10.126.39.132:8080 - R:/10.41.50.212:48879] Decoding failed: DefaultHttpRequest(decodeResult: failure(java.lang.IllegalArgumentException: Content-Length value is not a number: -1), version: HTTP/1.1)
POST /.jsp HTTP/1.1
Host: 10.126.39.132:8080
Content-Length: -1 : 
WARN 1 --- [or-http-epoll-2] r.n.http.server.HttpServerOperations     : [27848f5f, L:/10.126.39.132:8080 - R:/10.41.50.212:59493] Decoding failed: DefaultHttpRequest(decodeResult: success, version: HTTP/1.1)
GET %org/jboss/version.properties HTTP/1.1
Host: 10.126.39.132:8080 : 
WARN 1 --- [or-http-epoll-1] r.n.http.server.HttpServerOperations     : [ebe6653c, L:/10.126.39.132:8080 - R:/10.41.50.212:56851] Decoding failed: DefaultHttpRequest(decodeResult: success, version: HTTP/1.1)
GET %login-config.xml HTTP/1.1
Host: 10.126.39.132:8080 : 

这些请求会抛出如下异常:

java.net.URISyntaxException: Malformed escape pair at index 7: http://%org/jboss/version.properties
    at java.base/java.net.URI$Parser.fail(URI.java:2974) ~[na:na]
    at java.base/java.net.URI$Parser.scanEscape(URI.java:3102) ~[na:na]
    at java.base/java.net.URI$Parser.scan(URI.java:3125) ~[na:na]
    at java.base/java.net.URI$Parser.parseAuthority(URI.java:3264) ~[na:na]
    at java.base/java.net.URI$Parser.parseHierarchical(URI.java:3219) ~[na:na]
    at java.base/java.net.URI$Parser.parse(URI.java:3175) ~[na:na]
    at java.base/java.net.URI.<init>(URI.java:623) ~[na:na]
    at java.base/java.net.URI.create(URI.java:904) ~[na:na]
    at reactor.netty.http.HttpOperations.resolvePath(HttpOperations.java:389) ~[reactor-netty-http-1.0.23.jar:1.0.23]
    at reactor.netty.http.server.HttpServerOperations.<init>(HttpServerOperations.java:173) ~[reactor-netty-http-1.0.23.jar:1.0.23]
    at reactor.netty.http.server.HttpServerOperations.<init>(HttpServerOperations.java:148) ~[reactor-netty-http-1.0.23.jar:1.0.23]
    at reactor.netty.http.server.HttpTrafficHandler.channelRead(HttpTrafficHandler.java:205) ~[reactor-netty-http-1.0.23.jar:1.0.23]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) ~[netty-transport-4.1.82.Final.jar:4.1.82.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) ~[netty-transport-4.1.82.Final.jar:4.1.82.Final]
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357) ~[netty-transport-4.1.82.Final.jar:4.1.82.Final]
    at io.netty.channel.CombinedChannelDuplexHandler$DelegatingChannelHandlerContext.fireChannelRead(CombinedChannelDuplexHandler.java:436) ~[netty-transport-4.1.82.Final.jar:4.1.82.Final]
    at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:336) ~[netty-codec-4.1.82.Final.jar:4.1.82.Final]
    at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:308) ~[netty-codec-4.1.82.Final.jar:4.1.82.Final]
    at io.netty.channel.CombinedChannelDuplexHandler.channelRead(CombinedChannelDuplexHandler.java:251) ~[netty-transport-4.1.82.Final.jar:4.1.82.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) ~[netty-transport-4.1.82.Final.jar:4.1.82.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) ~[netty-transport-4.1.82.Final.jar:4.1.82.Final]
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357) ~[netty-transport-4.1.82.Final.jar:4.1.82.Final]
    at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410) ~[netty-transport-4.1.82.Final.jar:4.1.82.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) ~[netty-transport-4.1.82.Final.jar:4.1.82.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) ~[netty-transport-4.1.82.Final.jar:4.1.82.Final]
    at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919) ~[netty-transport-4.1.82.Final.jar:4.1.82.Final]
    at io.netty.channel.epoll.AbstractEpollStreamChannel$EpollStreamUnsafe.epollInReady(AbstractEpollStreamChannel.java:800) ~[netty-transport-classes-epoll-4.1.82.Final.jar:4.1.82.Final]
    at io.netty.channel.epoll.EpollEventLoop.processReady(EpollEventLoop.java:499) ~[netty-transport-classes-epoll-4.1.82.Final.jar:4.1.82.Final]
    at io.netty.channel.epoll.EpollEventLoop.run(EpollEventLoop.java:397) ~[netty-transport-classes-epoll-4.1.82.Final.jar:4.1.82.Final]
    at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:997) ~[netty-common-4.1.82.Final.jar:4.1.82.Final]
    at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) ~[netty-common-4.1.82.Final.jar:4.1.82.Final]
    at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) ~[netty-common-4.1.82.Final.jar:4.1.82.Final]
    at java.base/java.lang.Thread.run(Thread.java:833) ~[na:na]

一、请求来源判断

  • 从日志中的R:/10.41.50.212:端口字段可直接定位请求发起IP为10.41.50.212:
    • 若该IP属于内部网络,排查是否为内部服务的异常请求:比如配置错误的监控脚本、爬虫程序,或者服务间调用的代码bug
    • 若该IP为外部网络地址,基本可判定为恶意扫描或攻击请求,这类请求通常由自动化工具发起,用于探测系统潜在漏洞

二、成因分析

  1. Content-Length非法请求:
    HTTP协议明确要求Content-Length必须是非负整数,请求中Content-Length: -1属于违反协议规范的畸形请求。这类请求一般是攻击者构造的,用来测试服务器的容错能力,尝试触发解析层面的漏洞。
  2. URI格式错误请求:
    URI中的%是转义字符,必须后跟两位十六进制数(如%20代表空格),但请求中的%org不符合该规则,导致解析时抛出URISyntaxException。这类请求是典型的漏洞探测行为,攻击者试图通过构造特殊路径,获取服务器上的敏感配置文件(JBoss的version.properties、login-config.xml是常见的探测目标)。

三、后续处理建议

  • 拦截畸形请求:通过Nginx等反向代理添加规则,拦截包含非法路径(如%org、%login-config.xml)或Content-Length为负数的请求
  • 优化WebFlux异常处理:在Spring WebFlux中添加全局异常处理器,捕获URISyntaxException等请求解析异常,避免日志刷屏,同时返回400 Bad Request等合规状态码
  • 封禁恶意IP:若确认是外部恶意IP,可在防火墙或反向代理层面封禁该IP,减少后续攻击尝试

内容的提问来源于stack exchange,提问作者Paul

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 07:21:11