VYPR
Medium severity4.0NVD Advisory· Published Jul 5, 2025· Updated Apr 15, 2026

CVE-2025-53604

CVE-2025-53604

Description

The web-push crate before 0.10.3 for Rust allows a denial of service (memory consumption) in the built-in clients via a large integer in a Content-Length header.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
web-pushcrates.io
< 0.10.40.10.4

Patches

1
8447ed86bf3f

Limit push endpoint response size (#68)

https://github.com/pimeys/rust-web-pushNiklas FiekasFeb 16, 2025via ghsa
4 files changed · +23 27
  • src/clients/hyper_client.rs+6 11 modified
    @@ -1,10 +1,10 @@
     use async_trait::async_trait;
     
    -use http::header::{CONTENT_LENGTH, RETRY_AFTER};
    +use http::header::RETRY_AFTER;
     use hyper::{body::HttpBody, client::HttpConnector, Body, Client, Request as HttpRequest};
     use hyper_tls::HttpsConnector;
     
    -use crate::clients::{request_builder, WebPushClient};
    +use crate::clients::{request_builder, WebPushClient, MAX_RESPONSE_SIZE};
     use crate::error::{RetryAfter, WebPushError};
     use crate::message::WebPushMessage;
     
    @@ -66,18 +66,13 @@ impl WebPushClient for HyperWebPushClient {
             let response_status = response.status();
             trace!("Response status: {}", response_status);
     
    -        let content_length: usize = response
    -            .headers()
    -            .get(CONTENT_LENGTH)
    -            .and_then(|s| s.to_str().ok())
    -            .and_then(|s| s.parse().ok())
    -            .unwrap_or(0);
    -
    -        let mut body: Vec<u8> = Vec::with_capacity(content_length);
             let mut chunks = response.into_body();
    -
    +        let mut body = Vec::new();
             while let Some(chunk) = chunks.data().await {
                 body.extend(&chunk?);
    +            if body.len() > MAX_RESPONSE_SIZE {
    +                return Err(WebPushError::ResponseTooLarge);
    +            }
             }
             trace!("Body: {:?}", body);
     
    
  • src/clients/isahc_client.rs+11 16 modified
    @@ -1,10 +1,10 @@
     use async_trait::async_trait;
     use futures_lite::AsyncReadExt;
    -use http::header::{CONTENT_LENGTH, RETRY_AFTER};
    +use http::header::RETRY_AFTER;
     use isahc::HttpClient;
     
     use crate::clients::request_builder;
    -use crate::clients::WebPushClient;
    +use crate::clients::{WebPushClient, MAX_RESPONSE_SIZE};
     use crate::error::{RetryAfter, WebPushError};
     use crate::message::WebPushMessage;
     
    @@ -67,21 +67,16 @@ impl WebPushClient for IsahcWebPushClient {
             let response_status = response.status();
             trace!("Response status: {}", response_status);
     
    -        let content_length: usize = response
    -            .headers()
    -            .get(CONTENT_LENGTH)
    -            .and_then(|s| s.to_str().ok())
    -            .and_then(|s| s.parse().ok())
    -            .unwrap_or(0);
    -
    -        let mut body: Vec<u8> = Vec::with_capacity(content_length);
    -        let mut chunks = response.into_body();
    -
    -        chunks
    +        let mut body = Vec::new();
    +        if response
    +            .into_body()
    +            .take(MAX_RESPONSE_SIZE as u64 + 1)
                 .read_to_end(&mut body)
    -            .await
    -            .map_err(|_| WebPushError::InvalidResponse)?;
    -
    +            .await?
    +            > MAX_RESPONSE_SIZE
    +        {
    +            return Err(WebPushError::ResponseTooLarge);
    +        }
             trace!("Body: {:?}", body);
     
             trace!("Body text: {:?}", std::str::from_utf8(&body));
    
  • src/clients/mod.rs+2 0 modified
    @@ -14,6 +14,8 @@ pub mod hyper_client;
     #[cfg(feature = "isahc-client")]
     pub mod isahc_client;
     
    +const MAX_RESPONSE_SIZE: usize = 64 * 1024;
    +
     /// An async client for sending the notification payload.
     /// Other features, such as thread safety, may vary by implementation.
     #[async_trait]
    
  • src/error.rs+4 0 modified
    @@ -64,6 +64,8 @@ pub enum WebPushError {
         InvalidResponse,
         /// A claim had invalid data
         InvalidClaims,
    +    /// Response from push endpoint was too large
    +    ResponseTooLarge,
         Other(ErrorInfo),
     }
     
    @@ -134,6 +136,7 @@ impl WebPushError {
                 WebPushError::Io(_) => "io_error",
                 WebPushError::Other(_) => "other",
                 WebPushError::InvalidClaims => "invalidClaims",
    +            WebPushError::ResponseTooLarge => "response_too_large",
             }
         }
     }
    @@ -162,6 +165,7 @@ impl fmt::Display for WebPushError {
                 WebPushError::InvalidCryptoKeys => write!(f, "request has invalid cryptographic keys"),
                 WebPushError::Other(info) => write!(f, "other: {}", info),
                 WebPushError::InvalidClaims => write!(f, "at least one jwt claim was invalid"),
    +            WebPushError::ResponseTooLarge => write!(f, "response from push endpoint was too large"),
             }
         }
     }
    

Vulnerability mechanics

Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

6

News mentions

0

No linked articles in our index yet.