“Hiding” IDs in OutSystems URLs

Every few months, I see the question come up… “how do I hide the ID values in the URLs?” The concern is that in a URL like:

www.example.com/MyApplication/MyForm?RecordId=8

some nefarious user will change the “8” to a “9” and view data that they should not be looking at.

So if you strictly want to hide the IDs

Just use a “Submit” to access the page. This will do an HTTP POST request instead of a GET and the ID will be passed as a POST parameter and not in the URL. Hooray, missing accomplished! Right? Wrong.

  • There is no actual security here. The evil attacker can still change the ID being passed, they just need to use their browser’s developer tools to tweak the value of the POST parameter.
  • Now the user cannot bookmark the page or share the URL to view the record. This may not be a problem in some situations, but if you are doing something like a product catalog or content site, or whatever, this is a huge problem.

So… yeah. Don’t do this unless hiding the ID is an aesthetic concern. And even then, use the SEO Rules or something so you can get pretty URLs with the IDs instead (like www.example.com/MyApplication/MyForm/8)

If the concern is security, what should you be doing instead?

Prevent Access

You need to make sure that no one can get to a record that they should not be getting to. Whatever your criteria is for “who can see this?” you need to run that logic in the Preparation of any page that can display that data, and throw an Exception if they do not have the proper access. How you determine who has access depends on your application, but I usually have an Entity that has a reference to a User or Role, and a reference to the record, and look them up like that. I like to use a new Exception for this, so I can have a customized screen that says something like “You cannot access this record” as opposed to the default screens which indicate “not logged in” and “missing required role”.

Truly Hide IDs

You may still need to hide the IDs anyways in certain applications, so that users cannot simply guess at IDs. This is especially important when the user cannot be logged in when viewing the page, but the ID or URL may end up being public. For example, if a user creates a password reset request, you cannot just send an email with a sequential number as an ID in it and expect it to be safe.

In situations where you need to keep the ID “unguessable” (in fancy computer science terms, “non-deterministic”), add an Attribute to your Entity of type “Text”, make sure that you create an index on it, and populate it with the “GenerateGuid” Action (from “System”). Then, use this GUID as your ID that goes in the URL, and change your queries to query against this new Attribute.

J.Ja

Like what you read? Give Justin James a round of applause.

From a quick cheer to a standing ovation, clap to show how much you enjoyed this story.