Preventing leaks and injections in your database

So, your web or mobile application (front-end) has a backend, which includes a database of some kind. Front-end both consumes the data from backend and generates new data to store there. Frequently, data in the backend is a target for malicious attacks to steal or modify sensitive pieces of information. But normally backend is protected, and the only attack vector available for malicious actions is front-end itself.

Your modern app layout, clean and simple

There are many traditional techniques in protecting the data. We wrote a very high-level overview series in our blog some time ago (see More reading section). However, most of them involve both performance penalties and limited scope of protection for the data at the same time.

This post is about something else — several interesting techniques we’re using for detecting intruders in Acra, our open-source database protection suite.

Front app under attack!

No matter what kind of authentication or encryption you have between your front-end and remaining parts of the system, you have to trust your front-end to let it get the data. Any request it sends with correct authentication parameters, database has to serve.

But what if your front-end application gets exposed in a way in which attacker is able to alter execution or data request flow?

How about forgetting to filter quotes?

If you trust your application and its credentials, you will serve all of its requests, no matter how malicious they are.

Let’s introduce a Watchdog

Now, all traffic passes through the Watchdog node

Watchdog is a network proxy server, that sits between your app and your database, and controls all data stream. If the infrastructure behind the app was not compromised and only front-end is under attack, the only way for attackers to get the data they’re after is sending malformed requests through this Watchdog.

But apart from just enforcing access policy, it can filter correct requests and deny access for the obviously malicious ones.

So, what does such Watchdog proxy do? Try to detect anomalies and, specifically, all large-scale selects, not typical for an application flow. Then such proxy, based on threat level, either shuts down database access or generates notification events for monitoring/IDS.

Like the idea? Acra is such watchdog, additionally providing cryptographic services, focused on selectively and flexibly protecting only sensitive parts of the data you store.

What kind of bad requests should we detect?

All typical payloads for SQL Injections:

  • Inserts, targeting authentication data
  • SELECT *
  • Command execution
  • Grant rights
  • Denial of service attacks
  • Typical signatures of escaping payloads to execution on database side

Detection methods

Detection sounds simple — we should just look at the traffic that passes through Watchdog and match it against some rule. But SQL injections are not binary simple arrays of bytes with pre-determined signatures, which are easy to spot. There are different methods you can use to efficiently scan the database request traffic:

Query templates

Simple, flexible method of detecting suspicious behavior is matching SQL requests against some list of patterns. Although effortful in filling the list with possible / typical attack vectors for your particular data flow, matching queries against a list of typical injections is an efficient way to spot most unsophisticated attempts at scale, early.

Poison records

A classic design used to prevent SELECT *-type injections, poison record is a way to detect massive requests to the database. Designing your DB requests yourself or at least enumerating the ones your ORM generates allows you to understand, which tables with sensitive data are never accessed via requests with full scan requests. You can store a special record, a tag, in this table, which, when passing the Watchdog, triggers the alarm.

Query enumeration

—Let’s try injecting this way… 
 — Hmm, nah, doesn’t work
 — What about that way of escaping magic quotes?

Most processes of finding and exploiting the bugs relies on try-fail-try again cycle, in which attacker generates a lot of broken queries. Some of them will contain typical signatures, but overall they will increase the number of bad queries to the database.

While detecting these signatures is hard, detecting a sudden increase in empty/syntax error responses from the database is fairly easy.

There’s more to that

One of the interesting challenges we are pursuing right now is being able to detect abnormal (compared to regular request flow) behavior via ML-trained classifier.

What if…

attacker mounts an attack, which is indistinguishable from normal application behavior?

If the attacker is able to reverse engineer the regular data flow and emulate it in a way, in which you will not be able to distinguish his behavior from the normal app behavior, he will pass your watchdog.

But there are both statistical and ad-hoc techniques to fight that: stay tuned for more in our blog.

More reading

Three articles on classic and modern patterns in database defenses: