Easily encrypt querystring parameters

By João Melo on 24 Feb 2014
It should be possible to encrypt parameters that are passed in querystrings easily as a property of a Screen In Parameter.
Justin James24 Feb 2014
Joao -

I am not quite sure how that would work with a GET and query strings; all of the encryption would need to be done client-side, which means the server would have no way of decrypting it unless all of the decryption details were passed, unencrypted, to the server or sent tot he client in a previous request.

The best solution is to use a "Submit" action type and set SSL to required so it does a POST and the data is encrypted as part of the request body.

João Melo26 Feb 2014
I'm sorry, but I didn't understand your point...

I would like something like this: www.mydomain.com/?VisitorId=f2r3vowiu4ho5uivnfvun3o4r5u7498uhnpi

Like a slug, or a hash automatically generated by the application and put in the place of the real ID when a I intend to click on a link or navigate to other page. I don't want to make POSTs all the time...

This would done by a property on an Input Parameter of a Screen
Justin James26 Feb 2014
Joao -

If you are talking about a one-way hash, then all you need to do is use the "encrypt" function which is built right into OutSystems (same function used to do the one-way encryption of user password) and I supposed you could add an "EncryptedId" Attribute to your columns to look them up. You could also use "Generate Password" and check to make sure that it is not in the DB for that Entity first, or you could use GenerateGuid from the System eSpace as well. Of course, doing a lookup against the table with a long string will be a lot less efficient than an integer lookup. But if your goal is to keep something from entering in random IDs to access records, I suppose this would be a fine solution for that. I'd also suggest you implement stricter roles, implement multi-tenancy, or add something like an "owning user id" attribute and checking it against Session.UserId (we use ALL of these methods to keep folks out of records in our applications).

Now, if your goal is to keep people from getting sentiive data in the query string while it is "on the wire" or "at rest" (say, the user's browser cache history, or Google Analytics' data), then we go back to my original issue, which I will hopefully be able to explain better.

All encryption depends on the other end being able to decrypt it. That means that the other side needs to have some sort of key to unlock the encryption. This can be something like an SSL certificate which can be verified by a third party, a private key exchanged before hand, etc.

In this case, what you want simply does not work, because how is the key shared? You are asking the CLIENT to do the encryption, so the CLIENT needs to provide the SERVER with a key. But the key itself has to be shared un-encrypted (or else the server cannot decrypt it!). Unless you are using a pre-shared key (like a client certificate issued by an Active Directory controller) or something that can be verified against a trusted third-party (say, a Kerberos ticket), the key will need to be shared via the same medium (anonymous HTTP in this session) that we are already assuming the attacker can eavesdrop on. So there is no way to share the key without having attackers be able to access it, and decrypt the data, or worse, do a "man in the middle" attack.

If your goal is to prevent an attacker from accessing the data "on the wire" or "at rest" in a history cache, SSL is the right, best approach, and if you need to verify the identity of the client and it is an internally-used application, consider requiring client certificates issued by a trusted third-party (like an Active Directory domain controller).

Hope this makes sense!