HIGH api rate abusesaml

Api Rate Abuse with Saml

SAML-Specific Remediation

Implementing effective rate limiting for SAML endpoints requires understanding SAML's specific authentication flows and using appropriate middleware. Here's how to implement SAML-specific rate limiting:

// Spring Security SAML configuration with rate limiting
@EnableWebSecurity
public class SamlSecurityConfig extends WebSecurityConfigurerAdapter {
    
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests(auth -> auth
            .antMatchers("/sso").
                accessRateLimited(10, Duration.ofMinutes(1))
                .and()
            .antMatchers("/metadata").
                accessRateLimited(5, Duration.ofMinutes(1))
        );
        
        http.saml2Login(saml2 -> saml2
            .identityProviderConfiguration(saml2AuthenticationRequest -> {
                // SAML-specific configuration
            })
        );
    }
    
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http.addFilterBefore(new SamlRateLimitFilter(), BasicAuthenticationFilter.class);
        return http.build();
    }
}

// Custom SAML rate limiting filter
@Component
public class SamlRateLimitFilter extends OncePerRequestFilter {
    private final RateLimiter rateLimiter = RateLimiter.create(10.0); // 10 requests per second
    
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
            throws ServletException, IOException {
        
        if (isSamlEndpoint(request)) {
            String clientId = getClientIdentifier(request);
            if (!rateLimiter.tryAcquire(clientId)) {
                response.setStatus(HttpServletResponse.SC_TOO_MANY_REQUESTS);
                response.getWriter().write("SAML authentication rate limit exceeded");
                return;
            }
        }
        
        filterChain.doFilter(request, response);
    }
    
    private boolean isSamlEndpoint(HttpServletRequest request) {
        String path = request.getRequestURI();
        return path.endsWith("/sso") || path.endsWith("/login") || path.endsWith("/metadata");
    }
    
    private String getClientIdentifier(HttpServletRequest request) {
        String ip = request.getRemoteAddr();
        String userAgent = request.getHeader("User-Agent");
        return ip + ":" + (userAgent != null ? userAgent.hashCode() : "");
    }
}

For Node.js/Express applications using passport-saml:

const express = require('express');
const rateLimit = require('express-rate-limit');
const SamlStrategy = require('passport-saml').Strategy;

const app = express();

// SAML-specific rate limiting
const samlLimiter = rateLimit({
    windowMs: 1 * 60 * 1000, // 1 minute
    max: 15, // limit each IP to 15 requests per window
    message: 'Too many SAML authentication attempts',
    keyGenerator: (req) => {
        // Include SAML-specific identifiers
        const samlRequest = req.body.SAMLRequest;
        const relayState = req.body.RelayState;
        return req.ip + ':' + (samlRequest || relayState || 'unknown');
    }
});

// Apply rate limiting to SAML endpoints
app.post('/sso', samlLimiter, (req, res) => {
    // SAML authentication logic
});

app.get('/metadata', samlLimiter, (req, res) => {
    // SAML metadata endpoint
});

// Passport SAML configuration
passport.use(new SamlStrategy({
    path: '/sso',
    entryPoint: 'https://idp.example.com/sso',
    issuer: 'https://app.example.com',
    cert: fs.readFileSync('idp-signing-certificate.pem').toString(),
    acceptedClockSkew: 300
}, (profile, done) => {
    // Verify SAML response
    return done(null, profile);
}));

For Python/Flask with flask-saml2:

from flask import Flask, request
from flask_saml2.sp import ServiceProvider
from flask_limiter import Limiter
from flask_limiter.util import get_remote_address

app = Flask(__name__)
limiter = Limiter(
    get_remote_address,
    default_limits=["200 per day", "50 per hour"]
)

class MyServiceProvider(ServiceProvider):
    def get_sso_url(self):
        return 'https://idp.example.com/sso'

    def get_metadata_url(self):
        return '/saml/metadata'

    def get_assertion_url(self):
        return '/saml/acs'

sp = MyServiceProvider()

# SAML-specific rate limiting
@app.route('/sso', methods=['POST'])
@limiter.limit("10/minute", error_message='SAML rate limit exceeded')
def sso():
    try:
        saml_request = request.form['SAMLRequest']
        # Process SAML authentication
        return sp.create_authn_request_response()
    except Exception as e:
        return str(e), 400

@app.route('/metadata')
@limiter.limit("5/minute", error_message='Metadata rate limit exceeded')
def metadata():
    return sp.get_metadata_xml()

Additional SAML-specific protections include:

  • Validating AssertionConsumerServiceURL against a whitelist of allowed endpoints
  • Implementing IP-based rate limiting for high-risk authentication attempts
  • Using distributed rate limiting for SAML endpoints across multiple servers
  • Monitoring SAML response processing times and implementing circuit breakers

Frequently Asked Questions

Why are SAML endpoints particularly vulnerable to rate abuse?
SAML endpoints process complex XML-based authentication requests that require significant server resources. Each AuthnRequest must be parsed, validated against the identity provider, and potentially trigger multi-factor authentication workflows. Unlike simple API endpoints, SAML processing involves cryptographic operations, XML schema validation, and potentially external service calls to the IdP. This computational overhead makes SAML endpoints attractive targets for resource exhaustion attacks through rate abuse.
How does middleBrick detect SAML rate abuse vulnerabilities?
middleBrick performs black-box scanning of SAML endpoints by sending controlled request bursts to authentication and metadata endpoints. The scanner analyzes response patterns, timing variations, and error handling to identify missing rate limiting. It specifically tests /sso, /login, and /metadata endpoints with SAML-formatted requests, measuring how the service handles rapid authentication attempts. The scanner also examines SAML response processing and checks for inconsistent error messages that might indicate vulnerable implementations.