Security
Introduction to security
After deploying a web application, it is essential to secure your environment against hackers and malicious intentions. User credentials and available data must be safely sent to the client or back to the web server. This chapter describes which options are available to set up your environment safely and what Thinkwise does to enable users to work safely with your application.
HTTPS
HTTPS or SSL encryption ensures that all information sent via the internet between the web server and the client is encrypted. Therefore, it is not possible to see the sent information during the transport. The information may contain user credentials or data from the database.
More information about HTTPS is available at http://en.wikipedia.org/wiki/HTTP_Secure.
Thinkwise strongly recommends to always use HTTPS. A URL Rewrite rule can redirect users from HTTP to HTTPS automatically.
HTTPS Certificates
HTTPS works with a certificate that is installed on the web server.
An HTTPS certificate is connected to the URL with which the application is going to be accessed.
If the URL is not yet available, it should first be requested.
For external access to the application, a domain name is needed, for example, \<www.thinkwisesoftware.com\>
.
There are various providers of SSL certificates with various options and prices. There is a choice of:
- Type of validation:
- Domain name validation
- Organization validation
- Comprehensive validation
- Type of certificate:
- Single domain name certificate
- Multiple domain names certificate
- Wild card certificate
- Lifespan in years
The certificate is extended in good time in order to prevent cancellation.
The certificate is linked to the URL with which the user can access the web application. Usually, port 443 of the web environment is used to access the web application through HTTPS.
Connecting the certificate to the URL is done in IIS by right-clicking on the website in which the web application has been placed and choosing Edit Bindings… .
Edit bindings…
Normally, one binding has already been specified for a website.
This refers to the HTTP type with the IP Address *
.
This is meant to test the application locally on the web server without HTTPS after deployment.
If a binding is changed or added, the dialogue below will appear. In this dialog, the properties of the web application can be specified in order to access this application externally via the internet. At the bottom of this pop-up, the SSL certificate that has just been installed is chosen. Now, the certificate is connected to the web application's URL and the application can be accessed via HTTPS.
Edit site bindings
Security headers
Universal GUIThere are several security headers that web servers can return to browsers to prevent or limit certain capabilities that malicious users could exploit.
Since Indicium is a web application, it sets these headers to the appropriate values itself. For Indicium, further configuration is not necessary.
However, the Universal GUI is served as static content from a web server. For this reason, it cannot set any headers. Therefore, we recommend configuring the web server to set these headers on the static content requests of the Universal GUI as well.
-
Do not use the X-XSS-Protection header. Read the warnings in the link. It is an old security header that comes with its own risks, for deprecated browsers.
-
The X-Frame-Options header should be returned with the value
SAMEORIGIN
. It ensures that your Universal GUI cannot be embedded in an iframe on another website. This prevents click-jacking attacks that trick the user into clicking on the wrong link and potentially leaking sensitive information. When configured correctly, every request for Universal GUI assets will includeX-Frame-Options: SAMEORIGIN
in its response headers. -
The Referrer-Policy header should be returned with the value
same-origin
. This ensures that theReferer
request header, which can contain sensitive information, can only be included in requests to the same site. When configured correctly, every request for Universal GUI assets will includeReferrer-Policy: same-origin
in its response headers. -
The X-Content-Type-Options header should be returned with the value
nosniff
. This ensures that the browser always respects theContent-Type
response and does not try to infer the content type from the response data itself. When configured correctly, every request for Universal GUI assets will includeX-Content-Type-Options: nosniff
in its response headers.
For the Universal GUI, you can configure all of these headers in the web.config
file:
<system.webServer>
…
<httpProtocol>
<customHeaders>
<add name="X-Frame-Options" value="SAMEORIGIN" />
<add name="Referrer-Policy" value="same-origin" />
<add name="X-Content-Type-Options" value="nosniff" />
</customHeaders>
</httpProtocol>
…
</system.webServer>
If the Universal GUI is in the root of the web server and Indicium is a child application, Indicium inherits the custom headers listed in the web.config
.
This will cause duplicate headers in the Indicium application which might cause issues.
You can remove them by adding <remove name="X-Frame-Options" />
and the other custom headers in the Indicium web.config
file.
Aside from adding these important security headers, it is also important to remove certain standard response headers that can leak information that attackers might use to exploit vulnerabilities.
- The
Server
response header leaks the type of web server on which an application is hosted. Attackers can use this information to focus their attention on vulnerabilities of that type of web server. - The
X-Powered-By
response header leaks the web technology an application uses (e.g., ASP.NET). Attackers can use this information to focus their attention on vulnerabilities of that web technology.
You can remove these headers in the same section of the web.config
file:
<system.webServer>
…
<httpProtocol>
<customHeaders>
<remove name="Server" />
<remove name="X-Powered-By" />
</customHeaders>
</httpProtocol>
…
</system.webServer>
Content Security Policy header
Universal GUIThe Content Security Policy header (CSP) is a header that prevents certain types of attacks, such as cross-site scripting. The CSP prevents these attacks by only allowing content to load from web domains that are specified in your CSP. For example, loading the Map component will only work if the URL is whitelisted in the CSP header.
Setting up the CSP header requires knowledge of the features you are using in your application. The Universal GUI is served as static content, so to enable this header, you must configure it for your web server.
A CSP header can cause some parts of your application to not work as expected if not configured properly.
Enable the CSP header
To enable the CSP header for the Universal GUI:
-
Open your
web.config
. -
Find the
customHeaders
section. -
Add the following line to the
customHeaders
section:<add name="Content-Security-Policy"
value="default-src 'self';
script-src 'self';
style-src 'self' 'unsafe-inline' https://fonts.googleapis.com;
object-src 'none';
connect-src 'self' https://o70260.ingest.sentry.io;
font-src 'self' data: https://fonts.gstatic.com;
img-src 'self' data: blob:;
base-uri 'self';
frame-src 'self';
manifest-src 'self';
media-src 'self';
worker-src 'self';" />
The basic settings for the CSP header are now enabled. Configure the CSP header if necessary.
Configure the CSP header
Depending on your application requirements, you may need to make some changes to the CSP header settings.
If the Universal GUI is in the root of the web server and Indicium is a child application, Indicium inherits the custom headers listed in the web.config
.
This will cause duplicate headers in the Indicium application which might cause issues.
You can remove them by adding <remove name="X-Frame-Options" />
and the other custom headers in the Indicium web.config
file.
To configure the CSP header settings:
- Open your
web.config
. - Find the
Content-Security-Policy
in thecustomHeaders
section. - If Indicium is hosted on a different domain than the Universal GUI, add the domain of Indicium to the
connect-src
andimg-src
directives.
For example, if the Universal GUI is hosted onhttps://universal.thinkwise.app
and Indicium is hosted onhttps://indicium.thinkwise.app
, the values are:
Directive | Value |
---|---|
connect-src | connect-src 'self' https://o70260.ingest.sentry.io https://indicium.thinkwise.app; |
img-src | img-src 'self' data: blob: https://indicium.thinkwise.app; |
- If you use the Maps component, add additional entries to the
img-src
directive.
For example, if you use the OpenStreetMap tile server, you will need to addhttps://*.tile.openstreetmap.org
to theimg-src
directive:
Directive | Value |
---|---|
img-src | img-src 'self' data: https://*.tile.openstreetmap.org; |
The URL for your tile server might be different. In that case, add its value to base-url
.
You can find the Base layer URI in the Software Factory in the menu User interface > Maps > Base layers.
- If you use the Previewer with the URL control, add the URL of the previewer to the
frame-src
directive. For example, if you are hosting Universal onhttps://thinkwise.app
and want to be able to include something from a different domain, addhttps://example.com
to theframe-src
directive:
Directive | Value |
---|---|
frame-src | frame-src 'self' data: https://example.com; |
-
If you use the Barcode scanner:
- The standard Barcode scanner requires the use of
wasm-eval
:
Directive Value script-src
script-src 'self' wasm-eval;
- The
Cortex
barcode scanner control requires the use ofunsafe-eval
:
Directive Value script-src
script-src 'self' unsafe-eval;
The
Cortex
barcode scanner control requires the use ofunsafe-eval
in thescript-src
directive. This is because the barcode scanner uses theeval
function to execute the code that is returned by the barcode scanner. It is a known limitation of the barcode scanner control. If you do not use the barcode scanner control, you can remove theunsafe-eval
from thescript-src
directive. - The standard Barcode scanner requires the use of
-
If something is not working, open the developer tools in your browser and check the console for errors that look like this:
Refused to evaluate a string as JavaScript because 'unsafe-eval' is not an allowed source of script
in the following Content Security Policy directive: "script-src 'self'".The error above indicates that something is trying to use
eval
to execute code. In this case, this happened because of theCortex barcode scanner
control.
More information about CSP can be found on the Mozilla Developer Network
Additionally, certain features of the platform might require additional CSP headers.
HSTS header
The HTTP Strict-Transport-Security response header can be used by servers to signal modern browsers to access a domain only through HTTPS. Configuring your site to return this header makes it more secure than with only HTTP to HTTPS redirection enabled. The reason is that after receiving the response header, browsers will know to change HTTP requests to HTTPS client side. This can decrease the chance of man-in-the-middle attacks between the client and server.
In the latest versions of IIS, you can configure HSTS through the manager UI:
HSTS settings for a site
To enable Strict-Transport-Security through the web.config
, in case the IIS manager UI is not available, add the following to your configuration:
<system.webServer>
…
<httpProtocol>
<customHeaders>
<add name="Strict-Transport-Security" value="max-age=63072000" />
</customHeaders>
</httpProtocol>
…
</system.webServer>
HSTS should ideally be configured on your infrastructure's gateway/reverse proxy server level.
Not doing so can result in unexpected issues.
For example, when enabling the Redirect Http to Https
option on a site that is also using the Application initialization module,
the initialization request might not work correctly because it will be sent through HTTP instead of HTTPS.
For older IIS versions and more examples of how to properly configure the HTTP to HTTPS redirect, please refer to this site.
Technically, enabling the preload function is required for full protection against man-in-the-middle type attacks. Without it, browsers can potentially still make an initial connection through HTTP before receiving the HSTS header. However, to use this option, the site domain must be registered in a hard-coded list used by the browsers. Read here what is required to make this work before enabling it: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Strict-Transport-Security#preloading_strict_transport_security