XSS front-end firewall-seamless protection

Source: Internet
Author: User

The previous article (http://www.bkjia.com/Article/201406/310933.html) explained the hook program attack and defense practices, and achieved a set of framework page monitoring solution, will protect all sub pages.

So far, our protection depth is almost the same, but the breadth is still lacking.

For example, our property hook only considers setAttribute, but ignores the setAttributeNode. Although this method is never used, it does not mean that people cannot use it.

For example, createElement is used to create elements. In fact, createElementNS can also be used. You can even use the ready-made element cloneNode to achieve the goal. Therefore, these edge methods are worth considering.

Next we will review the previously discussed monitoring sites one by one.

Inline event execution eval

At the end of the first article, it is best to monitor eval, setTimeout ('... ') these functions can parse code to prevent execution of XSS code stored elsewhere.

Let's first list these functions:

  • Eval

  • SetTimeout (String)/setInterval (String)

  • Function

  • ExecScript/setImmediate (String)

In fact, you can monitor all the hooks in the previous article. But the reality is not as simple as we think.

Is there a problem with eval rewriting?

Eval is not a function. Why can't I rewrite it?

Var raw_fn = window. eval; window. eval = function (exp) {alert ('execute eval: '+ exp); return raw_fn.apply (this, arguments) ;}; console. log (eval ('1 + 1 '));

 

No problem at all. This is because the code is too simple. The following Demo shows the defects of the Alibaba Cloud version eval:

 (function() {    eval('var a=1');})();alert(typeof a);

It should be undefined, but the result is number. All the local variables are global. What is the situation? In fact, eval is not really a function, but a keyword! For details, click here.

Does Function rewriting make sense?

Function is a global variable. It is theoretically feasible to rewrite window. Function.

Var raw_fn = window. function; window. function = function () {alert ('call function'); return raw_fn.apply (this, arguments) ;}; var add = Function ('A', 'B ', 'Return a + B '); console. log (add (1, 2 ));

Rewriting is indeed feasible. But the reality is vulnerable: because all functions are Function-class instances, you can access the constructor of any Function to obtain the original Function.

For example, alert. constructor can bypass our hooks. You can even use anonymous functions:

(function(){}).constructor

Therefore, the Function can never be hooked.

Additional execution methods

Even if you do not use such functions, there are still a considerable number of methods to execute strings, such:

  • Create script, innerHTML = Code

  • Create a script, Path = data: Code

  • Create framework, Path = javascript: Code

  • ......

It seems unrealistic to fully monitor eval-like behaviors. However, as an alert, we only need to monitor eval and setTimeout/Interval.

Suspicious module Interception

The second part describes the interception of the out-of-site module. The reason for calling "module" instead of "script" is that not only script elements are capable of execution. Framework pages and plug-ins can all run code.

Executable Element

Let's list the elements that can execute remote modules:

  • Script
<script src="..." />
  • Framework
<iframe src="..."><frame src="...">
  • Plug-in (Flash)
<embed src="..."><object data="..."><object><param name="moive|src" value="..."></object>
  • Plug-ins (Others)
<applet codebase="...">

The path attributes of these elements should be used for troubleshooting.

However, the existence of such an element may lead to the failure of our path detection, which is:

<base href="...">

It can redefine the relative path of the page, which obviously cannot be ignored.

In fact, in addition to using elements to execute the station module, you can also use network communication to obtain the script code outside the station, and then call eval to execute:

AJAX

Currently, mainstream browsers support cross-origin requests as long as the server permits them. Therefore, we need to monitor the XMLHttpRequest: open method. If you are requesting an out-of-site address, you must make a policy match. If the call fails, the system will discard the upstream call, throw an exception, or generate a 400 status for XHR.

WebSocket

Similar to XHR, WebSocket can also be monitored through hooks.

However, it is worth noting that WebSocket is not a function, but a class. Therefore, when an instance is returned,Don't forget to change the constructor to your own hook. Otherwise, the original interface will be leaked.:

Var raw_class = window. webSocket; window. webSocket = function WebSocket (url, arg) {alert ('websocket request: '+ url); var ins = new raw_class (url, arg); // remember ins. constructor = WebSocket; return ins;}; var ws = new WebSocket ('ws: // 127.0.0.1: 100 ');

In addition, because it is a class, do not ignore static methods or attributes:

  • WebSocket. CONNECTING

  • WebSocket. OPEN

  • ...

Therefore, you also need to copy them to the hook.

Framework page message

HTML5 provides the framework Page Cross-origin communication capability. If a whitelist is not set up for the framework elements, attackers can embed the XSS Code into their own framework pages, send the XSS code postMessage to the homepage, and execute the Code through eval.

However, for the sake of security, HTML5 saves the source address in the message event to identify which page the message was sent.

Because it is an event, we can use the method mentioned in the first article to capture it. When a message is received, you can decide whether to block the event delivery based on the policy.

// Our defense system (function () {window. addEventListener ('message', function (e) {if (confirm ('found from [' + e. message of origin + ']: \ n \ n' + e. data + '\ n? ') {E. stopImmediatePropagation () ;}, true) ;}) (); window. addEventListener ('message', function (e) {alert ('Received: '+ e. data)}) postMessage ('hello ','*');

Of course, if the whitelist of the Framework page is configured, this can be completely avoided. Therefore, this defense can be enabled selectively.

Event Source

HTML5 adds an API named EventSource. However, its usage is very similar to WebSocket, so you can use a similar hook for defense.

At this point, we have listed various ways to execute remote modules. As a matter of fact, it is not difficult to defend against these monitoring points. What is difficult is to collect these monitoring points so that they do not leak water.

API hook

For dynamically created executable modules, we use Attribute hooks to monitor their remote paths.

How to create elements

This section is for Chrome because it does not support native accessors.

  • CreateElement/createElementNS out of nothing

  • CloneNode clone existing

  • InnerHTML/outerHTML factory Creation

The first two methods can be easily implemented through the hook program.

Third, because inner/outerHTML is the property of an element, not attribute. Because Chrome cannot obtain the native accessors, you cannot call the upper-level interface by using hooks.

Furthermore, inner/outerHTML transmits strings. Tags and attributes are mixed, and parsing strings is definitely unreliable. Therefore, you have to call native innerHTML to build nodes in batches and then scan the elements. In this process, the node Mount event has been triggered.

Therefore, you do not need to consider the third case.

You may be wondering why the previous hook is needed since all mounting events can be done with nodes? As a matter of fact, I have discussed in detail in the second article that the dynamically created scripts cannot be intercepted by events, so they only use hooks.

The scripts generated through innerHTML will not be executed! You have heard of this.

Accessors who modify attributes

Through the access hook of the prototype chain, you can directly monitor the specific property of a specific element without affecting others, so the efficiency is very high. Just now, we listed the elements that can execute remote modules. The path attributes of these elements must be overwritten by accessors.

Of course, Chrome can ignore this section.

How to modify attributes

In addition to setAttribute, setAttributeNode can also be used to set attributes, and even setAttributeNS versions.

Because setAttribute is a frequently called method, the hook program must be optimized to minimize the additional detection consumption.

New Page Environment

In addition to the simplest framework, there are other ways to get a new page.

Pop-up window

You can get the new page environment through the pop-up window. However, when the window is closed, it is destroyed. Can it be used? Test it as follows:

 <style> .aa { color: red }</style><button id="btn">POPUP</button><script>    btn.onclick = function() {        var win = window.open();        var raw_fn = win.Element.prototype.setAttribute;        win.close();        setTimeout(function() {            console.log(raw_fn);            raw_fn.call(btn, 'class', 'aa');        }, 1000);    };</script>

Although there will be instant flashes, the variables obtained from the new window are indeed retained and still take effect. Because we reference it, even if the window is closed, its memory will not be recycled.

In reality, you can bind the click event to the document, so that you can trigger any click anywhere to obtain a pure environment.

Therefore, we have to use the pop-up function to protect it through hooks.

In addition to the most commonly used window. open, there are:

  • ShowModalDialog

  • ShowModelessDialog

Opener

If the current webpage is clicked from another page, whether it is a pop-up window or hyperlink, window. opener records the environment of the Source Page.

If the source page is the same site as the source page, you can even access the variables in the Source Page.

This situation is quite common. For example, if you click a post details page on the post list page, the details page can fully control the list page.

It is not difficult to solve this problem. simply inject a protection program into window. opener, just like the new framework page.

However, window. opener may also have its own opener, and there may be a lot of recursion. Each page may have its own framework page, so window. opener may execute a lot of code. If it is performed during initialization, it may cause performance problems.

In fact, this unpopular attribute is rarely used. So it is better to set a latency policy: only when you first access opener can you protect it.

We will rewrite window. opener and convert it into a getter accesser:

var raw_opener = window.opener;var scanned;window.__defineGetter__('opener', function() {    if (!scanned) {        installHook(raw_opener);        scanned = true;    }    return raw_opener;});

In this way, as long as you do not access opener, protection against it will not be triggered, so as to truly execute on demand.

Postscript

There is no complete answer to the protection and monitoring points. You can add them later.

However, how many hooks and events have an impact on the page performance?

Therefore, we have to develop a test console to track this system. Check the page impact when monitoring is fully enabled.

Author: zjcqoo (http://cnblogs.com/index-html )- Hello

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.