Rate Limiting Bypass in Chi with Mutual Tls
Rate Limiting Bypass in Chi with Mutual Tls — how this specific combination creates or exposes the vulnerability
Rate limiting in Chi is typically enforced at the application or gateway layer using request counts per key (IP, API key, or principal). When mutual TLS (mTLS) is enforced, the server authenticates each client certificate and often maps requests to the certificate’s subject or serial number. If rate limiting is keyed only on the authenticated identity (e.g., certificate common name) and not augmented with additional dimensions, an attacker who obtains or compromises a valid client certificate can exhaust the quota for that identity. This makes the mTLS channel a single point of failure for identity-based rate limiting.
Additionally, mTLS does not inherently protect against HTTP method abuse or path-specific targeting. A compromised certificate may allow the attacker to issue high-volume requests to sensitive endpoints that lack per-client or per-IP throttling. Chi’s default behavior does not bind rate limits to transport-layer properties such as the client certificate fingerprint or the TLS session’s unique connection identifiers, so an attacker can reuse a valid certificate across multiple connections to bypass coarse-grained limits.
Another bypass scenario involves certificate delegation or multi-tenant configurations where a single client certificate is shared across services or users. If rate limiting is applied only at the ingress and not enforced per downstream service or per request path, an attacker can route traffic through less-protected endpoints to circumvent stricter limits on sensitive routes. In Chi, without explicit enforcement of request uniqueness per connection or per consumer, shared credentials enable quota manipulation across distinct operational contexts.
Furthermore, mTLS does not prevent protocol-level evasion such as request splitting or smuggling when underlying HTTP parsers mis-handle headers under TLS. Malformed headers or chunked encoding quirks can sometimes trick rate limit counters into undercounting requests. Chi applications that rely solely on middleware-level rate limiters without validating message integrity per connection may inadvertently allow inflated request rates when mTLS is in use.
To detect these risks, middleBrick scans unauthenticated attack surfaces and cross-references OpenAPI specifications with runtime behavior. For APIs using mTLS and Chi, findings may highlight missing per-client rate limits, over-reliance on identity-based throttling, and absence of secondary controls such as request fingerprinting or path-specific quotas. Remediation guidance typically includes layered controls and monitoring to reduce the attack surface exposed by this combination.
Mutual Tls-Specific Remediation in Chi — concrete code fixes
Implement robust rate limiting in Chi that accounts for mTLS contexts by combining identity-based limits with additional discriminating factors such as connection metadata and request characteristics. Below are concrete, syntactically correct examples using Chi and related middleware to enforce per-client rate limits with mTLS.
Example 1: Rate limiting by certificate subject in Chi
Use the client certificate presented during mTLS to derive a stable key for rate limiting. This example extracts the subject from the TLS state and applies a token-bucket limiter scoped to that subject.
import { createApp, json } from 'chi';
import { tlsSubjectRateLimiter } from './rateLimiters';
const app = createApp();
app.use(json());
app.use((req, res, next) => {
const subject = req.socket.getPeerCertificate?.().subject;
if (!subject) {
res.status(400).send({ error: 'Client certificate required' });
return;
}
const allowed = tlsSubjectRateLimiter.consume(subject, 10, 60_000); // 10 requests per 60s per subject
if (!allowed) {
res.status(429).send({ error: 'Rate limit exceeded for client certificate' });
return;
}
next();
});
app.get('/secure', (req, res) => {
res.send({ message: 'Access granted with mTLS rate limiting' });
});
app.listen(3000);
Example 2: Layered limits using connection and path in Chi
Combine per-client limits with per-path quotas to reduce risk of bypass via shared certificates. This approach adds a secondary dimension to rate limiting in Chi routes.
import { createApp, json } from 'chi';
const app = createApp();
const pathQuota = new Map(); // simple in-memory path quota store
app.use(json());
app.use((req, res, next) => {
const subject = req.socket.getPeerCertificate?.().subject;
const path = req.url;
const clientKey = `${subject}|${path}`;
const allowed = consumeWithSlidingWindow(clientKey, 5, 10_000); // 5 per 10s per path per client
if (!allowed) {
res.status(429).send({ error: 'Path-specific rate limit exceeded' });
return;
}
next();
});
app.post('/admin/action', (req, res) => {
res.send({ executed: true });
});
function consumeWithSlidingWindow(key, limit, windowMs) {
const now = Date.now();
const bucket = pathQuota.get(key) || { count: 0, start: now };
if (now - bucket.start > windowMs) {
bucket.count = 1;
bucket.start = now;
} else {
bucket.count += 1;
}
if (bucket.count > limit) return false;
pathQuota.set(key, bucket);
return true;
}
app.listen(3000);
Example 3: Enforce mTLS and reject unauthorized clients before rate limiting
Ensure mTLS is mandatory and validate certificate fields before applying any rate limiting logic. This prevents unauthenticated traffic from consuming quota.
import { createApp, json } from 'chi';
const app = createApp();
app.use(json());
app.use((req, res, next) => {
const cert = req.socket.getPeerCertificate();
if (!cert || !cert.subject) {
res.status(403).send({ error: 'mTLS authentication failed' });
return;
}
// Optionally validate issuer or extended key usage here
next();
});
// Apply rate limiting after mTLS validation
app.use((req, res, next) => {
const subject = req.socket.getPeerCertificate().subject;
const allowed = consumeSubject(subject, 20, 30_000);
if (!allowed) {
res.status(429).send({ error: 'Client rate limit exceeded' });
return;
}
next();
});
app.get('/data', (req, res) => {
res.send({ data: 'protected' });
});
function consumeSubject(subject, limit, windowMs) {
// simplified placeholder for a token-bucket or sliding-window implementation
return true;
}
app.listen(3000);
Operational recommendations
- Key rate limits by certificate subject or a derived stable identifier to ensure mTLS context is respected.
- Add path- or method-specific quotas to prevent shared certificates from bypassing limits on sensitive routes.
- Log certificate metadata (subject, serial) with rate limit violations for audit and incident response.
- Monitor for certificate sharing across services and rotate credentials if abuse is detected.
Related CWEs: resourceConsumption
| CWE ID | Name | Severity |
|---|---|---|
| CWE-400 | Uncontrolled Resource Consumption | HIGH |
| CWE-770 | Allocation of Resources Without Limits | MEDIUM |
| CWE-799 | Improper Control of Interaction Frequency | MEDIUM |
| CWE-835 | Infinite Loop | HIGH |
| CWE-1050 | Excessive Platform Resource Consumption | MEDIUM |