Skip to content

Commit edc5bed

Browse files
committed
Revert "feat: add timeout validation to prevent DoS attacks"
This reverts commit 8296242.
1 parent 5be0f43 commit edc5bed

File tree

3 files changed

+0
-98
lines changed

3 files changed

+0
-98
lines changed

crates/rmcp/src/service.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,6 @@ pub enum ServiceError {
4646
Cancelled { reason: Option<String> },
4747
#[error("request timeout after {}", chrono::Duration::from_std(*timeout).unwrap_or_default())]
4848
Timeout { timeout: Duration },
49-
#[error("invalid timeout value: {timeout:?} - {reason}")]
50-
InvalidTimeout { timeout: Duration, reason: String },
5149
}
5250

5351
trait TransferObject:

crates/rmcp/src/service/server.rs

Lines changed: 0 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -3,34 +3,6 @@ use std::borrow::Cow;
33
use thiserror::Error;
44

55
use super::*;
6-
7-
/// Validates timeout values to prevent DoS attacks and ensure reasonable limits
8-
fn validate_timeout(timeout: Option<std::time::Duration>) -> Result<(), ServiceError> {
9-
if let Some(duration) = timeout {
10-
const MAX_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(300); // 5 minutes max
11-
const MIN_TIMEOUT: std::time::Duration = std::time::Duration::from_millis(1); // 1ms min
12-
13-
if duration > MAX_TIMEOUT {
14-
return Err(ServiceError::InvalidTimeout {
15-
timeout: duration,
16-
reason: "Timeout exceeds maximum allowed duration (300 seconds)".to_string(),
17-
});
18-
}
19-
if duration < MIN_TIMEOUT {
20-
return Err(ServiceError::InvalidTimeout {
21-
timeout: duration,
22-
reason: "Timeout must be at least 1 millisecond".to_string(),
23-
});
24-
}
25-
if duration.is_zero() {
26-
return Err(ServiceError::InvalidTimeout {
27-
timeout: duration,
28-
reason: "Timeout cannot be zero".to_string(),
29-
});
30-
}
31-
}
32-
Ok(())
33-
}
346
#[cfg(feature = "elicitation")]
357
use crate::model::{
368
CreateElicitationRequest, CreateElicitationRequestParam, CreateElicitationResult,
@@ -363,9 +335,6 @@ macro_rules! method {
363335
&self,
364336
timeout: Option<std::time::Duration>,
365337
) -> Result<$Resp, ServiceError> {
366-
// Validate timeout to prevent DoS attacks
367-
validate_timeout(timeout)?;
368-
369338
let request = ServerRequest::$Req($Req {
370339
method: Default::default(),
371340
extensions: Default::default(),
@@ -392,9 +361,6 @@ macro_rules! method {
392361
params: $Param,
393362
timeout: Option<std::time::Duration>,
394363
) -> Result<$Resp, ServiceError> {
395-
// Validate timeout to prevent DoS attacks
396-
validate_timeout(timeout)?;
397-
398364
let request = ServerRequest::$Req($Req {
399365
method: Default::default(),
400366
params,

crates/rmcp/tests/test_elicitation.rs

Lines changed: 0 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1346,68 +1346,6 @@ async fn test_realistic_timeout_scenarios() {
13461346
assert!(long_timeout <= Duration::from_secs(300));
13471347
}
13481348

1349-
/// Test timeout validation to prevent DoS attacks
1350-
#[tokio::test]
1351-
async fn test_timeout_validation_dos_prevention() {
1352-
use std::time::Duration;
1353-
1354-
// Test extremely long timeout (should be rejected)
1355-
let very_long_timeout = Duration::from_secs(3600); // 1 hour
1356-
assert!(very_long_timeout > Duration::from_secs(300)); // Exceeds max
1357-
1358-
// Test zero timeout (should be rejected)
1359-
let zero_timeout = Duration::from_millis(0);
1360-
assert!(zero_timeout.is_zero());
1361-
1362-
// Test extremely short timeout (should be rejected)
1363-
let too_short_timeout = Duration::from_nanos(1);
1364-
assert!(too_short_timeout < Duration::from_millis(1));
1365-
1366-
// Test valid timeout ranges
1367-
let valid_timeouts = vec![
1368-
Duration::from_millis(1), // Minimum valid
1369-
Duration::from_millis(100), // Short but valid
1370-
Duration::from_secs(1), // Normal
1371-
Duration::from_secs(30), // Standard
1372-
Duration::from_secs(300), // Maximum valid
1373-
];
1374-
1375-
for timeout in valid_timeouts {
1376-
assert!(timeout >= Duration::from_millis(1));
1377-
assert!(timeout <= Duration::from_secs(300));
1378-
assert!(!timeout.is_zero());
1379-
}
1380-
}
1381-
1382-
/// Test timeout validation error messages
1383-
#[tokio::test]
1384-
async fn test_timeout_validation_error_messages() {
1385-
use std::time::Duration;
1386-
1387-
// Test that timeout validation provides meaningful error messages
1388-
let invalid_timeouts = vec![
1389-
(Duration::from_secs(400), "exceeds maximum"), // Too long
1390-
(Duration::from_millis(0), "cannot be zero"), // Zero
1391-
(Duration::from_nanos(1), "at least 1 millisecond"), // Too short
1392-
];
1393-
1394-
for (timeout, expected_message_part) in invalid_timeouts {
1395-
// Verify that these timeouts would fail validation
1396-
match timeout {
1397-
t if t > Duration::from_secs(300) => {
1398-
assert!(expected_message_part.contains("maximum"));
1399-
}
1400-
t if t.is_zero() => {
1401-
assert!(expected_message_part.contains("zero"));
1402-
}
1403-
t if t < Duration::from_millis(1) => {
1404-
assert!(expected_message_part.contains("millisecond"));
1405-
}
1406-
_ => unreachable!(),
1407-
}
1408-
}
1409-
}
1410-
14111349
/// Test that different ElicitationAction values map to correct error types
14121350
#[tokio::test]
14131351
async fn test_elicitation_action_error_mapping() {

0 commit comments

Comments
 (0)