01 Client and server, and who you can trust
Every web interaction has two halves. The client is your browser, running on your machine. The server is someone else's computer, running their code.
The split matters enormously, and it produces the single most important rule in web security.
Anything the browser sends can be altered before it arrives. Hidden form fields, prices, user IDs, JavaScript validation, disabled buttons, all of it. If a check happens only in the browser, it is not a security control, it is a suggestion. This one sentence explains a large fraction of the vulnerabilities you will find in Phase 02.4.
02 The three languages in every page
You do not need to build websites. You need to recognise what each part does, because attacks target them differently.
| Language | Job | Why an attacker cares |
|---|---|---|
| HTML | Structure and content | Forms and inputs are where user data enters the system |
| CSS | Appearance | Can hide elements or overlay invisible ones for clickjacking |
| JavaScript | Behaviour in the browser | If an attacker runs their JavaScript in your browser, they act as you |
That last row is cross-site scripting, usually written XSS, and it is one of the most common web vulnerabilities in the world. The attacker's goal is to get their JavaScript to run inside someone else's session, at which point they can read the page, submit forms, and steal the session token.
03 The anatomy of a request
Lesson 00.4 showed you a request in outline. Now look at the parts properly.
POST /login HTTP/1.1 Host: shop.example.com User-Agent: Mozilla/5.0 Cookie: session=a3f9b2c8d1 Content-Type: application/x-www-form-urlencoded username=alice&password=hunter2
Four things are worth naming, because you will manipulate all of them later.
- The method says what kind of action this is.
GETasks for something,POSTsubmits something. Others exist, includingPUTandDELETE. - The path says which resource is wanted. Attackers manipulate this to reach things they should not, which is called path traversal.
- The headers carry metadata, including the all-important cookie.
- The body carries submitted data, here the login form.
A GET puts its data in the URL, which means it lands in browser history, server logs and referrer headers. A POST puts it in the body, which is not logged by default. This is why a password must never travel in a URL. It is not about encryption, since both are encrypted equally under HTTPS. It is about where the data gets written down afterwards.
Check yourself
A site sends a password reset token in the URL, like /reset?token=abc123. What is the risk?
Send some requests and read the replies. Notice how much a status code gives away.
04 Sessions: how a website remembers you
HTTP is stateless. Each request arrives with no memory of the last one. The server genuinely does not know that the request asking for your inbox came from the same person who logged in a moment ago.
Cookies solve this. When you log in successfully, the server generates a random session identifier, stores it, and sends it back. Your browser then attaches it to every subsequent request automatically.
the session token replaces the password on every later request
Notice what that means. After login, the token is the identity. Anyone holding it is you, as far as the server is concerned. No password required, and in most cases no second factor either.
The flags that protect a cookie
| Flag | What it does | What it prevents |
|---|---|---|
| HttpOnly | JavaScript cannot read the cookie | Cross-site scripting stealing the session |
| Secure | Only ever sent over HTTPS | Leaking the token over plain HTTP |
| SameSite | Not sent on requests from other sites | Cross-site request forgery |
A missing flag on a session cookie is a genuine, reportable finding on a penetration test. You will check for exactly this in Phase 02.4.
Check yourself
Why does the HttpOnly flag matter so much when a site has a cross-site scripting flaw?
05 The same-origin policy
Here is the rule that stops the web from being completely broken. A page from one origin cannot read data from a different origin.
An origin is the combination of scheme, domain and port. All three must match.
| Compared with https://shop.com/page | Same origin? | Why |
|---|---|---|
| https://shop.com/other | Yes | Only the path differs, which does not matter |
| http://shop.com/page | No | Different scheme |
| https://mail.shop.com/page | No | Different subdomain is a different domain |
| https://shop.com:8443/page | No | Different port |
Without this rule, a malicious page you opened in one tab could quietly read your bank account in another. The same-origin policy is why it cannot.
Sometimes a site genuinely needs to let another origin read its data, for example an API serving a front end on a different domain. Cross-Origin Resource Sharing is the mechanism for granting that, using response headers. Misconfigured CORS that permits any origin is a common and serious finding, because it hands away the protection the same-origin policy provides.
06 APIs, where the real data lives
Modern sites often serve a nearly empty page and then fetch the actual data separately, as JSON, from an API. That means the interesting traffic is frequently invisible in the page source and only shows up in the network panel.
GET /api/v1/users/1042/orders HTTP/1.1 Host: shop.example.com Authorization: Bearer eyJhbGciOiJIUzI1NiIs...
Look at that path. It contains 1042, a user ID. The obvious question, and it is the right question, is what happens if you change it to 1043.
If the server returns someone else's orders, that is insecure direct object reference, usually shortened to IDOR. It is one of the most common and most damaging web flaws precisely because it is so simple. The server authenticated you, but forgot to check whether you are authorised for this specific record.
Proving who you are and being allowed to see a particular thing are two separate checks. IDOR happens when a developer does the first and forgets the second. You will exploit this in Phase 02.4 and it is covered from the defensive side in lesson 01.3.
07 Do it on your real machine
Your browser contains a full inspection toolkit. Open developer tools in Safari or Chrome with Command + Option + I. In Safari you may first need to enable the Develop menu in Settings under Advanced.
Try this on this very page, which is served from your own machine so there is nothing to worry about:
- Open the Network tab, then reload. Every file the page requested is listed, with its status code and size.
- Click any request and look at the headers, matching them to section 03 above.
- Open the Console tab and type
document.title, then press Enter. You just ran JavaScript inside the page, which is exactly what an XSS attacker wants to achieve. - Open the Storage or Application tab and find Local Storage. Your lesson progress is stored there.
Now from the terminal. Fetch only the response headers:
curl -I https://example.com
See the full request and response including the TLS negotiation:
curl -v https://example.com -o /dev/null
Send a request with a custom header, the way a tool would:
curl -H "User-Agent: MidorCyber-Learning" -I https://example.com
Fetch some JSON from a public test API and look at the structure:
curl -s https://api.github.com/zen
Requesting a public page or a public API is ordinary internet use. Changing an ID in someone else's URL to see another person's data is unauthorised access, even when it is trivially easy and even if you report it afterwards. Practise IDOR on the deliberately vulnerable applications you will set up in lesson 00.8, never on a live site.
Your checklist
- Can explain why client-side checks are not security controls
- Can name the four parts of an HTTP request
- Understand why a secret in a URL leaks even under HTTPS
- Know what the HttpOnly, Secure and SameSite flags each prevent
- Can decide whether two URLs share an origin
- Opened dev tools and inspected the network panel on this page
- Ran JavaScript in the console and saw local storage
- Can describe IDOR in one sentence
08 Final check
Question 1 of 3
A shopping site validates the price in JavaScript before submitting the order. Why is that insufficient?
Question 2 of 3
You are logged into your bank in one tab and open a malicious page in another. What stops that page from reading your bank balance?
Question 3 of 3
An API returns your profile at /api/users/1042. Changing it to 1043 returns another user's profile. What is the flaw?
The client is untrusted territory and only the server can enforce a rule. A request is a method, a path, headers and a body. Sessions turn a token into your identity, which is why cookie flags matter. The same-origin policy keeps tabs apart. And authentication without authorisation produces IDOR. Phase 02.4 attacks every one of these.
✓ Key takeaways
The things from this lesson worth carrying into the next one. If you remember nothing else, remember these.
★ Carry these forward
- The user owns the client and can edit it, disable it, or skip the page and send a crafted request. Only the server can enforce a rule.
- HttpOnly stops JavaScript reading the cookie, so XSS cannot steal the session. Secure sends it only over HTTPS. SameSite blocks cross-site request forgery.
- It stops one page reading another origin's data. An origin is scheme, domain and port, and all three must match, so http differs from https and subdomains differ.
- Insecure direct object reference, an authorisation failure. The server authenticated you correctly but never checked that you may see that specific record.
⚑ Keep going
You have read it and tried it in the lesson. Now cement it. These three do more for retention than re-reading ever will.