mirror of
https://github.com/qaiu/netdisk-fast-download.git
synced 2025-12-17 04:43:02 +00:00
js演练场漏洞修复
This commit is contained in:
189
parser/doc/security/NASHORN_LIMITATIONS.md
Normal file
189
parser/doc/security/NASHORN_LIMITATIONS.md
Normal file
@@ -0,0 +1,189 @@
|
||||
# ⚠️ Nashorn引擎限制说明
|
||||
|
||||
## 问题描述
|
||||
|
||||
Nashorn JavaScript引擎(Java 8-14自带)**无法中断正在执行的JavaScript代码**。
|
||||
|
||||
这是Nashorn引擎的一个已知限制,无法通过编程方式解决。
|
||||
|
||||
## 具体表现
|
||||
|
||||
### 症状
|
||||
当JavaScript代码包含无限循环时:
|
||||
```javascript
|
||||
while(true) {
|
||||
var x = 1 + 1;
|
||||
}
|
||||
```
|
||||
|
||||
会出现以下情况:
|
||||
1. ✅ 30秒后客户端收到超时错误
|
||||
2. ❌ Worker线程继续执行无限循环
|
||||
3. ❌ 线程被永久阻塞,无法释放
|
||||
4. ❌ 日志持续输出线程阻塞警告
|
||||
|
||||
### 日志示例
|
||||
```
|
||||
WARN -> [-thread-checker] i.vertx.core.impl.BlockedThreadChecker:
|
||||
Thread Thread[playground-executor-1,5,main] has been blocked for 60249 ms, time limit is 60000 ms
|
||||
```
|
||||
|
||||
## 为什么无法中断?
|
||||
|
||||
### 尝试过的方案
|
||||
1. ❌ `Thread.interrupt()` - Nashorn不响应中断信号
|
||||
2. ❌ `Future.cancel(true)` - 无法强制停止Nashorn
|
||||
3. ❌ `ExecutorService.shutdownNow()` - 只能停止整个线程池
|
||||
4. ❌ `ScriptContext.setErrorWriter()` - 无法注入中断逻辑
|
||||
5. ❌ 自定义ClassFilter - 无法过滤语言关键字
|
||||
|
||||
### 根本原因
|
||||
- Nashorn使用JVM字节码执行JavaScript
|
||||
- 无限循环被编译成JVM字节码级别的跳转
|
||||
- 没有安全点(Safepoint)可以插入中断检查
|
||||
- `while(true)` 不会调用任何Java方法,完全在JVM栈内执行
|
||||
|
||||
## 现有防护措施
|
||||
|
||||
### 1. ✅ 客户端超时(已实现)
|
||||
```java
|
||||
executionFuture.toCompletionStage()
|
||||
.toCompletableFuture()
|
||||
.orTimeout(30, TimeUnit.SECONDS)
|
||||
```
|
||||
- 30秒后返回错误给用户
|
||||
- 用户知道脚本超时
|
||||
- 但线程仍被阻塞
|
||||
|
||||
### 2. ✅ 前端危险代码检测(已实现)
|
||||
```javascript
|
||||
// 检测无限循环模式
|
||||
/while\s*\(\s*true\s*\)/gi
|
||||
/for\s*\(\s*;\s*;\s*\)/gi
|
||||
```
|
||||
- 执行前警告用户
|
||||
- 需要用户确认
|
||||
- 依赖用户自觉
|
||||
|
||||
### 3. ✅ Worker线程池隔离
|
||||
- 使用独立的 `playground-executor` 线程池
|
||||
- 最多16个线程
|
||||
- 不影响主服务的事件循环
|
||||
|
||||
### 4. ✅ 代码长度限制
|
||||
- 最大128KB代码
|
||||
- 减少内存消耗
|
||||
- 但无法防止无限循环
|
||||
|
||||
## 影响范围
|
||||
|
||||
### 最坏情况
|
||||
- 16个恶意请求可以耗尽所有Worker线程
|
||||
- 后续所有Playground请求会等待
|
||||
- 主服务不受影响(独立线程池)
|
||||
- 需要重启服务才能恢复
|
||||
|
||||
### 实际影响
|
||||
- 取决于使用场景
|
||||
- 如果是公开服务,有被滥用风险
|
||||
- 如果是内部工具,风险较低
|
||||
|
||||
## 解决方案
|
||||
|
||||
### 短期方案(已实施)
|
||||
1. ✅ 前端检测和警告
|
||||
2. ✅ 超时返回错误
|
||||
3. ✅ 文档说明限制
|
||||
4. ⚠️ 监控线程阻塞告警
|
||||
5. ⚠️ 限流(已有RateLimiter)
|
||||
|
||||
### 中期方案(建议)
|
||||
1. 添加IP黑名单机制
|
||||
2. 添加滥用检测(同一IP多次触发超时)
|
||||
3. 考虑添加验证码
|
||||
4. 定期重启被阻塞的线程池
|
||||
|
||||
### 长期方案(需大量工作)
|
||||
1. **迁移到GraalVM JavaScript引擎**
|
||||
- 支持CPU时间限制
|
||||
- 可以强制中断
|
||||
- 更好的性能
|
||||
- 但需要额外依赖
|
||||
|
||||
2. **使用独立进程执行**
|
||||
- 完全隔离
|
||||
- 可以强制杀死进程
|
||||
- 但复杂度高
|
||||
|
||||
3. **代码静态分析**
|
||||
- 分析AST检测循环
|
||||
- 注入超时检查代码
|
||||
- 但可能被绕过
|
||||
|
||||
## 运维建议
|
||||
|
||||
### 监控指标
|
||||
```bash
|
||||
# 监控线程阻塞告警
|
||||
tail -f logs/*/run.log | grep "Thread blocked"
|
||||
|
||||
# 监控超时频率
|
||||
tail -f logs/*/run.log | grep "JavaScript执行超时"
|
||||
```
|
||||
|
||||
### 告警阈值
|
||||
- 单个IP 1小时内超时 >3次 → 警告
|
||||
- Worker线程阻塞 >80% → 严重
|
||||
- 持续阻塞 >5分钟 → 考虑重启
|
||||
|
||||
### 应急方案
|
||||
```bash
|
||||
# 重启服务释放被阻塞的线程
|
||||
./bin/stop.sh
|
||||
./bin/run.sh
|
||||
```
|
||||
|
||||
## 用户建议
|
||||
|
||||
### ✅ 建议的代码模式
|
||||
```javascript
|
||||
// 使用有限循环
|
||||
for(var i = 0; i < 1000; i++) {
|
||||
// 处理逻辑
|
||||
}
|
||||
|
||||
// 使用超时保护
|
||||
var maxIterations = 10000;
|
||||
var count = 0;
|
||||
while(condition && count++ < maxIterations) {
|
||||
// 处理逻辑
|
||||
}
|
||||
```
|
||||
|
||||
### ❌ 禁止的代码模式
|
||||
```javascript
|
||||
// 无限循环
|
||||
while(true) { }
|
||||
for(;;) { }
|
||||
|
||||
// 无退出条件的循环
|
||||
while(someCondition) {
|
||||
// someCondition永远为true
|
||||
}
|
||||
|
||||
// 递归炸弹
|
||||
function boom() { return boom(); }
|
||||
```
|
||||
|
||||
## 相关链接
|
||||
|
||||
- [Nashorn Engine Issues](https://github.com/openjdk/nashorn/issues)
|
||||
- [GraalVM JavaScript](https://www.graalvm.org/javascript/)
|
||||
- [Java Script Engine Comparison](https://benchmarksgame-team.pages.debian.net/benchmarksgame/)
|
||||
|
||||
---
|
||||
|
||||
**最后更新**: 2025-11-29
|
||||
**状态**: ⚠️ 已知限制,已采取缓解措施
|
||||
**建议**: 如需更严格的控制,考虑迁移到GraalVM JavaScript引擎
|
||||
|
||||
Reference in New Issue
Block a user