SQL InjectionOut-of-Band

Out-of-Band SQL Injection: Confirming a Blind Flaw Through DNS

When a response offers no usable signal, a database-initiated DNS or HTTP callback can confirm SQL execution out of band. Learn the prerequisites, safe correlation model, and layered defenses.

SelfSec Team5 min read
Part 4 of 8from theSQL Injectionseries
xp_dirtree '\\ssec-lab.assessment.example\x'

At a glance

CWE-89
Interpreter
SQL database engine and outbound network resolver
Required condition
The query is injectable and the database can initiate observable DNS or HTTP traffic.
Potential impact
Data can leave through outbound requests even when responses reveal nothing.
Primary defense
Parameterized queries, least privilege, and tightly restricted database egress.

Safe practice: use benign proof only, in a disposable local lab or on a system you are explicitly authorized to test.

On this page

Boolean and time-based blind injection extract data one bit at a time, and they are slow. Sometimes they are worse than slow — a heavily cached page, an aggressive WAF, or a flaky network can make the true/false signal unreliable enough that inference stalls. When the response is fully blind and there is no UNION echo to lean on, there is still another channel: make the database server itself reach out to a host you control, and smuggle the stolen value inside the DNS or HTTP request it sends.

This post covers how out-of-band (OOB) SQLi works, the engine and network prerequisites, and how a unique fixed marker can confirm the channel without placing database content in the callback.

When this technique applies

OOB confirmation needs more than injection. The database must expose a network-capable function in the current context, the application account must be allowed to call it, outbound DNS or HTTP must leave the database network, and the assessor must control an authorized callback service that records a unique correlation token.

If no callback arrives, that does not prove the query is safe. Egress may be blocked, name resolution may be cached, the function may be unavailable, or the injected context may not permit the call. OOB is one evidence channel, not a universal test.

How it happens

The root cause is the same concatenation that enables every other class of SQLi. What makes OOB possible on top of that is a database that exposes functions capable of touching the network or the filesystem — and a query whose result the attacker never sees. Consider a reporting endpoint that returns nothing to the page on success:

$id = $_GET['report_id'];
$db->query("SELECT * FROM reports WHERE id = '$id'");

echo "Report queued.";

The page gives no usable signal, so UNION and boolean inference are out. But if the attacker can append a function call that forces the server to resolve a hostname they own, the data leaves through DNS regardless of what the page shows.

A safe proof: a fixed marker in the hostname

In an authorized lab, assign the probe a random token such as scan-7f31 under an assessment-owned domain. On Microsoft SQL Server, a permitted call that touches a UNC path can cause Windows to resolve the hostname:

'; EXEC master..xp_dirtree '\\scan-7f31.assessment.example\x' --

If the database host resolves scan-7f31.assessment.example and the authoritative callback log records that exact token after the probe, the observation links the HTTP request to database-side network activity. The hostname contains no selected value. Oracle deployments may expose controlled network packages such as UTL_INADDR, subject to database network ACLs:

' || UTL_INADDR.get_host_address('scan-7f31.assessment.example') || '

On a Windows-hosted MySQL deployment with the necessary filesystem behavior and privileges, a fixed UNC path may also trigger name resolution:

' UNION SELECT LOAD_FILE('\\\\scan-7f31.assessment.example\\x') -- -

Blind inference waits for the page to answer. OOB confirmation correlates the web probe with a separate network observation made by the database environment.

Why it beats blind

The advantage is separation from the application response. Boolean testing needs a stable page difference, while timing testing competes with latency noise. An OOB observation can arrive after the HTTP response and carries a high-entropy correlation token that is unlikely to occur accidentally. Real attackers may try to place data into that channel, which is why database egress is a security boundary; an authorized proof should not do so.

That last point is also the seam. OOB depends on egress: if the database server cannot resolve external names or open outbound connections, the channel goes dark.

The fix: parameterize, then cut egress

The injection has to be closed at the source, the same way as every other variant — bind input as a value so there is no query text to break out of:

using var cmd = new SqlCommand(
    "SELECT * FROM reports WHERE id = @id", connection);
cmd.Parameters.Add("@id", SqlDbType.Int).Value = reportId;

With a parameter, the xp_dirtree payload is just a (failed) lookup of a literal id — there is no statement boundary to append to. Then defend in depth specifically against the OOB channel: a production database server has no business making arbitrary outbound DNS or HTTP requests, so apply an egress firewall that denies it. Run the database under a least-privilege account, deny unnecessary EXECUTE permission on SQL Server extended procedures such as xp_dirtree and xp_fileexist, and restrict Oracle network packages such as UTL_HTTP, UTL_INADDR, and DBMS_LDAP. Defence in depth means even a missed injection cannot phone home.

Evidence and false positives

  • Give every probe a new random token and record its creation time.
  • Ignore generic shared hostnames that could be resolved by unrelated systems.
  • Account for DNS caching and asynchronous job delays.
  • Confirm the observed source and protocol match the authorized target environment.
  • Repeat with a fresh token only when operational limits permit it.
  • Treat an absent callback as inconclusive, not proof of safety.

How SelfSec finds it

SelfSec's SQL injection engine covers 19 database families with error-based, boolean, time-based, UNION, stacked and out-of-band techniques. For OOB it provisions a unique callback host per probe and applies the engine-correct trigger — xp_dirtree and xp_fileexist UNC paths on MSSQL, UTL_HTTP/UTL_INADDR/DBMS_LDAP on Oracle, and LOAD_FILE on compatible Windows MySQL deployments — then watches for the correlated DNS or HTTP interaction. Each finding comes with a reproduction request you can replay. Core scan processing runs locally on 127.0.0.1; managed OOB confirmation uses the documented remote callback flow when enabled.

References

SelfSec is intended strictly for authorized security testing of systems you own or are explicitly permitted to assess.

Do both things about SQL Injection

SelfSec covers this class from both sides — the scanner confirms it in your own app, the firewall blocks it in front of your origin while the fix ships.

The SQL Injection series

  1. 01OverviewSQL Injection, Explained: From Login Bypass to Full Data Extraction6 min
  2. 02Boolean-Based BlindBoolean-Based Blind SQL Injection: Extracting Data One Bit at a Time4 min
  3. 03Error-BasedError-Based SQL Injection: Turning Database Errors Into Data4 min
  4. 04Out-of-BandOut-of-Band SQL Injection: Confirming a Blind Flaw Through DNSReading
  5. 05Second-OrderSecond-Order SQL Injection: When Stored Input Detonates Later4 min
  6. 06Stacked QueriesStacked Queries: Running Multiple Statements Through One Injection4 min
  7. 07Time-Based BlindTime-Based Blind SQL Injection: Reading a Database Through the Clock5 min
  8. 08UNION-BasedUNION-Based SQL Injection: Appending Your Own Result Set4 min

Related reading