Fighting DDoS Attacks: Implementing Custom Rate Limiting in Your API with Spring Boot
Distributed Denial-of-Service (DDoS) attacks on APIs are malicious attempts to overload an online service, such as a web API, by generating a massive amount of simultaneous requests from multiple sources. The goal is to overwhelm the target server, exhaust its resources, and render the service inaccessible to legitimate users.
Key features of DDoS attacks on APIs include:
- Massive volume of requests: Attackers send a large number of simultaneous requests to the API from a network of compromised devices (botnets) or automated tools, causing a resource overload on the server.
- Geographical distribution: DDoS attacks often originate from multiple geographical locations, making it challenging to identify and block malicious IP addresses.
- Variability in the application layer: DDoS attacks can target different parts of the API infrastructure, including network, transport, or application layers. Some attacks may focus on specific endpoints or critical functions within the API.
- Aim to disrupt service: The primary goal of a DDoS attack on an API is to render the service inaccessible to legitimate users, potentially leading to revenue loss, reputation damage, and a negative user experience.
DDoS attacks can take various forms, such as SYN flood attacks, HTTP flood attacks, DNS amplification attacks, among others. Perpetrators exploit vulnerabilities in the underlying infrastructure to execute these attacks and disrupt service.
It is crucial for organizations to implement protective measures like rate limiting, real-time monitoring systems, firewalls, intrusion detection systems (IDS), and CDN services to mitigate the impact of these attacks and maintain the availability and security of their APIs.
On this occasion, we will see how to create a custom filter that will help us address this issue in case we don’t have third-party cloud systems or architectures and need to implement this method in our API.
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import javax.servlet.*;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;
@Component
@Order(1)
public class RateLimitFilter implements Filter {
private final ConcurrentHashMap<String, AtomicLong> requestCount = new ConcurrentHashMap<>();
private final long rateLimit = 10;
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
String ipAddress = request.getRemoteAddr();
AtomicLong count = requestCount.computeIfAbsent(ipAddress, k -> new AtomicLong());
if (count.incrementAndGet() > rateLimit) {
HttpServletResponse httpResponse = (HttpServletResponse) response;
httpResponse.setStatus(HttpServletResponse.SC_TOO_MANY_REQUESTS);
httpResponse.getWriter().write("Rate limit exceeded. Please try again later.");
return;
}
chain.doFilter(request, response);
}
}
This RateLimitFilter checks the number of requests per second for each IP address and responds with a status code 429 Too Many Requests if the established limit (rateLimit) is exceeded.
Add a logging monitoring system to your API to validate which IPs were blocked
private void logBlockedRequest(String ipAddress, ServletRequest request) {
logger.log(Level.INFO, "Blocked request from IP: " + ipAddress + ", URI: " + ((HttpServletRequest) request).getRequestURI());
}
//call in validation of limit
Conclusion
The implementation of rate limiting is a fundamental strategy to protect an API against DDoS attacks and ensure its availability and stability. Although considered a simple method, its effectiveness lies in its ability to control the number of requests the API can handle, helping to prevent resource overload and service disruption.
Through rate limiting, a limit can be set on the number of requests allowed per second, significantly reducing the impact of a DDoS attack by restricting malicious traffic. As the API grows and security needs evolve, this simple method can be scaled and adjusted to meet specific requirements.
By combining rate limiting with other security strategies such as firewalls, real-time monitoring, and security updates, a comprehensive approach is created to safeguard the API from cyber threats and attacks. The inherent flexibility of rate limiting allows for adjusting limits, setting custom rules, and excluding certain IP addresses or routes based on changing application needs.
In summary, while rate limiting may be considered a straightforward solution, its scalability and adaptability make it an essential component for API security, providing a robust first line of defense against DDoS attacks and serving as a solid foundation for building a more complex and comprehensive security ecosystem.