Back to blog
AzureBest PracticesCloud SecurityDatabasesNetworking

Redis Cache Non-SSL Port Enabled: Why It Matters and How to Fix It

Azure Redis caches with port 6379 enabled send your access key in plaintext. Learn the risks and how to disable the non-SSL port with CLI, Terraform, and policy.

TL;DR

This check flags Azure Cache for Redis instances that still accept connections on the unencrypted port 6379. Anyone who can reach that port sees your traffic, including the auth key, in plaintext. Disable the non-SSL port so clients must use TLS on 6380.

Azure Cache for Redis can listen on two ports: an SSL/TLS port (6380) and a plain TCP port (6379). When the non-SSL port is enabled, the cache happily accepts unencrypted connections. That means the Redis protocol, your commands, your cached data, and critically the access key used to authenticate all travel across the network as cleartext.

The redis_nosslonly check looks at the enableNonSslPort property on each Redis instance and fails any cache where it is set to true. The fix is simple, but the consequences of leaving it open are not.


What this check detects

Every Azure Cache for Redis resource exposes a boolean property called enableNonSslPort. By default this is false, so new caches are SSL-only. But the property can be flipped to true at creation time or later, often because a legacy client library does not support TLS or a developer hit a connection error and disabled SSL to "just make it work."

Lensix reports a failure when:

  • The Redis cache has enableNonSslPort set to true, and
  • Port 6379 is therefore reachable by any client that can route to the cache.

Note: Redis authentication uses an access key sent with the AUTH command at the start of each connection. On the non-SSL port that key is sent in plaintext, so anyone passively capturing traffic can read it and then connect themselves.


Why it matters

Redis often holds session tokens, cached user records, rate-limit counters, queue payloads, and sometimes credentials. Treating that traffic as public-readable is a real problem, and the non-SSL port makes it exactly that for anyone on the path.

Plaintext key exposure

The most direct risk is the access key. Because the key is sent unencrypted, a single captured packet hands an attacker full read and write access to your cache. From there they can dump session data to hijack accounts, poison cached responses, or flush the entire dataset.

On-path and lateral movement attacks

People assume traffic inside a VNet is safe, but it is not. A compromised VM, a misconfigured peering, a malicious container in the same subnet, or a network appliance with logging enabled can all observe cleartext Redis traffic. Once an attacker has a foothold somewhere on the network, an unencrypted cache is one of the easiest things to pivot through.

Danger: If your cache stores session identifiers or auth tokens, plaintext capture of those values lets an attacker impersonate real users directly, with no need to crack a password or trigger an alert.

Compliance failures

Encryption in transit is a baseline requirement in PCI DSS, HIPAA, SOC 2, and the CIS Microsoft Azure Foundations Benchmark. An open non-SSL port is a clear, easily-auditable finding that auditors will flag, and one that is hard to defend after the fact.


How to fix it

The remediation is to disable the non-SSL port. After that, clients connect over TLS on port 6380 only. The change itself does not cause data loss and applies within seconds.

Warning: Disabling port 6379 will break any client still connecting without TLS. Before you flip the setting, confirm every application connects on 6380 with SSL enabled. Roll this out in staging first and watch connection error rates.

Option 1: Azure CLI

Disable the non-SSL port on an existing cache:

az redis update \
  --name my-redis-cache \
  --resource-group my-resource-group \
  --set enableNonSslPort=false

Verify the change took effect:

az redis show \
  --name my-redis-cache \
  --resource-group my-resource-group \
  --query enableNonSslPort \
  --output tsv

The output should be false.

Option 2: Azure Portal

  1. Open the Azure Cache for Redis resource in the portal.
  2. Under Settings, select Advanced settings.
  3. Find Allow access only via SSL and set it to Yes (this disables port 6379).
  4. Click Save.

Option 3: Update your client connection

If your client was using the non-SSL port, point it at 6380 with TLS. For example, with the .NET StackExchange.Redis library:

var options = ConfigurationOptions.Parse(
    "my-redis-cache.redis.cache.windows.net:6380,ssl=true,password=YOUR_KEY");
var connection = ConnectionMultiplexer.Connect(options);

For Python with redis-py:

redis-cli -h my-redis-cache.redis.cache.windows.net \
  -p 6380 -a YOUR_KEY --tls

