cossacklabs / acra

Database security suite. Database proxy with field-level encryption, search through encrypted data, SQL injections prevention, intrusion detection, honeypots. Supports client-side and proxy-side ("transparent") encryption. SQL, NoSQL.
https://www.cossacklabs.com/acra/
Apache License 2.0
1.35k stars 128 forks source link

Fix bug with i32 encoding #542

Closed G1gg1L3s closed 2 years ago

G1gg1L3s commented 2 years ago

This PR fixes a bug with int32 encoding. Bug was triggered with negative int32 values, when we insert them and then select with text encoding.

There were two ways of fixing this bug:

Fix insertion (which is implemented here)

Acra normalizes integers into int64 text before encrypting and sending into the database. The normalization happens here. For an int32 the whole process looked like:

[4 bytes] -> uint32 -> int64 -> text

But the issue is, expanding from uint32 into int64 happens signless. So, if the integer is -2061435539 the whole process would looks like:

[8520fd6d] -> uint32(2233531757) -> int64(2233531757) -> "2233531757"

This PR adds explicit conversion from uint32 into int32, so the compiler can omit correct instruction for expansions with a negative sign:

[8520fd6d] -> uint32(2233531757) -> int32(-2061435539) -> int64(-2061435539) -> "-2061435539"

But, this will not work with the values encrypted before this change, the bug can still remain in the database of some users

Fix selection

This is the fix I was first thinking of, and even implemented that, so if you believe this way should be used instead/with the previous one, it can be easily applied.

When we encode integer values in postgres, we create IntValue object, defined here. In consists of an int value and a string one. String is used as an optimization, because the whole int value is produced from string, so in case of text encoding, we can reuse that string.

But because strings are signless for int32 (see reasons above), this doesn't work. The way to correct is to explicitly calculate string representation based on an integer value.


I don't know which variant is better, so I'm here for your opinion.

Checklist