Skip to Main Content
  • Questions
  • Security Design for Tables with Highly Sensitive Data

Breadcrumb

Question and Answer

Chris Saxon

Thanks for the question, Jacek.

Asked: February 14, 2022 - 6:00 am UTC

Last updated: February 14, 2022 - 2:51 pm UTC

Version: 19C

Viewed 1000+ times

You Asked

Hi guys!

We're building a service that allows users to store credentials for third-party sites, you can think of this service as something along the lines of 1Password.

The table that stores the credentials is highly sensitive, if an attacker were to get their hands on those credentials then our business is gone.

Hashing credentials is not an option since we have to be able to retrieve actual values.

What security measures can we take (aside from encrypting values) to:

1) protect our data, and 2) raise alarms if there is suspicious activity happening on the Credentials table?

E.g. How can we raise an alarm if someone does a SELECT * FROM Credentials?

E.g. How can we prevent someone from querying SELECT * FROM Credentials in the first place?

One solution I thought of was to put the Credentials table in its own schema, then create a stored procedure and GRANT EXECUTE on that procedure to the database user used by the web application and REVOKE SELECT from the table to ensure only the query SELECT * FROM Credentials WHERE id = ? (inside the procedure) can be run by the web app, but what if we want to join the results of the procedure to another table will that still work?

Please let me know how you might approach this problem.

Thanks in advance!

and Chris said...

You're right to be paranoid about this - any app that stores third-party credentials is a potentially lucrative target for attackers.

Below are some thoughts on how to secure this information. But you absolutely should seek out security experts to advise you further on this and review your solutions.

Firstly, try to avoid storing user credentials at all!

Look for APIs from the third parties that give the information you need. These will enable you to create access tokens instead of using the user's credentials directly.

For example, here in the UK we have Open Banking. This is a standard for enabling apps to request access to your banking transaction history, make payments, etc. without storing the customer's credentials yourself.

If you do need to store the credentials themselves, storing them in a separate schema and wrapping access in a stored procedure is a good start.

Once you've done this there are more steps you can take to lock down access, including:

Create views

These expose the "safe" (non-sensitive) columns. Only grant other users privileges on the view, not the table itself:

create table credentials (
  ...
);

create or replace view credentials_public as 
  select non_sensitive_columns 
  from   credentials;
  
grant 
  select on credentials_public 
  to other_user;


Use row-level security (RLS) - Virtual Private Database/Real Application Security

Views are really a DIY RLS solution. With VPD etc. you can define policies on your tables over who can access what. The policies are transparent to the end-user, so you can hide columns or rows from all queries against the credentials table as needed.

Database-level protections like this are just the start though. You'll want to have "defence in depth" with checks throughout the tech stack to limit access and look for suspicious activity.

The technical brief Securing the Oracle Database A technical primer goes through the options Oracle provides to help you with this:

https://download.oracle.com/database/oracle-database-security-primer.pdf

Finally, once you have a working version of the application, ensure you organize penetration testing ("pen test") from a third party to search for and report on vulnerabilities in your application.

Is this answer out of date? If it is, please let us know via a Comment

More to Explore

Design

New to good database design? Check out Chris Saxon's full fundamentals class.