Preventing iFrame injection in web app


There is an issue that an malicious attacker can inject iframes within the app so that the iframe can have a source to an external application that is outside of the parent app’s domain.

Ex: Lets consider the app to be hosted at https://app.com/. The attacker could inject an iframe that will contain a source to https://malicious.com/

In this case, we have to prevent any iFrames injected in our app that can point to a domain that is different from ours. To fix this issue, add the following header in the response for each request

X-Frame-Options : SAMEORIGIN

This is done by the following ways in MVC

web.config file

<system.webServer>

<httpProtocol>

<customHeaders>

<add name=”X-Frame-Options” value=”SAMEORIGIN” /> </customHeaders> </httpProtocol>

</system.webServer>

Application Start in Global.asax.cs

protected void Application_Start()
{
    AntiForgeryConfig.SuppressXFrameOptionsHeader = true;
}

Services


The following are the points to be taken care in our services layer

  1. Do not resolve any External references in the Xml documents that are input from external sources
  2. For any encryption mechanism, do not pass the keys / iv in the constructor
    1. Use certificate based encryption for better security
    2. Keep higher key sizes [512 and higher]
    3. For passwords, hashing is preferred
    4. Allow encrypted appsettings and connectionStrings section in web.config in ASP.Net MVC or ASP.Net
  3. Do not externalize the object initialization, esp from an un-trusted source
    1. Example: Do not allow an object to be created from the data from an external API call. A person object cannot be instantiated from an external call which can control the core behavior of a person
  4. Do not allow relative paths in the directory or file paths.
    1. Example: do not trust paths that contain ..\.
      1. The path “..\..\bin\Application.dll” should not be trusted when the user enters this value for sending a file by email
      2. So, is the case like “d:\wwwroot\site\app\..\..\logs\ActivityLog.xml”
    2. In the above two cases, the path enables the code to access the files / locations outside the application hosted path or outside its allowed boundary. This may result in hacking the system logs or accidentally exposing sensitive data.
  5. Do not trust any connection string or database name that may come from the external source or from the UI.
  6. Do not allow file names or directory names that meet the following criteria
    1. Longer than or equal to 255 characters in length
    2. contains special characters
    3. Directories or files having an name that starts with a “.”
  7. Always, invoke the file system read with the appropriate read permissions.
  8. Do not check if a file can be read and then try reading as it potentially leads into a race condition as other parts of the code may have a handle for the file
  9. Do not let the exception that occurs while accessing a database or a file system seep through the controller code to the UI
    1. Always, have a resource file that has a generic and a euphemistic message to let the user know if something  went wrong in the application.
  10. Do not grant more permissions via ACL [Access Control Lists] to any directory
  11. Do not publicly allow directory browsing even for the log files directory
  12. Do not allow Carraige return and linefeed in loggers / file writing logic
  13. Always have a pluggable serializer to serialize or deserialize the objects of the application.

View Pages


In any programming language, if there is a user input ex: username or some comments, that needs to be displayed on the page back, always encode and display.

Example : If a blog site wants to display the user comments against a post in the page, the application should use something like this

@Html.Encode(post.Comments) [C# => Razor Syntax]

This will avoid issues like when there is a malicious comment posted on the page which can be using some script like below, we can avoid being lured into the attack.


window.location.href='https://www.google.com';


SQL Injection


SQL Injection Tips

1. Do not use SQL Query without parameters in the following cases

1. Direct arguments : where name=’John’, use where name=@name instead
2. Like or contains : where name like ‘John%’, use where name=@name+’%’ instead
3. In clauses :
1. string[] paramNames = tags.Select(
(s, i) =&gt; “@tag” + i.ToString()).ToArray();
2. string inClause = string.Join(“,”, paramNames);using (SqlCommand cmd = new SqlCommand(string.Format(cmdText, inClause))) {
for(int i = 0; i &lt; paramNames.Length; i++) {
cmd.Parameters.AddWithValue(paramNames[i], tags[i]);
}}

4. When using columns in the order by clause in Row_Number Queries, validate the column names before setting them to form the query
5. For the soring directions, using an enumeration for ASC / DESC in the code will do a good job.
6. Always parameterize any query that goes to the database
7. In case of passing uniqueidentifiers into varchar columns, use guid.tryparse before passing the data to the DAL