Skip to content
>_ITDITDWeb Security Platform

Security Guides

4 common security mistakes: default settings, forgotten services, missing monitoring and over-trusted input validation

Real incidents rarely involve exotic attacks. Sorted by the assumption behind them, the causes come down to four beliefs — and each was true once, which is why nobody re-examines them.

Published 2026-09-05 Updated 2026-10-04 Last verified 2026-09-05 9 min read

Line up the incidents that actually happen and exotic attack techniques barely appear. What appears is a small set of recurring patterns, and those patterns are clearer when sorted not by technology but by the assumption behind them.

① The assumption that defaults are safe (nothing was configured)

Defaults chosen for ease of development

detailed errors · admin surfaces reachable · broad permissions

↓ shipped unchanged

Shows internal details to anyone looking

structure, paths, versions and internal values become readable

A default is a value that is unobjectionable for everyone — not a value that is safe for your production.
What this shape looks like, and what to check
Debug output enabled in production
Do error pages expose environment variables, file paths or stack traces? Open a URL that does not exist and look at what comes back with your own eyes. Framework specifics live in the framework guides
Administrative surfaces reachable
Database management tools and admin consoles reachable from the internet. Do not rely on authentication alone — layer IP restrictions or network-level blocking
Headers unset, or copied from a stale list
See which headers still matter and which do not. A deprecated header can do harm if you add it
Weak storage left in place
Password storage as described in hashing and salting. "It's encrypted" is not a description of a storage scheme
Updates have stopped
Running a language, framework or CMS past its supported life. See machine-monitoring dependencies and what end of support actually means

② The assumption that unused things are harmless (nothing was closed)

More of your attack surface comes from things you stopped using than from things you built. Once something stops being used, it drops out of monitoring and review without anyone noticing.

What this shape looks like, and what to check
Secrets left in a public directory
.env, backups, dumps, config files. what must never sit in a public directory / placement on shared hosting
Storage still public
Turning blocking on does not delete the existing public policy. public buckets
Dangling DNS records
Delete a resource without the DNS entry and anyone can claim the name and take the subdomain. subdomain takeover
Registration and admin paths left open
Is open registration still enabled? Measure it over HTTP rather than reading the config (authentication vs authorization). Do not leave a guessable URL as the only thing "hiding" a page
Accounts you thought were cancelled
Cancelling a service and deleting the account are different, and data stays until you delete. when your hosting provider is breached
Old keys, tokens and permissions
Departed colleagues' accounts, tokens with no expiry, over-broad scopes. SSH keys and least privilege / password managers

Do not scope the inventory to what is running

Limit your review to "things currently in use" and this pattern cannot be found at all. Scope it to everything you ever created — subdomains, accounts, keys, buckets, staging environments, third-party subscriptions. Something you stopped using is still an asset until it is deleted. How to build the list: the asset inventory checklist.

③ The assumption that you would notice (no monitoring)

Damage is determined less by the breach itself than by how long it runs before anyone notices. And most environments have no mechanism for noticing.

The usual state

・Access logs exist but nobody reads them
・No audit log of authentication attempts (so "what was seen" cannot be reconstructed afterwards)
・Rate limits are configured but nobody can see when they trigger
・Public status is the composition of several layers, so no single one answers the question

The end state is being able to say only "we don't know" about whether anything happened.

The minimum worth having

・A notification on new user registration (one signal is enough to catch the odd one)
・A record of authentication successes and failures, with a retention period
・Machine monitoring of dependency vulnerabilities (people cannot track this → osv-scanner)
・A record of limit hits, and an alert on a spike (rate limiting and abuse control)

You do not need all of it. One working way to notice problems is what stops an incident from becoming a long one.

With no logs, the honest answer is "we don't know", not "nothing happened"

The most dangerous move in incident response is reading an absence of records as evidence that nothing occurred. With no records, the only supportable statement is "we don't know" — and in that case, proceed on the assumption of compromise and rotate whatever could have been exposed. The organisational minimum is in the organisational security baseline.

