Safeguard
Security Guides•

nginx proxy_ssl_verify is off by default: fix your upstream TLS

nginx does not verify the certificate of an https upstream unless you set proxy_ssl_verify on. The directives needed to verify, name check and send SNI.

Safeguard Security Team
3 min read

When nginx proxies to an https backend, it does not verify that backend's certificate unless you tell it to. The documented default is proxy_ssl_verify off. Traffic is encrypted but the proxy will talk to anyone presenting any certificate. Turning verification on takes four directives.

What the docs say

In the nginx proxy module documentation, proxy_ssl_verify has the default off and enables or disables verification of the proxied HTTPS server certificate. proxy_ssl_trusted_certificate names a PEM file of trusted CA certificates used for that verification, and because verify defaults to off, that file does nothing until verification is on. People often add the CA file and believe they are protected.

proxy_ssl_server_name also defaults to off. It controls whether the server name is passed in the TLS Server Name Indication extension when connecting to the proxied server. proxy_ssl_name sets the name used for both certificate verification and SNI, and by default is the host part of the proxy_pass URL.

A working configuration

location / {
    proxy_pass https://backend.internal:8443;

    proxy_ssl_verify              on;
    proxy_ssl_trusted_certificate /etc/nginx/internal-ca.pem;
    proxy_ssl_server_name         on;
    proxy_ssl_name                backend.internal;
}

Each line matters. Verify on enables the check. The trusted file says which CA to believe. The server name line sends SNI, which many backends need to choose the right certificate. The name line says which hostname the certificate must match.

Why it matters

Without verification, an attacker positioned on the path between proxy and backend, or able to redirect that name, can present their own certificate and read or alter requests, including session cookies and API tokens. The encryption exists but the identity check does not.

This is most relevant when the backend is across a shared network, another cluster or a vendor boundary. For a single host over loopback it matters less, but turning verification on is still cheap. The TLS termination decision guide helps pick when to re-encrypt.

Related defaults worth checking

  • proxy_http_version default is 1.1 since nginx 1.29.7, and was 1.0 before. Older builds that rely on keepalive to the backend may need it set explicitly.
  • proxy_read_timeout and proxy_connect_timeout default to 60s, so a slow backend ties up a worker connection for a minute. The connect timeout usually cannot exceed 75 seconds.
  • proxy_set_header inherits only if the current level defines none, the same trap as add_header. Our add_header post explains it.

Test it

Point the backend name at a host with a self signed certificate in a staging copy of the config. With verification on, requests should fail with a 502 and the error log should name a certificate problem. If they succeed, verification is not applied in that location. You can also inspect the backend yourself with openssl s_client.

Where Safeguard fits

Safeguard does not rewrite proxy settings. It scans the dependencies and container images that run your backend and keeps compliance evidence organized. Try the free scan at https://gold.safeguard.sh/scan.

Quick check

What is the default of proxy_ssl_verify?

off. nginx does not verify the upstream certificate unless you enable it.

Does proxy_ssl_trusted_certificate alone enable checking?

No. It only supplies the CA file, and verification still needs proxy_ssl_verify on.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.