Skip to content

Security misconfiguration

CWE-16OWASP A05:2021Updated August 29, 20265 min read

Security misconfiguration is the umbrella term for insecure settings: default passwords, debug modes left on in production, publicly readable cloud storage or missing security headers. Attackers find these mistakes with automated scans and use them as the cheapest way into your systems and data.

Not every vulnerability is a programming error. With security misconfiguration the software works exactly as intended, it is the settings that are wrong. A forgotten default password, a debug mode still enabled in production or a cloud bucket that is publicly readable: small oversights with outsized consequences. This article explains what falls under security misconfiguration, how attackers find these mistakes at scale, what the damage can be and how to lock your environment down for good.

What is security misconfiguration?

Security misconfiguration is the umbrella term for security risks that live not in the source code but in how software is installed and configured: default accounts that were never changed, unnecessary features and ports left open, error messages that reveal internal details, missing security headers or cloud permissions granted far too broadly. The category sits at number five in the OWASP Top 10 as A05:2021 and maps to CWE-16 (Configuration).

Think of a brand-new office building fitted with certified locks. The locks are not the problem, but the contractor left every door on the factory code, the fire exit is still propped open for the movers and the alarm system’s floor plan hangs in the lobby. Nothing is broken; the building was simply never set up securely. That is security misconfiguration in a nutshell: working technology whose settings leave the door open.

What makes this category awkward is its breadth. The mistake can sit in any layer of the stack: the operating system, the web server, the framework, the database, a container or the cloud platform. One forgotten setting in one layer is all an attacker needs.

How does an attack on a misconfigured system work?

Attackers rarely have to work for it. Search engines such as Shodan and Censys continuously index everything connected to the internet, including version numbers, open ports and admin interfaces. Automated scripts probe well-known paths such as /admin, /.git, /backup and /phpinfo.php, and churn through lists of default credentials. Run a misconfigured server and you will typically be found within hours, not because anyone is targeting you specifically, but because the entire internet is being swept around the clock.

This Express example shows what that looks like in practice: an API with three common configuration mistakes rolled into one.

Vulnerable:

const express = require('express');
const cors = require('cors');
const serveIndex = require('serve-index');
const app = express();

// CORS wide open: any website may call the API
app.use(cors({ origin: '*' }));

// Directory listing exposes every file in /backup
app.use('/backup', serveIndex('backup'), express.static('backup'));

// Error handling leaks stack traces and versions to the visitor
app.use((err, req, res, next) => {
  res.status(500).send('<pre>' + err.stack + '</pre>');
});

An attacker who requests /backup receives a tidy listing of every file in that directory, including last year’s database export. The wide-open CORS policy lets any arbitrary website talk to the API from a visitor’s browser. And every error the application throws comes back as a full stack trace: file paths, directory structure, framework versions and sometimes even query fragments. Every detail speeds up the attacker’s next move.

Secure:

const express = require('express');
const helmet = require('helmet');
const cors = require('cors');
const app = express();

app.disable('x-powered-by');   // do not advertise the framework
app.use(helmet());             // set standard security headers

// Only the origins you actually trust
app.use(cors({ origin: ['https://app.example.com'] }));

// Static files without listing, dotfiles blocked
app.use('/files', express.static('files', { index: false, dotfiles: 'deny' }));

// Generic error for the client, details only in the log
app.use((err, req, res, next) => {
  console.error(err);
  res.status(500).json({ error: 'Internal server error' });
});

The secure variant closes every tap: CORS works from an explicit allowlist, static files are served without a directory index and with dotfiles blocked, and on failure the visitor sees only a generic message while the details go to the internal log. Helmet adds the standard security headers on top, and the header that gives away the framework is switched off. More important than the individual lines is the principle behind them: anything not explicitly needed stays closed.

A debug or development setting enabled “temporarily” in production tends to stay there for months. Treat every environment as if it will be scanned today, because it will be.

What is the impact of security misconfiguration?

The severity ranges from low to high, and real-world incidents reflect that spread. A missing header or a visible version number is modest on its own: it leaks information that helps an attacker aim more precisely. But an admin panel with a default password, a database exposed to the internet without authentication or a publicly readable storage bucket hands over direct access to systems and sensitive data. Unsecured Elasticsearch and MongoDB instances have repeatedly leaked millions of customer records in recent years, without a single line of code being at fault.

Misconfiguration is also rarely the end of the story. A verbose error message reveals paths that enable a path traversal attack, an XML parser on default settings opens the door to XXE, and a forgotten debug console grows into remote code execution. For the organisation this quickly means a reportable data breach under the GDPR, recovery costs, reputational damage and hard questions from customers and regulators, all caused by a setting that would have taken five minutes to get right.

How do you detect security misconfiguration?

The good news: configuration flaws are eminently findable. Automated scanners compare headers, TLS settings, well-known paths and version numbers against secure baselines and catch the low-hanging fruit that way. Context, however, remains human work: whether a reachable endpoint is actually a problem depends on what sits behind it. Pentesters therefore follow, among other things, the configuration chapters of the OWASP Web Security Testing Guide: they try default credentials, hunt for forgotten test and admin interfaces, provoke error messages, review cloud permissions and bucket policies, and check whether environments drift apart. AssistSec includes these checks in every penetration test as a matter of course, precisely because this is so often where the first foot lands in the door.

How do you prevent security misconfiguration?

  • Make hardening a repeatable process: capture the secure configuration in code (infrastructure as code, golden images) so every environment is rolled out identically and verifiably.
  • Minimise the attack surface: remove or disable sample applications, unused features, ports, packages and accounts.
  • Replace all default passwords and remove default accounts before going live.
  • Separate development, test and production strictly; switch debug modes and verbose errors off in production.
  • Show visitors generic error pages only, and write technical details exclusively to internal logs.
  • Send security headers such as HSTS, Content-Security-Policy and X-Content-Type-Options.
  • Apply least privilege to cloud permissions and keep storage buckets private by default.
  • Verify the configuration automatically in the CI/CD pipeline, test periodically against benchmarks such as those from CIS, and repeat the check after every change.

Sources

Frequently asked questions

What are common examples of security misconfiguration?

Default passwords that were never changed, debug modes left on in production, publicly readable cloud buckets, directory listing, verbose error messages and missing security headers. The mistake can sit in any layer: web server, framework, database or cloud platform.

Is security misconfiguration a bug in the software?

No. The software works exactly as intended; the settings were simply chosen insecurely or never changed. That is why patching alone does not help: you have to review and harden the configuration itself, and repeat that check after every change.

Why is security misconfiguration in the OWASP Top 10?

Because the category shows up somewhere in almost every security assessment. OWASP ranked it fifth in 2021 (A05:2021), partly because modern stacks built on cloud services, containers and microservices keep adding settings that can be wrong.

Does a firewall or WAF protect against security misconfiguration?

Only partially. A WAF filters known attack patterns, but it will not stop an attacker who logs in with a default password or opens a publicly readable cloud bucket. Besides, a firewall can be misconfigured just as easily as anything else.

Related articles

Press / to search · Esc