④ The assumption that validated input is safe

The real question about an input is not "is this value correct" but "how much have I let this input decide". The more decisions you hand over, the less validation can keep up.

Sorted by the decision you have handed outside
Only the value
Ordinary input. Checks on length, format and range work — the safe side
The structure too
Designs that accept a whole nested object and merge it. prototype pollution
The type as well
Formats that reconstruct objects. The attack succeeds before your value checks run. insecure deserialization
Where it lands
Uploads that end up somewhere they can be executed. file upload vulnerabilities
Who the request is
Trusting a request header to decide the client's identity. X-Forwarded-For spoofing and trusted proxies

Counting the decisions you have handed over shows you the dangerous places. And the underlying cause is usually the same: trying to solve in validation what should be solved in structure. Changing the format you accept is more reliable than adding another check.

Doing it in order

1

Look at how production actually appears (①)

A URL that does not exist, a request that errors, the administrative paths — request them over HTTP and look at what comes back. The point is to read the output, not the configuration. Headers can be measured in one go with the header scanner.

2

Write down everything you ever created (②)

Subdomains, accounts, keys, buckets, third-party services. The trick is not to filter by "still running". Build the list with the asset inventory checklist, and take unused entries all the way to deletion (not merely disabled).

3

Set up exactly one way to notice problems (③)

Trying to stand up complete monitoring usually results in none at all. Start with one — new-registration notifications, a spike in failed logins, or dependency vulnerability mail. One, including confirming it actually fires (monitoring that was configured but never verified is monitoring you do not have).

4

Count what your inputs are allowed to decide (④)

Write out whether external data decides only values, or also structure, type and destination. Anywhere it decides more than values is a high-priority place to change.

5

Make updates a mechanism (so ① does not come back)

The first pattern reliably returns if left alone. Putting dependency and framework updates under machine monitoring is the only realistic answer (getting started with osv-scanner / a practical CVE remediation playbook). A procedure that only exists in a document is the first thing skipped on a busy day.

This site's view: all four were true once

What the four have in common is that each was correct at some point. Defaults were reasonable during development; unused things genuinely were unused; while you were small you really would have noticed; and input validation has solved a great many problems. That is exactly why they go unexamined.

Our position is to periodically ask when a formerly correct assumption stopped being correct. That check is cheaper and more effective than adding more technology. And note the difference in kind: a checklist tells you what to do, but not why something was missed — and if the reason is unchanged, the same thing gets missed in the same place again.

FAQ

QWhere should I start with security?
A

Checking which of four patterns your own environment matches works faster than learning individual attack techniques. Are production settings still at their defaults? Is anything still open that you created and never closed? Would you notice if something went wrong? How much are you letting external input decide? This article gives the concrete checks for each and links to the deeper articles.

QDoes this apply to a small personal site?
A

The patterns are the same; the ordering changes. For an individual or a small team, the two that pay off first are checking defaults (is debug output enabled in production?) and inventorying what was never closed (secrets in a public directory, unused subdomains, dormant accounts). Observability needs machinery so it can wait — but even a single signal, such as a notification on new user registrations, dramatically shortens how long a problem goes unnoticed.

QHow is this different from a checklist?
A

A checklist tells you what to do; this is about why things get missed. Listing items does not help if the reason they were missed is unchanged — the same thing gets missed in the same place again. All four beliefs were true once, which is exactly why they survive unexamined. When you want the actual steps, follow the links to the checklist articles from each section.

QI only have time for one. Which?
A

Fix one thing in the third: being able to notice. The first two turn into incidents if ignored, but without the third you will not know an incident happened. Damage is decided less by the breach than by how long it runs unnoticed. Keep a log, add one notification, do one inventory a month: any of those is the single highest-return investment against an incident becoming a long one.