click the screen · press Enter
← back to blog
Web & API · Topic 1

Injection Attacks Explained: Beyond SQLi

Injection attacks explained, beyond SQLi - Web and API

Injection is the oldest trick in the web hacking book, and it still works. It's been sitting near the top of the OWASP list of the worst web risks since 2003, which is a long time for a bug class to stay dangerous. Everyone's heard of SQL injection. What fewer people talk about is that the exact same flaw hides in corners nobody thinks to check, and those corners are where the easy wins are.

This is the start of my Web & API track, so I'm keeping it as an introduction: what injection actually is, and a tour of a few less-famous flavours. No exploit walkthroughs today, just the idea, clearly. Get the idea and the attacks all start to look like the same trick wearing different clothes.

What "injection" actually means

An injection bug is when an app takes something you typed and mixes it straight into a command or a query, and then some interpreter runs the whole lot. Your input was supposed to be plain data, a username, a search term. But because it's glued into a string that gets executed, part of it can escape being "data" and start being read as "instructions". At that point you're not filling in a form any more. You're partly writing the app's code for it.

That's the whole thing, and it's worth saying in one line: injection is what happens when data crosses the line into code. Every injection attack, no matter how exotic it sounds, is a version of that same mistake, input that should have stayed inert got treated as commands.

01
You type

input meant to be plain data

02
App glues it in

your text is dropped into a query or command string

03
Interpreter runs it

the database, directory or OS executes the string

04
Data becomes code

your input changed what the app does

One root cause, every time: untrusted input ends up where the app expects trusted code.

The three everyone already knows

Before the interesting ones, a quick nod to the household names. If you've read any web security at all, you've met these:

SQL Injection

Malicious input reaches a database query, letting an attacker read, change or dump data.

Command Injection

Input reaches an operating system command, so the attacker can run commands on the server itself.

Cross-Site Scripting

Input reaches a web page as script, so attacker JavaScript runs in another user's browser.

Different interpreters (database, OS shell, browser), same underlying flaw.

Here's the twist that makes the rest of this post worth reading. These three are so well known that modern frameworks quietly defend against them by default. Developers watch for them. So attackers do the sensible thing and go looking where nobody's watching. That's a modern cousin too: large language model apps have their own version called prompt injection, same root idea, brand new attack surface. Let me show you three of the classic-but-overlooked ones.

XPath injection: SQL's forgotten cousin

Some apps don't use a database. They store data in XML, a text format that holds information in nested tags. To search that XML they use XPath, a query language for XML that plays the same role SQL plays for databases. And where there's a query language built from user input, there's injection.

Picture a login that checks your details against an XML user list. The query it builds looks something like this:

//users/user[username='admin' and password='hunter2']

See where the username and password are dropped straight into the query text? If the app doesn't carefully separate your input from the query, a crafted username can change the logic of that query rather than just filling in a value, for example turning the password check into a condition that's always true. Done right, the effect is the same as SQL injection: authentication bypassed, or the whole XML document coughed up. No database doesn't mean no injection. XML plus XPath has the exact same weak spot.

LDAP injection: attacking the directory

LDAP (Lightweight Directory Access Protocol) is how apps talk to a directory service, the address book of an organisation. The big one is Microsoft Active Directory, and loads of web apps log you in by checking your credentials against it over LDAP.

To do that check, the app builds an LDAP search filter with your input in it. A simple one looks like this, matching a user whose id and password fields line up:

(&(uid=singh)(password=Password123))

LDAP filters have their own special characters and syntax, just like SQL does. So if the app pastes your input in without treating those characters carefully, an attacker can bend the filter, potentially logging in as someone they shouldn't, or pulling back directory entries they were never meant to see. Why this one stings: the target is often the identity system itself. Get injection here and you're meddling with the thing that decides who's allowed in.

HTML injection in PDF generators: the sneaky one

This is my favourite of the three, because it's so easy to miss. Tonnes of apps generate PDFs, think invoices, reports, tickets, by building an HTML page behind the scenes and handing it to a library that renders that HTML into a PDF. Your name, your order details, all dropped into the HTML template.

So an invoice template might be:

<h1>Invoice</h1><p>Customer: [ your name goes here ]</p>

Now, what if "your name" isn't a name but a chunk of HTML? If the app doesn't clean it, the PDF renderer will happily process whatever markup you supplied. And here's the kicker: that renderer often runs on the server with more power than a browser tab. Depending on the library, injected markup can push it into two nasty places:

  • SSRF (Server-Side Request Forgery): you trick the server into making web requests on your behalf, often to internal systems it can reach and you can't.
  • LFI (Local File Inclusion): you get it to read files off the server's own disk, the classic prize being something like /etc/passwd.
Why this is worse than it looks A plain HTML injection in a web page is usually a browser-side problem. The same bug in a server-side PDF renderer moves the damage onto the server, and a "cosmetic" flaw quietly becomes file disclosure or a pivot into the internal network. The reach is the same idea as the parser bug behind CVE-2026-8451: trusted input assumptions, broken.

The common thread (and the fix in one idea)

Line these up and they're the same story three times. XML and XPath. A directory and LDAP. An HTML template and a PDF engine. In each one, user input got mixed into something an interpreter later executed, and nobody kept the two apart.

SAME ROOT CAUSE
XPath · input meets an XML query
LDAP · input meets a directory filter
HTML-to-PDF · input meets a renderer
SQLi / XSS · the famous versions
Learn the pattern once and you can spot injection anywhere a query or command is built from input.

Which means the defence is one idea, applied everywhere: keep data and code apart. Don't build queries or commands by gluing strings together with user input. Use the safe, parameterised way your language gives you so input can only ever be a value, never syntax. Where you must place input into a specific context (HTML, XML, a filter), escape it for that context. Validate to an allowlist of what's actually expected. And give the component the least power it needs, so if something does slip through, the blast radius is small. You don't need a different mental model for each injection type. Treat all input as untrusted data, and never let it become code.

One idea, not a list of tricks

The thing I want to hammer home, mostly to myself, is that "injection" isn't a list of separate tricks to memorise. It's one bug with a hundred outfits. Once I started reading it as "did untrusted input end up somewhere it gets executed?", the obscure variants stopped feeling obscure. I'm still building intuition for the HTML-to-PDF ones, the exact conditions that turn a rendering quirk into SSRF or file read vary a lot by library, and I want to understand that properly before I write more on it. Next in this track I'll pick one of these and go deeper, probably with a proper lab. If you've hit an odd injection in the wild, an interpreter nobody expects to be attackable, tell me, those are the ones I find most interesting.

If this was a useful primer, come say hi on LinkedIn or the contact page, and tell me which injection type to break down first. This is the opening post of the Web & API track, so there's a lot more coming.

Further reading

FAQ

What is an injection attack?

An injection attack happens when an application mixes untrusted user input into a command or query and an interpreter runs it. The attacker's input stops being treated as plain data and starts being treated as code, letting them change what the application actually does.

What are some injection attacks other than SQL injection?

Beyond SQL injection there is XPath injection (against XML queries), LDAP injection (against directory lookups like Active Directory), and HTML injection into PDF generators, which can escalate to SSRF or local file reads. Command injection and cross-site scripting are also injection classes.

Why do injection vulnerabilities still exist?

Frameworks now defend the famous ones like SQL injection well, so developers focus there. The lesser-known variants, XPath, LDAP, HTML-to-PDF, often have no built-in guardrails, so they get overlooked and stay easy to exploit without any advanced bypass.