Poison Records in Acra
When naming our special type of data containers created for raising an alarm within Acra-powered infrastructures, we were sure we’ve seen the term “poison records” used elsewhere in the same context. This particular technique in out of the box solution was first offered by us (if it wasn’t, let us know! We'd like to know more about their backstory :)).
In a way, poison records are very much like passive honeypots, but their mechanics of work is completely different. Here is a description of what poison records are, what they do, and how to create and use them to protect your database.
Poison records are records specifically designed to sit quietly in the database and not be queried by legitimate users under normal circumstances. They resemble regular records and fit in seamlessly with other data. Technically speaking, poison records is data (binary or strings, int, or whatever suits your database design), placed in particular tables / columns / cells.
However, poison records will only be included in the outputs of suspicious requests from malicious applications that read more data than they should, i.e. using SELECT * requests. The sole purpose of these requests is that when an unauthorised leakage occurs, they’ll be present in it and detected through:
● Trigger on a specific cell in a table. Applying trigger function to a poison record will trigger pre-programmed database reaction, from raising some alarm signal to shutting down the database responses completely. This approach has plenty of trade-offs: these triggers alter the table processing logic and require proper maintenance.
● Putting all database traffic through some proxy, which acts as DLP fingerprint scanner.
We’ve implemented the second approach in our database security suite, Acra. Let’s see how exactly it works.
After a “leaky” request, database responses containing poison records will be detected by a database proxy.
Upon passing through
A database proxy is an intermediary server handling requests from the app to the client and vice versa, acting as a helpful benevolent man-in-the-middle. Proxies originally were created to add structure and encapsulation to distributed systems (and we suggest the use of an encryption proxy as a means for providing better backend security).
Acra, our take on database security, sits between the application and the database, passes requests into the database, verifies and decrypts database responses, then passes plaintext output to the application, enforcing transport security in between. You can read more about Acra’s architecture and data flow here (but it’s not entirely necessary to understand this approach in general).
The goal of using poison records for detecting leaks on a proxy is to detect intruders trying to download the full database content through consumer application or trying to run a full scan using SQL injections.
In our implementation, poison records are flawed AcraStructs (cryptographic data envelopes Acra operates on), encrypted with a special Poison record key, unlike the encryption keys used for regular “normal” records. The chance of generating such record randomly is incredibly small; the chance of such data structure emerging in proper application-generated content is even less probable.
If an app is badly compromised (through an SQL injection or alteration of the application flow) in an Acra-powered infrastructure, AcraServer — as the only entity that decrypts the sensitive data and sees all the requests addressed to it — will be the one responsible for telling the legit behaviour from malicious, and for taking an appropriate action. Poison records allow detecting the illegitimate behaviour.
AcraServer’s key storage contains a special poison record private key, which is used for recognition of poison records. Acra provides a special utility for generating poison records and keys — AcraPoisonRecordMaker. As database owner, you might generate as many poison records, as you wish, and put them into the database.
How to use poison records?
Besides Acra (which is open source), poison records can also be monitored by the middleware of the app itself, using the DLP-instruments, and via traffic inspection. All of these approaches have their unique merits and trade-offs, but they all share a common approach:
The effective implementation of poison records in your database comes down to these points:
● Making sure that your system can generate a unique poison record and tell a poison record from a normal one to avoid false-positives. The difference shouldn’t be obvious, i.e. don’t use strings like “I’m a poison record”. It’s better to generate data that has length and structure similar to any other data in the particular table.
● Making sure that the poison records you are putting into your database are impossible to (accidentally) query through a legitimate request by an authorised user.
● Setting an alarm system in place to recognise and take appropriate pre-defined action if poison records are queried and recognised in a query by any means you use to inspect the database responses.
What can you do upon detection of a poison record? We’ve seen various schemes in the wild, the ones we chose to implement in Acra are:
● Shut down the processing completely. This is useful for high-value databases with very reliable application structure around. Very problematic for 24/7 services with high SLA or availability risk. Moreover, in a distributed environment, shutting down one proxy instance does not mandate shutting down all of them and the attacker might try again. And again, improving their SQL over time.
● Raise a security alarm/notification. Generate an appropriate log, monitoring metrics or security event in SIEM — active “push” pattern for monitoring and events.
● Only log the event. Systems with centralised security controls elsewhere would collect these problematic events on their own and performance-wise it’s cheaper to simply accumulate the logs until the sensors in the “pull” monitoring model come back to pick the logs up.
Poison records in Acra: a primer
To get acquainted with Acra and run a basic demo environment in which you can try poison records, you can launch our educational docker image using the following instructions.
Poison records are generated by a special utility –
For example, you can run AcraServer with MySQL database:
$ docker-compose -f docker/docker-compose.mysql-nossl-server-ssession-connector.yml up $ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES fa5c8a717f82 cossacklabs/acra-webconfig:master "/acra-webconfig -st…" 5 minutes ago Up 5 minutes 0.0.0.0:8000->8000/tcp docker_acra-webconfig_1 74ab6172fa41 cossacklabs/acra-connector:master "/acra-connector --a…" 5 minutes ago Up 5 minutes 9191/tcp, 0.0.0.0:9494->9494/tcp docker_acra-connector_1 19e2160e7c2f cossacklabs/acra-server:master "/acra-server --mysq…" 6 minutes ago Up 5 minutes docker_acra-server_1 732610db0946 docker_mysql "docker-entrypoint.s…" 6 minutes ago Up 6 minutes 0.0.0.0:3306->3306/tcp docker_mysql_1
Then run AcraPoisonRecordMaker:
$ docker exec -it docker_acra-server_1 /acra-poisonrecordmaker --keys_dir=/keys IiIiIiIiIiJVRUMyAAAALZT3kRMDW8biNub1xNvp8h8VMUGF2RZJ6aMEcu2tYrv9SRt23T8gJwQmVAAAAAABAUAMAAAAEAAAACAAAADM9OG4Y+XeOgQ1lotlwD3HFF3zfemKwqi3hW/jUt9pecCuSPJOcLydlYCDN9SX9THSwB66SO4JZAjuEVRwAAAAAAAAAAABAUAMAAAAEAAAAEQAAAB8M92tf6mWIegFfvwpKRU0rxvo24/N6PzmaAr3SpgIyldLPwSpm5Ly+TgDXGvaCcbV47DV/Qn/YmKnT2FJW8xh5Wyj7IKBoVxzqdvLkfE2VfbjdfekQeICEB/smYYQCKk=
The output is base64 encoded poison record. Decode it and insert into your data as binary data.
There is one useful additional parameter that AcraPoisonRecordMaker has: --data_length. It will change the size of the generated random data in the poison record. This is useful for transforming the data inside the poison records to resemble your data length-wise.
For instance, if you store data that’s typically 2kb in size, use the following option:
docker exec -it docker_acra-server_1 /acra-poisonrecordmaker --keys_dir=/keys --data_length=2048
What you can do with poison records in Acra
Poison records are useful as signals for raising a security reaction. Here are things you can configure in Acra:
● Perform a proxy shut-down if a poison record is detected:
acra-server --db_host=127.0.0.1 --poison_shutdown_enable
Useful for the extremely security conscious individuals and critical infrastructures – just shutdown the server if an attacker is detected.
● Run a script if a poison record is found in the input stream:
acra-server --db_host=127.0.0.1 --poison_run_script_file=/path/to/file
You can specify any action in a script, like, calling admin, sending messages to monitoring systems (or Slack channels), blocking IP as suspicious.
● Perform a system shut-down and run a script:
acra-server --db_host=127.0.0.1 --poison_run_script_file=/path/to/file --poison_shutdown_enable
From a paranoid standpoint, the third version is optimal, but from the operations’ point of view, 2nd might be sufficient if the other security controls are in place and are implemented well.
Poison records are means of monitoring and detecting data leaks in your database. In a way, poison records resemble part honeypots, part file fingerprinting, and you can read more about this resemblance in our Explain Like I’m 5-style post in Medium "Poison Records (Honeypots for Database Tables)” or pay a visit to the Acra GitHub repository and try them out for yourself.