Documentation

Security Misconfiguration

HIGH SEVERITY OWASP TOP 10 #5 COMMON VULNERABILITY

Overview

Security Misconfiguration occurs when security settings are not properly defined, implemented, or maintained, leaving applications vulnerable to attacks.

Security Misconfiguration Illustration

In One Sentence

Leaving security doors unlocked, alarms disabled, or passwords unchanged from factory defaults.


Simple Explanation

Real-World Analogy

Imagine you buy a brand-new house with the latest security features:

The House Comes With
  • Advanced alarm system (but you never turn it on)
  • Smart locks (but you keep using the contractor's default code "1234")
  • Security cameras (but they're still in the box)
  • Reinforced doors (but you leave them wide open)
  • Safe for valuables (with instruction manual taped to it)
Then You Wonder

You go on vacation and wonder why you got robbed.

In the Digital World

Security Misconfiguration = Having security features available but not using them properly.

  • Default passwords never changed
  • Unnecessary features enabled
  • Security headers missing
  • Error messages revealing sensitive information
  • Outdated software with known vulnerabilities
  • Unnecessary ports and services running

Types of Security Misconfigurations

1. Default Credentials

Using factory-set usernames and passwords that were never changed

textadmin / admin
administrator / password
root / root
admin / password123
user / user
python# Attacker's automated script
import requests

common_defaults = [
    ('admin', 'admin'),
    ('admin', 'password'),
    ('root', 'root'),
    ('administrator', 'password123')
]

for username, password in common_defaults:
    response = requests.post('https://target.com/admin/login',
        data={'user': username, 'pass': password})

    if 'dashboard' in response.text:
        print(f"SUCCESS! {username}:{password}")
        break

2. Unnecessary Features Enabled

Running features, services, or ports that aren't needed for the application to function

bash# Port scan reveals unnecessary exposure
$ nmap target.com

PORT      STATE SERVICE
22/tcp    open  ssh          # SSH admin access - needed?
80/tcp    open  http         # Web server - needed
443/tcp   open  https        # Web server - needed
3306/tcp  open  mysql        # Database - why publicly accessible?
8080/tcp  open  http-proxy   # Debug server - why exposed?
27017/tcp open  mongodb      # Database - no authentication!
python# settings.py - DANGEROUS in production
DEBUG = True  # NEVER in production!

INSTALLED_APPS = [
    'django.contrib.admin',        # Needed
    'django.contrib.auth',         # Needed
    'myapp',                       # Needed
    'debug_toolbar',               # DEV ONLY - remove!
    'django_extensions',           # DEV ONLY - remove!
]

ALLOWED_HOSTS = ['*']  # DANGEROUS - allows any host header
apache# Apache configuration - WRONG
Options +Indexes  # Shows directory listings - REMOVE!
<Directory /var/www/html/uploads>
    AllowOverride All  # Allows .htaccess files - risky
</Directory>

3. Information Disclosure

Revealing sensitive information through error messages, headers, or files

❌ BAD (Reveals Internal Paths)
Database Connection Error:
ERROR: Connection refused (Connection refused)
Host: 10.0.1.15:5432
Database: production_db
User: db_admin
Password file: /etc/postgresql/.pgpass
Stack trace:
  File "/var/www/myapp/db.py", line 42
  File "/var/www/myapp/models/user.py", line 18
  ...
✅ GOOD (Generic Message)
An error occurred. Please try again later.
Error ID: 7a3f9e2b (support reference)
❌ Vulnerable Response
httpHTTP/1.1 200 OK
Server: Apache/2.4.41 (Ubuntu)  # Attacker knows exact version
X-Powered-By: PHP/7.2.24        # Attacker knows PHP version
X-AspNet-Version: 4.0.30319     # Framework version

Attackers search for known vulnerabilities in these specific versions.

✅ Secure Response
httpHTTP/1.1 200 OK
Server: WebServer  # Generic name
# X-Powered-By header removed
# X-AspNet-Version header removed

4. Missing Security Headers

❌ MISSING HEADERS (Vulnerable)
httpHTTP/1.1 200 OK
Content-Type: text/html
Set-Cookie: session=abc123
✅ PROPER HEADERS (Secure)
httpHTTP/1.1 200 OK
Content-Type: text/html

# Prevents clickjacking attacks
X-Frame-Options: DENY

# Stops XSS attacks
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block

# Enforces HTTPS
Strict-Transport-Security: max-age=31536000; includeSubDomains

# Controls what resources can load
Content-Security-Policy: default-src 'self'; script-src 'self' https://trusted-cdn.com

# Limits what info is sent in Referer header
Referrer-Policy: strict-origin-when-cross-origin

# Controls access to browser features
Permissions-Policy: geolocation=(), microphone=(), camera=()

# Secure cookies
Set-Cookie: session=abc123; HttpOnly; Secure; SameSite=Strict

5. Outdated Software

Your server runs:
- Apache 2.4.29 (released 2017)

Known vulnerabilities in Apache 2.4.29:
- CVE-2021-44790: Remote Code Execution
- CVE-2021-26691: Buffer Overflow
- CVE-2020-9490: HTTP/2 Push Request Crash

Attacker searches:
"Apache 2.4.29 exploit" → finds working exploit code
Runs exploit → gains server access

6. Directory Listings and Backups

Web server showing folder contents or exposing backup files

Index of /uploads/

[DIR] documents/          2025-01-15 10:23
[DIR] confidential/       2025-01-14 09:15
[FILE] passwords.txt      2025-01-12 14:30  2KB
[FILE] user_data.csv      2025-01-10 11:45  15MB
[FILE] .env.backup        2025-01-08 08:12  1KB

Attacker can browse and download all files.

# Backup files
config.php.bak
database.sql.backup
.env.old
settings.py~
wp-config.php.save

# Version control
.git/
.svn/
.hg/

# IDE files
.vscode/
.idea/
*.swp (vim temporary files)

# Log files
error.log
access.log
debug.log

# Database dumps
dump.sql
backup_20250115.sql

Real-World Examples

Case Study 1: Capital One (2019)

Misconfigured AWS Web Application Firewall (WAF)

  • 100 million customers affected
  • Social Security numbers exposed
  • $80 million fine from regulators
  • $190 million in customer settlements
  1. WAF rules were too permissive
  2. Allowed access to AWS metadata service
  3. Attacker exploited SSRF vulnerability
  4. Retrieved temporary AWS credentials
  5. Accessed S3 buckets with customer data
json{
  "WAF Rule": {
    "Action": "ALLOW",
    "Condition": "ANY"  // Should have been more restrictive
  },
  "S3 Bucket Policy": {
    "Effect": "Allow",
    "Principal": "*",    // Should have been specific IAM roles
    "Action": "s3:GetObject"
  }
}

Case Study 2: Elasticsearch Exposures (2018-2020)

Publicly accessible Elasticsearch databases with no authentication

  • Hundreds of companies affected
  • Billions of records exposed
  • Medical records, financial data, personal information
  • Default Elasticsearch installation has no authentication
  • Many companies deployed without changing defaults
  • Databases indexed by Shodan search engine
  • Anyone could read/modify/delete all data
yaml# elasticsearch.yml - WRONG
network.host: 0.0.0.0  # Binds to all interfaces - publicly accessible
xpack.security.enabled: false  # No authentication required

Case Study 3: MongoDB Ransomware (2017)

MongoDB databases with no authentication on public internet

  • 26,000+ databases hijacked
  • Data deleted and held for ransom
  • Small businesses crippled
  1. MongoDB default installation has no authentication
  2. Databases bound to 0.0.0.0 (all interfaces)
  3. Attackers scanned for open MongoDB instances
  4. Deleted all data
  5. Left ransom note demanding Bitcoin
yaml# mongod.conf - WRONG
net:
  bindIp: 0.0.0.0  # Public access
  port: 27017
security:
  authorization: disabled  # No authentication

Prevention & Mitigation

1. Change Default Credentials

Change all default passwords immediately after installation

  • [ ] Change default admin passwords
  • [ ] Change database root passwords
  • [ ] Update API keys and secrets
  • [ ] Change default SSH/RDP credentials
  • [ ] Update IoT device passwords
  • [ ] Remove/disable default accounts

2. Disable Unnecessary Features

Minimize attack surface by removing unused features

python# config.py
class ProductionConfig:
    DEBUG = False
    TESTING = False

    # Restrict allowed hosts
    ALLOWED_HOSTS = ['myapp.com', 'www.myapp.com']

    # Disable development tools
    SQLALCHEMY_ECHO = False

    # Remove debug toolbar
    DEBUG_TB_ENABLED = False

3. Implement Security Headers

Configure HTTP headers to enable browser security features

pythonfrom flask import Flask

app = Flask(__name__)

@app.after_request
def set_security_headers(response):
    response.headers['X-Frame-Options'] = 'DENY'
    response.headers['X-Content-Type-Options'] = 'nosniff'
    response.headers['X-XSS-Protection'] = '1; mode=block'
    response.headers['Strict-Transport-Security'] = 'max-age=31536000; includeSubDomains'
    response.headers['Content-Security-Policy'] = "default-src 'self'"
    response.headers['Referrer-Policy'] = 'strict-origin-when-cross-origin'
    return response

4. Keep Software Updated

Regular updates and patch management

  • [ ] Enable automatic security updates
  • [ ] Subscribe to security mailing lists
  • [ ] Monitor CVE databases for your stack
  • [ ] Test updates in staging environment
  • [ ] Apply critical patches immediately
  • [ ] Update dependencies regularly
  • [ ] Use dependency scanning tools
bash# Enable automatic security updates
sudo apt install unattended-upgrades
sudo dpkg-reconfigure --priority=low unattended-upgrades

# Configure automatic updates
echo 'APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Unattended-Upgrade "1";
APT::Periodic::AutocleanInterval "7";' | sudo tee /etc/apt/apt.conf.d/20auto-upgrades

5. Secure Error Handling

Generic error messages to users, detailed logs for developers

pythonfrom flask import Flask, jsonify
import logging

app = Flask(__name__)

# Configure logging
logging.basicConfig(
    filename='app.log',
    level=logging.ERROR,
    format='%(asctime)s %(levelname)s: %(message)s'
)

@app.errorhandler(Exception)
def handle_error(error):
    # Log full error details
    logging.error(f"Error: {str(error)}", exc_info=True)

    # Return generic message to user
    if app.debug:
        # Only show details in development
        return jsonify({'error': str(error)}), 500
    else:
        # Generic message in production
        return jsonify({
            'error': 'An error occurred',
            'error_id': generate_error_id()
        }), 500

Detection & Testing

Testing Checklist

  • [ ] Check all admin interfaces for default passwords
  • [ ] Verify database user passwords changed
  • [ ] Test API keys and tokens aren't defaults
  • [ ] Check IoT devices and network equipment
  • [ ] Test error messages for sensitive info
  • [ ] Check HTTP headers for version numbers
  • [ ] Look for exposed configuration files
  • [ ] Verify directory listings are disabled
  • [ ] Test for presence of security headers
  • [ ] Verify Content-Security-Policy is configured
  • [ ] Check cookie security attributes
  • [ ] Verify HTTPS enforcement (HSTS)
  • [ ] Port scan for open unnecessary ports
  • [ ] Check for debug mode in production
  • [ ] Verify test files removed
  • [ ] Check for development features enabled

Testing Tools

Nikto
bash# Web server scanner
nikto -h https://target.com

# Checks for:
# - Outdated software versions
# - Default files
# - Security misconfigurations
# - Information disclosure
Security Headers
bash# Check security headers
curl -I https://target.com

# Online tool
https://securityheaders.com/
Nmap
bash# Port scanning
nmap -sV target.com

# Check for unnecessary open ports
nmap -p- target.com
OWASP ZAP
bash# Automated security scan
zap-cli quick-scan https://target.com

Security Checklist

Development

  • [ ] Remove development/debug features in production
  • [ ] Disable verbose error messages
  • [ ] Remove test/sample files
  • [ ] Implement proper error handling
  • [ ] Add all security headers
  • [ ] Disable directory listings
  • [ ] Remove version disclosure in headers
  • [ ] Configure secure cookie settings

Infrastructure

  • [ ] Change all default credentials
  • [ ] Close unnecessary ports
  • [ ] Disable unnecessary services
  • [ ] Keep software updated
  • [ ] Configure firewalls properly
  • [ ] Use least privilege principles
  • [ ] Regular security audits
  • [ ] Monitor for exposed files

Testing

  • [ ] Scan for default credentials
  • [ ] Test for information disclosure
  • [ ] Verify security headers present
  • [ ] Check for outdated software
  • [ ] Scan for exposed files
  • [ ] Penetration testing
  • [ ] Regular vulnerability scans

Key Takeaways

Primary Defenses

  1. Change default credentials - First step after any installation
  2. Disable unnecessary features - Minimize attack surface
  3. Implement security headers - Enable browser protections
  4. Keep software updated - Apply security patches promptly
  5. Secure error handling - Generic messages to users, detailed logs internally

Critical Points

  • Security misconfiguration is #5 in OWASP Top 10 - extremely common
  • Default credentials are still used in millions of installations
  • Exposed configuration files can reveal database passwords and API keys
  • Missing security headers leave applications vulnerable to XSS and clickjacking

Best Practices

  • Use configuration management tools (Ansible, Terraform)
  • Implement security hardening baselines
  • Regular security audits and scans
  • Principle of least privilege everywhere
  • Defense in depth with multiple layers

References & Resources

Official Documentation

Testing Tools

Learning Resources


Layerd AI Protection

Layerd AI Cloud WAF detects and prevents misconfigurations:

  • Configuration scanning - Identifies common misconfigurations
  • Baseline monitoring - Detects configuration drift
  • Real-time alerts - Notifies of security risks
  • Automatic hardening - Applies security best practices

Learn more about Layerd AI Protection →


Remember: Security misconfiguration is one of the most common vulnerabilities. Always change default credentials, disable unnecessary features, implement security headers, and keep software updated.

Security by default, not security by obscurity!


Last updated: November 2025