ASVS 5.0 V15.4.1 requires that shared objects in multi threaded code, such as caches, files and in memory state, are accessed with thread safe types and synchronization like locks or semaphores, to avoid race conditions and corrupted data. It is Level 3. Share as little as possible, and when you must share, guard every access path.
Why it matters
A race condition is a security bug when the shared data is a session, a balance, a permission cache or a rate limit counter. Two requests interleave and one reads a stale value, so a limit is exceeded or a check is skipped. These bugs are intermittent, which is why they survive testing and show up under attacker load.
How to implement it
Prefer concurrency safe types over hand rolled locking.
// Java: atomic, lock free counter and a concurrent map
private final ConcurrentHashMap<String, Session> sessions = new ConcurrentHashMap<>();
private final AtomicInteger failures = new AtomicInteger();
Session s = sessions.computeIfAbsent(id, k -> loadSession(k)); // atomic
When several fields must change together, use one lock for all of them:
type Wallet struct {
mu sync.Mutex
balance int64
}
func (w *Wallet) Debit(n int64) error {
w.mu.Lock()
defer w.mu.Unlock()
if w.balance < n {
return errors.New("insufficient funds")
}
w.balance -= n
return nil
}
The check and the update sit inside one critical section. Hold locks for the shortest time possible and never call unknown code while holding one.
How to test it
Run tests under a race detector: go test -race ./..., ThreadSanitizer for C and C++, or the equivalent for your runtime. Then add a stress test that fires many concurrent operations at one object and asserts an invariant, such as the balance never going negative. Run it hundreds of times.
Common mistakes
- Protecting writes with a lock but reading without one.
- Using a thread safe map and then doing check then insert as two steps.
- Sharing a non thread safe object, such as a date formatter, between requests.
- Assuming a single process deployment when autoscaling runs several.
Quick check
Does a thread safe collection make my logic safe?
No. Each call is safe, but a sequence of calls is not unless you use an atomic compound operation or a lock.
Which level is this?
Level 3.