ASVS 5.0 V12.3.1 requires an encrypted protocol, usually TLS, on all connections into and out of your application. The scope is wide: databases, message brokers, monitoring agents, management consoles, SSH, mainframes, partner systems and third party APIs. The server must not fall back to an unencrypted protocol. It is Level 2.
Why it matters
Teams harden the public edge and then leave the interior plaintext, on the theory that the network is trusted. Lateral movement ends that theory. An attacker on one compromised host can sniff database credentials, metrics tokens and message payloads from the wire.
Fallback is the second half of the problem. A client with an option like "try TLS, else plain" will be downgraded by anyone who can block the TLS attempt.
How to implement it
Make encryption mandatory in each client and server, not optional.
PostgreSQL client connection string that refuses plaintext and verifies the server:
postgresql://app@db.internal:5432/orders?sslmode=verify-full&sslrootcert=/etc/pki/internal-ca.pem
Server side, reject non TLS connections in pg_hba.conf by using only hostssl lines:
hostssl orders app 10.0.0.0/16 scram-sha-256
Other places to switch on:
- Redis:
tls-port 6379andport 0to disable the plain listener. - Kafka: listeners of type SSL or SASL_SSL only, no PLAINTEXT.
- SSH instead of telnet or plain FTP, and SFTP instead of FTP.
- Metrics and logging agents: HTTPS endpoints with verified certificates.
Keep an inventory of every connection (see V13.1.1) so nothing is missed.
How to test it
From a host on the network, attempt a plaintext connection to each service and confirm it is refused:
psql "postgresql://app@db.internal/orders?sslmode=disable"
redis-cli -h cache.internal -p 6379 ping
Both must fail. Then run a packet capture while the app exercises a workflow and check that no cleartext protocol appears:
tcpdump -i eth0 -nn -A 'port 5432 or port 6379 or port 9092' | head
You should see TLS records, not SQL text.
Common mistakes
- sslmode=prefer or require, which encrypt but skip server verification (see V12.3.2).
- Leaving the legacy plaintext port open "just for the old reporting tool".
- Forgetting out of band paths: backups, replication, admin tools, health check agents.
- Assuming a VPN or private subnet replaces encryption.
Try it yourself
Draw the connection map for one request path through your system: browser to edge, edge to app, app to database, app to cache, app to queue, app to a third party API, plus the monitoring agent beside each host. Mark each arrow as encrypted and verified, encrypted only, or plaintext.
Anything not in the first category gets a ticket. Start with the arrows carrying credentials or personal data, since those carry the most risk. Then attempt the plaintext connections described above and keep the refused connection output as evidence.
Do not forget scheduled jobs and one off tools. Backup scripts and ad hoc admin utilities often talk to databases with TLS off because nobody owns them.
Quick check
What does "must not fall back" mean in practice?
The plaintext listener is disabled or refused, and clients are configured to fail when TLS cannot be established.