[CryptoAPI] How to use CryptoAPI to encrypt my Site Properties

Forge Component
Published on 3 Mar by Ricardo Silva
22 votes
Published on 3 Mar by Ricardo Silva

It is pretty common for people to want to save passwords or api tokens in OutSystems applications.

Currently the most convenient way to do this is by having a Site Property for this data. However, Site Properties are not encrypted on the database which makes this data vulnerable to a potential SQL Injection attack on your application.

In order to mitigate against this attack, one option would be to encrypt the content of the sensitive site properties. Good news, you can easily do this using Crypto API!

When assigning a value to the sensitive site property simply use Site.PropertyName = KEncrypt("new value", GetPrivateKey())

When reading it, use KDecrypt(Site.PropertyName, GetPrivateKey())

That's basically it.

The major drawback is that you can't directly use ServiceCenter to set these properties in plain text, I would recommend you create a page in your application to set these values.

"use Site.PropertyName = KEncrypt(GetPrivateKey(), "new value")" -

but in this case, wont "new value" be unencrypted in the database? I suppose the property value in the assignment is in the database as well, isnt it?

it will be encrypted in the database because what's written there is the result of the KEncrypt function, which encrypts "new value" using the environment's private key.

You can verify this yourself by consulting the ossys_site_property_shared table after you set the new value. It should contain an encrypted base64 blob instead of directly the value you set.

I see, but when you go to the assignemnt page and look at the value of site property, wont you see KEncrypt(GetPrivateKey(), "new value") and the new value not yet encrypted?

or when you set parameter with the function and do publish, as a result you are going to see KEncrypt(GetPrivateKey(), "encrypted value")?

No, you will see the result of that function call, which is the encrypted value.

If it makes it more clear to you, you can call the function in an orange ball in the flow before the assignment and use the result.

Your assignment will be: Site.PropertyName = KEncrypt.EncryptedText

Ricardo, when I do assignment:

it shows an error (two at the same time): 

Text data is required instead of binary

Binary data is required instead of text

Maybe this is not the right way to do the assignment?

i figured it out, the functions are parameters are KEncrypt("new value", GetPrivateKey()) and not KEncrypt(GetPrivateKey(), "new value")

it does encrypt it

but in the asignment it still shows the original value (which comes from database)

oops, the parameters are the other way around. KEncrypt("new value", GetPrivateKey())

I'll update the original post.

but you are right, inside the DB its all encrypted, thank you ;)

That assignment doesn't come from the database, it comes from your code.

You should not hardcode credentials into your code. You should have an empty site property and have a screen to set this value to something that is dynamic and specific to your environment.

yes, the site property is empty by default and on one screen i do assignment of var to the site property. This is right?

That is slightly better as a database attack on site properties will not yield your token in plain text. However, they could still attack the platform metadata and obtain your code, where the token is in plaintext.

The safest option would be to never have this value explicit in your code.