ASVS 5.0 V11.3.2 (Level 1) requires that only approved ciphers and modes are used, for example AES with GCM. In practice: keep a short allow list, and make code reject anything outside it.
Why it matters
Home made ciphers, DES, RC4 and unauthenticated modes keep appearing in code reviews because someone copied an old snippet. An allow list turns that from a debate into a failing check.
How to implement it
A sensible allow list for new code: AES-128 or AES-256 in GCM, and ChaCha20 Poly1305. Wrap it once and let everyone call the wrapper.
func Seal(key, plaintext []byte) ([]byte, error) {
block, err := aes.NewCipher(key) // 16 or 32 byte key
if err != nil { return nil, err }
gcm, err := cipher.NewGCM(block)
if err != nil { return nil, err }
nonce := make([]byte, gcm.NonceSize())
if _, err := rand.Read(nonce); err != nil { return nil, err }
return gcm.Seal(nonce, nonce, plaintext, nil), nil
}
In Node, crypto.createCipheriv('aes-256-gcm', key, iv) is the equivalent; read and check the auth tag on decrypt.
How to test it
Write a lint rule or grep check that lists every cipher name string in the code and compares it to the allow list. For TLS, scan servers and confirm only AEAD suites are offered.
Common mistakes
- Several different wrappers, each with its own mode choices
- Using GCM but ignoring the auth tag on read
- Leaving 3DES enabled for one old client
Quick check
Name two approved options.
AES with GCM and ChaCha20 Poly1305.