What is web security?
Web security is the work of making sure a website only does what its owner meant it to do, for the people it was meant for. A bakery's site should show the menu, take orders and let customers leave comments. It should not let a stranger read other customers' details, change the prices, or use the comments box to run code in everyone else's browser.
Most of that work happens in ordinary places: the line of code that puts a comment on the page, the settings on the cookie that keeps someone signed in, a few headers your server sends with every page. Secure sites are mostly built from dozens of small, boring choices made carefully. A special security product bolted on afterwards rarely makes up for them.
This course teaches those choices for total beginners. You will not learn how to break into anyone's site. You will learn how the common attacks work in outline, so you can recognise the weak spot in your own code, and then you will close it and watch the same attack fail.
What does an attack actually look like?
An attack is usually a normal-looking request with something unexpected inside it. A comment form expects a sentence like Lovely rye, still warm at 9am. An attacker types a sentence that contains a scrap of HTML instead, for example <img src=x onerror="steal()">. If the server pastes that text into the page as it was typed, the browser reads it as code, tries to load an image called x, fails, and runs steal().
Nothing about that request is clever. It goes through the same form every customer uses. The weakness is entirely on the site's side: one place in the code trusted visitor text as if the owner had written it. That pattern, trusting input that came from outside, sits behind most of the attacks in this course.
In the task above you ran exactly that attack against the bakery's comments page. The Attacker view told you it got through and named the line in server.js responsible. That direct link between an attack and a line of your own code is what makes security fixable.
Why would anyone attack a small bakery's site?
Most attacks are not aimed at anyone in particular. They come from automated programs, often called bots, that visit millions of sites and try the same few tricks on each one. A bot does not care that Crumb and Crust sells cinnamon buns. It cares that the comments box accepts HTML, or that the sign-in page lets it guess passwords all night.
What the bot gains varies. A script running in visitors' browsers can show fake sign-in forms, redirect people to scam pages or fill the site with spam links. A guessed password can be tried on the member's email account too. A database of email addresses can be sold. Small sites get caught because they are numerous and often unattended.
The useful conclusion is a calm one. You do not need to outwit a determined genius. You need to avoid the handful of well-known holes that automated tools look for, and this course covers each of them.
What is the attack lab on this page?
Every lesson in this course includes a pretend website made of a few small files, shown as tabs above the editor. server.js holds the routes, the bits of code that answer each address. headers.txt lists headers sent with every page. site.conf holds simple settings such as whether HTTPS is on. Later lessons add .env, .gitignore and package.json.
On the right are four views. Page shows roughly what a visitor sees. Attacker lists every pretend attack, each with a Try it button. Network shows the requests and responses travelling between browsers and your server. Report shows which defences are switched on and what each attack did. All four update as you type.
The attacks are deliberately simple and safe. Each payload is a toy string, nothing leaves this page, and the same files always give the same result. The lab reads your files with simple rules instead of running a real server, so it can miss unusual code that a real attacker would find. When the lab says blocked, read it as good evidence, not a guarantee.
- Page: what a visitor sees, including the padlock and how a comment is shown.
- Attacker: the pretend attacks, with the reason each one worked or failed.
- Network: requests, cookies and headers, as they cross the network.
- Report: every defence, on or off, and what it stopped.
Why did the comment run as code?
A web page is a single piece of text that the browser reads from top to bottom. When the bakery's server builds the comments page, it glues together its own HTML and the customers' comments into that one text. The browser has no way to tell which characters came from the owner and which came from a stranger. If a comment contains <img, the browser sees the start of an image tag.
Escaping fixes this by changing the few characters that have a special meaning in HTML into harmless stand-ins. < becomes <, > becomes >, & becomes & and quotes become " or '. The browser displays those stand-ins as the original characters, so the comment reads exactly as typed, but it can never start a tag.
In server.js the bakery already escaped the customer's name with escapeHtml(c.name), which comes from the small escape-html package. The comment text was the one gap. That is very typical. Real holes are rarely a whole site with no defences; they are one field someone forgot.
const list = rows.map((c) =>
`<li><b>${escapeHtml(c.name)}</b> ${escapeHtml(c.text)}</li>`
).join('');

What does blocked really mean?
When an attack shows a tick in the Report view, it means that particular trick failed against your files as they are now. It does not mean the site is safe from everything. Security is a set of separate walls, each covering a different gap, and most of the time several of them help with the same attack.
For cross-site scripting there are at least three walls. Escaping stops visitor text from becoming code. A Content Security Policy, which you meet in a later lesson, tells the browser to refuse inline scripts even if one slips through. The HttpOnly flag on a login cookie stops a script from reading it. Any one of them helps; together they cover each other's gaps.
Professionals call this defence in depth. The sound habit is to fix the root cause first, which here is the missing escaping, and then add the extra walls. A header that blocks scripts is welcome, but it should never be the reason you leave a field unescaped.
How do you start thinking like a defender?
Begin with one question for every piece of your site: where did this data come from, and who could have changed it? Anything that arrived from a browser, such as form fields, the address, cookies and uploaded files, could have been written by anyone. Treat it as untrusted until your code has checked it or made it safe for where it is going.
Next, ask what happens if a stranger sends something you did not expect. A comment of 50,000 characters, a price of 0.01, a quote mark in a name like O'Neill. Most security bugs are ordinary bugs that a stranger can trigger on purpose.
Finally, look for the boring settings. Is HTTPS on? Do cookies have the right flags? Are keys kept out of the code? These checks take minutes and stop a large share of the automated attacks that hit small sites every day. The last lesson of the course turns them into a checklist you can reuse.
What do AI tools get wrong about web security?
AI assistants write a lot of web code now, and they often produce the vulnerable version because it is shorter and it works in a demo. A request like "show the latest comments on the page" commonly comes back with visitor text dropped straight into a template string or innerHTML, with no escaping at all. The page looks fine until someone types a tag.
They also tend to describe security in vague terms, telling you to sanitise input or follow security guidelines without saying which characters, in which place, with which function. When an assistant gives you code that shows visitor text, check every place a value goes into HTML and ask what would happen if that value contained <. If the answer is unclear, ask the assistant directly whether the output is escaped, and test it here in the lab.
Field notes
- Web security means your site only does what you meant, for the people you meant it for.
- An attack usually looks like a normal request with something unexpected inside it.
- A comment ran as code because the page put visitor text into HTML without escaping it.
- Blocked means the browser or server refused the trick, so the attacker got nothing back.
Easy to get wrong
Visitor text placed straight into HTML can contain tags. Escaping turns < and > into harmless characters, so the comment shows as text.
Attackers use whichever field you forgot. Names, search terms, email addresses and even the page address all come from the visitor.
Headers help, but they depend on the browser and on being set correctly. Escaping removes the problem at its source.
Questions people ask
Is the attack lab safe to use?
Yes. The site, the attacks and the network are all pretend and run inside this page. Nothing is sent anywhere, and the payloads are toy strings that only make sense to the lab.
Do I need to know how to code?
A little HTML helps. The lab files are short, and each lesson tells you which line to look at. You will mostly be changing a word or adding a setting, then watching what that does to each attack.
Will this course teach me to hack websites?
No. It explains attacks only as far as you need to recognise and fix them in your own site. Testing someone else's site without permission is illegal in most countries.
Is any site completely secure?
No, and nobody serious claims so. The goal is to close the well-known holes, keep software up to date, and limit the damage if something does go wrong. That stops most of the automated attacks that small sites face.