Tip: While you are in the cache settings, set the Minimum TLS version to 1.2. Older TLS versions have known weaknesses, and 1.2 is the practical minimum for any modern client.

Option 4: Infrastructure as Code

If you manage Redis with Terraform, the relevant attribute is enable_non_ssl_port. Keep it set to false (which is also the default):

resource "azurerm_redis_cache" "example" {
  name                = "my-redis-cache"
  location            = azurerm_resource_group.example.location
  resource_group_name = azurerm_resource_group.example.name
  capacity            = 1
  family              = "C"
  sku_name            = "Standard"

  enable_non_ssl_port = false
  minimum_tls_version = "1.2"
}

The equivalent in a Bicep template:

resource redisCache 'Microsoft.Cache/redis@2023-08-01' = {
  name: 'my-redis-cache'
  location: location
  properties: {
    sku: {
      name: 'Standard'
      family: 'C'
      capacity: 1
    }
    enableNonSslPort: false
    minimumTlsVersion: '1.2'
  }
}

How to prevent it from happening again

Fixing one cache is easy. Making sure nobody re-enables the port across dozens of subscriptions is the real work. Push the control as far left as you can.

Enforce with Azure Policy

Azure ships a built-in policy that audits or denies caches with the non-SSL port enabled. Assign it with a Deny effect to block the misconfiguration at deploy time:

az policy assignment create \
  --name 'deny-redis-nonssl' \
  --display-name 'Redis caches should disable the non-SSL port' \
  --policy '/providers/Microsoft.Authorization/policyDefinitions/22bee202-a82f-4305-9a2a-6d7f44d4dedb' \
  --scope '/subscriptions/YOUR_SUBSCRIPTION_ID'

With Deny in place, any attempt to create or update a cache with enableNonSslPort=true is rejected before it lands.

Note: Policy definition 22bee202-a82f-4305-9a2a-6d7f44d4dedb is the built-in "Azure Cache for Redis should disable public network access" family. Check the current parameter set in the portal, since Microsoft updates these definitions, and confirm the effect is set to deny rather than audit.

Gate it in CI/CD

Catch the setting in pull requests before infrastructure ever reaches Azure. With Terraform, a Conftest or OPA policy can scan the plan:

package main

deny[msg] {
  resource := input.resource_changes[_]
  resource.type == "azurerm_redis_cache"
  resource.change.after.enable_non_ssl_port == true
  msg := sprintf("Redis cache '%s' has the non-SSL port enabled", [resource.address])
}

Run it in your pipeline after terraform plan:

terraform plan -out=tfplan
terraform show -json tfplan | conftest test -

Monitor continuously with Lensix

Policy and CI gates stop new drift, but settings get changed by hand during incidents and never reverted. Lensix runs redis_nosslonly across all your subscriptions on a schedule, so a cache that someone "temporarily" reopened gets flagged rather than quietly sitting exposed for months.


Best practices

  • SSL-only, always. There is no production reason to accept plaintext Redis traffic. If a client cannot do TLS, fix the client.
  • Set minimum TLS to 1.2. Disabling the plain port is not enough if you still allow weak TLS versions on the encrypted one.
  • Restrict network access. Pair SSL-only with private endpoints or VNet injection so the cache is not reachable from the public internet at all. Encryption protects traffic, but network isolation reduces who can attempt a connection in the first place.
  • Rotate access keys after exposure. If the non-SSL port was open in production, assume the key may have been observed. Regenerate it with az redis regenerate-keys and update your clients.
  • Prefer Microsoft Entra ID authentication. Newer Redis tiers support Entra ID auth, which removes the shared static key entirely and replaces it with short-lived tokens.
  • Audit on a schedule, not just at deploy. Configuration drifts. Continuous checks catch the gap between what your IaC says and what is actually running.

Tip: Combine this check with private endpoint enforcement. An SSL-only cache that is also unreachable from the internet gives you defense in depth: even a leaked key is useless to an attacker who cannot route to the endpoint.

Disabling the non-SSL port is a one-line change with no ongoing cost and no downside once your clients use TLS. It closes off plaintext key theft, satisfies common compliance baselines, and removes one of the easiest pivot points an attacker can find inside your network.