Skip to content

Spring Boot anti-tampering persistence PoC application using AES-GCM

Notifications You must be signed in to change notification settings

rusakovichma/authenticated-persistence-poc

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Spring Boot Authenticated encryption persistence PoC

The PoC how to defend against tampering of encrypted data at persistence layer

Attack example

An encryption is used to prevent information disclosure at DB layer, but it is not prevents sensitive data tampering. Lets imagine the following table structure:

ID | First Name | Last Name | Email | Position | Salary (Encrypted)
1, 'John', 'Smith', 'john_smith@companyname.com', 'CEO', 'ZHNmNDNnYWRmZzQ1MjR2NDJmMjRm'
....
999, 'Joe', 'Doe', 'joe_doe@companyname.com', 'Software Engineer', 'HNdrmQ2NMjRDNZqQ1RD8eRtCerWm'

Suppose, the encrypted employee salary field value were tampered with another employee salary (for example, with CEO salary encrypted value) stored in the same table.

ID | First Name | Last Name | Email | Position | Salary (Encrypted)
1, 'John', 'Smith', 'john_smith@companyname.com', 'CEO', 'ZHNmNDNnYWRmZzQ1MjR2NDJmMjRm'
....
999, 'Joe', 'Doe', 'joe_doe@companyname.com', 'Software Engineer', 'ZHNmNDNnYWRmZzQ1MjR2NDJmMjRm' <-- Tampered with CEO salary

Result: Now the employee has the salary as the CEO has.

PoC

The solution is to use authenticated encryption. Demonstration and PoC of the solution may be found here: https://github.com/rusakovichma/authenticated-persistence-poc/blob/master/src/test/java/com/github/rusakovichma/persistance/authenticated/poc/controller/PersistenceSalaryTamperingAttack.java

        @Sql({"classpath:schema_h2_cleaning.sql", "classpath:schema_h2_salary_tampering.sql"})
        @Test
        public void testGetEmployee() {
            Employee ceoEmployee = restTemplate.getForObject(String.format("http://localhost:%d/employees/1", port), Employee.class);
            assertEquals(99999, (int) ceoEmployee.getSalary());
            assertNull(ceoEmployee.getSalaryEncrypted());
            assertNull(ceoEmployee.getNonce());

            ResponseEntity<Employee> devEmployee = restTemplate.getForEntity(String.format("http://localhost:%d/employees/999", port), Employee.class);
            //Tampering detected -> INTERNAL_SERVER_ERROR
            assertEquals(HttpStatus.INTERNAL_SERVER_ERROR.value(), devEmployee.getStatusCodeValue());
        }

Releases

No releases published

Packages

No packages published

Languages