Security

Viewstate Protection

Viewstate lies at the heart of PRADO. Viewstate represents data that can be used to restore pages to the state that is last seen by end users before making the current request. By default, PRADO uses hidden fields to store viewstate information.

It is extremely important to ensure that viewstate is not tampered by end users. Without protection, malicious users may inject harmful code into viewstate and unwanted instructions may be performed when page state is being restored on server side.

To prevent viewstate from being tampered, PRADO enforces viewstate HMAC (Keyed-Hashing for Message Authentication) check before restoring viewstate. Such a check can detect if the viewstate has been tampered or not by end users. Should the viewstate is modified, PRADO will stop restoring the viewstate and return an error message.

HMAC check requires a private key that should be secret to end users. Developers can either manually specify a key or let PRADO automatically generate a key. Manually specified key is useful when the application runs on a server farm. To do so, configure TSecurityManager in application configuration,

<modules>
    <module id="security"
        class="TSecurityManager"
        ValidationKey="my private key" />
</modules>

HMAC check does not prevent end users from reading the viewstate content. An added security measure is to encrypt the viewstate information so that end users cannot decipher it. To enable viewstate encryption, set the EnableStateEncryption of pages to true. This can be done in page configurations or in page code. Note, encrypting viewstate may degrade the application performance. A better strategy is to store viewstate on the server side, rather than the default hidden field.

Cross Site Scripting Prevention

Cross site scripting (also known as XSS) occurs when a web application gathers malicious data from a user. Often attackers will inject JavaScript, VBScript, ActiveX, HTML, or Flash into a vulnerable application to fool other application users and gather data from them. For example, a poorly design forum system may display user input in forum posts without any checking. An attacker can then inject a piece of malicious JavaScript code into a post so that when other users read this post, the JavaScript runs unexpectedly on their computers.

One of the most important measures to prevent XSS attacks is to check user input before displaying them. One can do HTML-encoding with the user input to achieve this goal. However, in some situations, HTML-encoding may not be preferable because it disables all HTML tags.

PRADO incorporates the work of HTMLPurifier and provides developers with a useful component called TSafeHtml. By enclosing content within a TSafeHtml component tag, the enclosed content are ensured to be safe to end users. In addition, the commonly used TTextBox has a SafeText property which contains user input that are ensured to be safe if displayed directly to end users.

With the broad use of active controls and more generally of AJAX-enabled controls using Javascript to transfer data between the server and the client, it's common to see attackers target javascript itself as a vector to inject malicious code.

Imagine a validator that uses an ajax callback to check user input from a textbox and returns an error message including the user input, example: 'The email address is not valid: test@example.com'. In such a situation user input must be checked to avoid possible injection.

The classic xss check involves checking for html tags inside the message and encode them; but since the message gets sent back to the client inside a javascript block, it needs to be encoded again to avoid any possible javascript escaping. By default PRADO encodes all variables sent clientside inside a javascript block to avoid any user-generated input from injecting malicious javascript code.

Cookie Attack Prevention

Protecting cookies from being attacked is of extreme important, as session IDs are commonly stored in cookies. If one gets hold of a session ID, he essentially owns all relevant session information.

There are several countermeasures to prevent cookies from being attacked.

  • An application can use SSL to create a secure communication channel and only pass the authentication cookie over an HTTPS connection. Attackers are thus unable to decipher the contents in the transferred cookies.
  • Expire sessions appropriately, including all cookies and session tokens, to reduce the likelihood of being attacked.
  • Prevent cross-site scripting (XSS) which causes arbitrary code to run in a user's browser and expose his cookies.
  • Validate cookie data and detect if they are altered.

PRADO implements a cookie validation scheme that prevents cookies from being modified. In particular, it does HMAC check for the cookie values if cookie validation is enable.

Cookie validation is disabled by default. To enable it, configure the THttpRequest module as follows,

<modules>
  <module id="request" class="THttpRequest" EnableCookieValidation="true" />
</modules>

To make use of cookie validation scheme provided by PRADO, you also need to retrieve cookies through the Cookies collection of THttpRequest by using the following PHP statements,

foreach($this->Request->Cookies as $cookie)
    // $cookie is of type THttpCookie

To send cookie data encoded with validation information, create new THttpCookie objects and add them to the Cookies collection of THttpResponse,

$cookie=new THttpCookie($name,$value);
$this->Response->Cookies[]=$cookie;

To avoid the possibility of identity theft through some variants of XSS attacks, THttpSession should always be configured to enforce HttpOnly setting on session cookie. The HttpOnly setting is disabled by default. To enable it, configure the THttpSession module as follows,

<modules>
  <module id="session" class="THttpSession" Cookie.HttpOnly="true" >
</modules>