我有一个小型的Rust程序,用于格式化MySQL查询,但发现较大的查询失败,返回
未编码的有效载荷大小大于允许的大小(默认值:256kB)
我正在使用actix网站,它看起来像这样
use actix_web::{
web, App, HttpResponse, HttpServer, Result,
};
#[derive(Deserialize)]
pub struct MyParams {
q: String,
}
fn index(params: web::Form<MyParams>) -> Result<HttpResponse> {
Ok(HttpResponse::Ok()
.content_type("text/html; charset=utf-8")
.body("test"))
// .body(mysql_format2(¶ms.q[..])))
}
fn main() -> std::io::Result<()> {
HttpServer::new(|| {
App::new().service(
web::resource("/")
.route(web::post().to(index))
)
})
.bind("127.0.0.1:48627")?
.run()
}
调用此脚本的PHP脚本如下
$this->FormattedMySQL = str_repeat("make a big query ", 1024*256);
$query = http_build_query([
'q' => $this->FormattedMySQL,
]);
// if I change this to 16385 (+1)
// then it breaks and returns that error
$query = substr($query, 0, 16384);
if ($this->FormatMySQL && strlen($query) <= 262144) {
try {
$this->VerbosePrint('formatting');
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, MYSQL_FORMAT_ENDPOINT);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $query);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 5);
$this->FormattedMySQL = curl_exec($ch);
curl_close($ch);
} catch (Exception $_) { }
}
我缺少什么,或者为什么这似乎为16kB而不是256kB引发此错误?
我看到也可以set the Payload
config,但是我不确定在现有代码中如何/在何处应用它。
答案 0 :(得分:2)
快速的答案是,还有第二个配置(FormConfig
),这就是您要面对的问题。尚不清楚,因为它返回与PayloadConfig
相同的错误类型(这是有原因的,我将在“较长版本”中解释)
将您的actix服务器定义更改为此,例如,将其更改为256kb:
HttpServer::new(|| {
App::new().service(
web::resource("/")
.route(web::post()
.to(index)
)
.data(web::Form::<MyParams>::configure(|cfg| cfg.limit(256 * 1024)))
)
})
.bind("127.0.0.1:48627")?
.run()
您还需要导入actix_web::FromRequest
,因为这是对象类型从请求更改为文本编码的地方,并且configure()
方法也存在。
现在,进行解释!
Actix与其他框架一样,具有多层限制。您已经找到其中一个,这是另一个。
您找到的那个可以防止由于内存耗尽而导致拒绝服务(即有人向服务器oom发送了故意大的有效负载,因为它必须将主体存储在某个地方进行处理)。它控制请求的整个有效负载。
您要面对的一个限制是对每个字段的限制要小得多,它的存在是为了防止其他类型的疲劳攻击。假设您的攻击者知道您正在解析输入内容;我们假设它是JSON。通过发送任意大而复杂的JSON,它们可以在处理单个请求时有效地锁定服务器。小数据输入,非常大后果。
因此,两个限制通常彼此独立,并允许您根据需要微调限制。很多小领域?没问题。一大块?也不是问题。
FormConfig
限制的作用位于here,以防您想查看代码本身。由于类型返回与PayloadConfig
限制的类型返回((此结构的Overflow
变体)[https://docs.rs/actix-web/1.0.7/actix_web/error/enum.UrlencodedError.html])相同,因此消息内容不清楚,最终您被抓到了结果。
我认为该错误为“相似”的主要目的是防止服务器向潜在的攻击者指示其命中的限制,以及it seems to be what they had in mind。面向用户的错误描述是问题所在,而位置适当的PR可能会对此进行调整。