Tip: How to avoid code injection in OutSystems applications

Tip: How to avoid code injection in OutSystems applications

Code injection in user input forms are one of the widely security breaches in web development these days, used to access internal data as well as redirecting a user to a malicious web sites. This can be achieved everywhere an inputted literal is used to generate or build parts of code instructions. The scenarios can be many: from url addresses input boxes that allow HTML and Javascript code injection to SQL search literals that can be used to build entire SQL statements. The solution to prevent this type of code injection is to properly escape all injectable contents.

The OutSystems platform provides a set of built-in functions that properly escape text literals for the most common languages, like URI (EncodeURL), HTML (EncodeHTML), JavaScript (EncodeJavascript) and SQL (EncodeSQL), as well as the built-in Escape Contents property in expressions. Hence, when using text literals to build any kind of code statement, make sure escape them, preventing code injection of malicious instructions. As an example, some scenarios are presented below.

URI Scenario:
One of the most reported scenarios, is the infamous case of the URL field in an edition form (like user information or company information), where a user must enter a valid URI address for a website, and the application will then display the proper link using the entered URI as the "href" source. The EncodeHTML built-in function will escape all HTML characters, preventing HTML code injection. In fact, this scenario can occur wherever a text literal inputted by a user is used to build a HTML page. Additionally, the use of EncodeJavascript built-in function should also be used to prevent Javascript code injection in URI addresses. If the escape content property of an expression is set to yes, then it's contents are automatically escaped.

SQL scenario
Another commonly reported scenario, and probably more critical, is SQL code injection. Assuming that an inputted text literal is directly used in a SQL statement (usually as an expand inline parameter), if this value is not properly escaped, injected SQL code could change the SQL statement to access confidential information directly, or even DROP some tables and databases. The use of the built-in function EncodeSQL prevents this and should be used in every text literal used to build the SQL statement. In a more innocent scenario, an unescaped text literal could generate runtime errors in the application due to incorrect SQL syntax. As an example, an error message like the one below could popup.

Error in advanced query QUERYNAME in ACTIONNAME: Line 15044: Incorrect syntax near 'text literal'. Unclosed quotation mark before the character string ')'

Keep in mind that the text literals could be introduced in input boxes, data from external files (like excel upload) and query strings in the URL of the application.
Best regards

Miguel João
Nice features,

however should it not be default in the espace.
It's kinda weird for an out-of-the-box application like this we still have to manually add security to prevent sql-injection.

imho, it should be in the system by default, and perhaps with a global setting to override it somehow.

The platform defaults are already not to allow code injection.

The presented cases are for when users explicitly disable content escaping or use expand inline parameters on Advanced SQL Queries, in order to manually build HTML and SQL code. This kind of usage is required only for complex/advanced scenarios and should be avoided as while using the platform you should write as little code as possible (preferably none at all). On more common usage patterns the platform will deal with all the escaping for you.

Best regards,
Miguel Ventura