Platform

Platform overview How it works Authorization testing Evidence & reports Private scanning Integrations

Solutions

Security agencies Product teams Regulated industries Partner programme

Learn

Blog Knowledge hub Compare

Resources

Pricing Documentation Help centre FAQ Security & data What we haven’t proved

Company

About Contact Careers Sign in to the platform Start a $199 pilot →

Home / Knowledge hub / Second-order injection

Knowledge hub

Second-order injection

Malicious input stored safely at first, then run later when another part reads it.

Illustration explaining Second-order injection

What it means

In a normal injection, the attacker's input does harm in the same request. Second-order injection splits it into two steps. First the input is saved, and it is handled safely at that moment. Later, a different part of the app reads it back and uses it in a way that treats it as code or a command.

The input is trusted the second time because it came from your own database. That is the mistake. Data is only as safe as the place it originally came from, and that was a visitor. That is why the flaw hides so well.

Why it matters

It defeats the usual checks. Testing the form that stores the value shows nothing wrong, and the part that runs it may be an admin screen, a nightly report or an export that nobody linked to the original form. Damage lands somewhere unexpected, often with higher privileges than the visitor ever had.

A classic case is a name saved with a quote and SQL fragment in it, stored using a safe query, then pasted into a string-built query by a report job. It is the same family as SQL injection and stored XSS.

How it shows up

You meet it wherever stored data is reused: profile names, addresses, comments, ticket subjects, file names, and values copied into logs, emails, PDFs or batch jobs. Look for places where a saved value is concatenated into a query, a command, a template or a page.

The fix is the same as for any injection, applied to every read as well as every write. Use parameterised queries everywhere, encode output for the place it lands, and treat database content as untrusted input. Testing needs a long path: store a harmless marker, then follow it to every place it shows up.

Questions people ask

Second-order injection, answered

Why do scanners miss second-order injection?

Because the response to the request that stores the value looks normal. The effect shows later, on another page or job, and a tool that only reads the immediate response never connects the two.

Following the stored value is the key.

Is stored XSS second-order too?

In a sense, yes. Stored XSS saves the payload and runs it later when another person views the page. The term second-order is more often used for SQL and other back-end injection.

The pattern is the same: store now, run later.

Does escaping on input fix it?

No. Escaping when you save protects only that one use. Stored data will be used in many places, each needing its own treatment.

Handle it at the point of use.

Which parts of an app are most exposed?

Admin tools, reports, exports, search indexing, email templates and background jobs. They read stored data and often run with more power than the public pages.

They are also less often tested.

How do we test for it?

Store a harmless, unique marker in each field, then trace where it reappears. In each place, check whether special characters are handled safely.

With the code available, tracing is much quicker.

Cyberlop mark

Where does your stored data end up?

In white-box mode we read the code to follow stored values to the places that reuse them, then prove the ones that run. Each finding shows the request and the line. Book a pilot on one app.

Or start with a $199 pilot on one application: thirty days, success criteria agreed before day one, credited against the annual if you convert.