ASVS 5.0 V17.1.2 requires that a TURN server is not susceptible to resource exhaustion when legitimate users try to open a large number of ports. It is a Level 3 requirement.
Each TURN allocation reserves a relay port. A finite port range and finite memory mean one authenticated user can starve everyone else unless the server enforces per user limits.
Why it matters
Credentials for WebRTC apps are often distributed widely. A single valid user, or a script holding one credential, can request allocations until the relay range is empty. Calls then fail for real users. See CWE-770 for the general weakness.
How to implement it
Set quotas per user and in total, size the relay port range deliberately, and rate limit the expensive operations. With coturn:
min-port=49152
max-port=65535
user-quota=12
total-quota=1200
max-bps=1000000
bps-capacity=0
stale-nonce=600
user-quota caps allocations per username, total-quota caps the server, and max-bps limits bandwidth per session. Use short lived credentials from the TURN REST API pattern so abuse is bounded by expiry. Add monitoring on allocation count and port utilization, and a firewall limit on new UDP flows per source address.
How to test it
Using a test credential, open allocations in a loop until you are refused, and check the refusal happens at your configured user-quota (typically a 486 Allocation Quota Reached response). Then, while that user is at quota, confirm a second user can still allocate. Finally, run a load test at expected peak plus a margin and confirm port utilization alerts fire before exhaustion.
Sizing and monitoring
Work out capacity from numbers. If each call needs two allocations at peak and you expect 500 concurrent calls, you need roughly a thousand allocations, so a port range of a few thousand gives headroom. Alert at seventy percent of ports in use. Track allocations per user over time so you can spot a credential that is being abused, and revoke it.
Expire credentials quickly. With the TURN REST API pattern the username carries an expiry timestamp and the password is an HMAC of it, so a leaked credential stops working on its own after a short period.
Common mistakes
- Leaving quotas unset, which means unlimited.
- One shared credential for all users, so per user quotas protect nothing.
- A relay port range of a few hundred ports on a busy service.
- No alert on utilization.
Quick check
Why are per user quotas not enough alone?
An attacker with many accounts or credentials still reaches the total. Keep a global cap and monitor utilization too.