/**
 * The OWASP CSRFGuard Project, BSD License
 * Eric Sheridan (eric@infraredsecurity.com), Copyright (c) 2011 
 * All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *    1. Redistributions of source code must retain the above copyright notice,
 *       this list of conditions and the following disclaimer.
 *    2. Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *    3. Neither the name of OWASP nor the names of its contributors may be used
 *       to endorse or promote products derived from this software without specific
 *       prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
(function() {
    /**
     * Code to ensure our event always gets triggered when the DOM is updated.
     * @param obj
     * @param type
     * @param fn
     * @source http://www.dustindiaz.com/rock-solid-addevent/
     */
    function addEvent( obj, type, fn ) {
        if (obj.addEventListener) {
            obj.addEventListener( type, fn, false );
            EventCache.add(obj, type, fn);
        }
        else if (obj.attachEvent) {
            obj["e"+type+fn] = fn;
            obj[type+fn] = function() { obj["e"+type+fn]( window.event ); }
            obj.attachEvent( "on"+type, obj[type+fn] );
            EventCache.add(obj, type, fn);
        }
        else {
            obj["on"+type] = obj["e"+type+fn];
        }
    }
    
    var EventCache = function(){
        var listEvents = [];
        return {
            listEvents : listEvents,
            add : function(node, sEventName, fHandler){
                listEvents.push(arguments);
            },
            flush : function(){
                var i, item;
                for(i = listEvents.length - 1; i >= 0; i = i - 1){
                    item = listEvents[i];
                    if(item[0].removeEventListener){
                        item[0].removeEventListener(item[1], item[2], item[3]);
                    };
                    if(item[1].substring(0, 2) != "on"){
                        item[1] = "on" + item[1];
                    };
                    if(item[0].detachEvent){
                        item[0].detachEvent(item[1], item[2]);
                    };
                };
            }
        };
    }();
    
    /** string utility functions **/
    String.prototype.startsWith = function(prefix) {
        return this.indexOf(prefix) === 0;
    };

    String.prototype.endsWith = function(suffix) {
        return this.match(suffix+"$") == suffix;
    };

    /** hook using standards based prototype **/
    function hijackStandard() {
        XMLHttpRequest.prototype._open = XMLHttpRequest.prototype.open;
        XMLHttpRequest.prototype.open = function(method, url, async, user, pass) {
            this.url = url;
            
            this._open.apply(this, arguments);
        };
        
        XMLHttpRequest.prototype._send = XMLHttpRequest.prototype.send;
        XMLHttpRequest.prototype.send = function(data) {
            if(this.onsend != null) {
                this.onsend.apply(this, arguments);
            }
            
            this._send.apply(this, arguments);
        };
    }

    /** ie does not properly support prototype - wrap completely **/
    function hijackExplorer() {
        var _XMLHttpRequest = window.XMLHttpRequest;
        
        function alloc_XMLHttpRequest() {
            this.base = _XMLHttpRequest ? new _XMLHttpRequest : new window.ActiveXObject("Microsoft.XMLHTTP");
        }
        
        function init_XMLHttpRequest() {
            return new alloc_XMLHttpRequest;
        }
        
        init_XMLHttpRequest.prototype = alloc_XMLHttpRequest.prototype;
        
        /** constants **/
        init_XMLHttpRequest.UNSENT = 0;
        init_XMLHttpRequest.OPENED = 1;
        init_XMLHttpRequest.HEADERS_RECEIVED = 2;
        init_XMLHttpRequest.LOADING = 3;
        init_XMLHttpRequest.DONE = 4;
        
        /** properties **/
        init_XMLHttpRequest.prototype.status = 0;
        init_XMLHttpRequest.prototype.statusText = "";
        init_XMLHttpRequest.prototype.readyState = init_XMLHttpRequest.UNSENT;
        init_XMLHttpRequest.prototype.responseText = "";
        init_XMLHttpRequest.prototype.responseXML = null;
        init_XMLHttpRequest.prototype.onsend = null;
        
        init_XMLHttpRequest.url = null;
        init_XMLHttpRequest.onreadystatechange = null;

        /** methods **/
        init_XMLHttpRequest.prototype.open = function(method, url, async, user, pass) {
            var self = this;
            this.url = url;
            
            this.base.onreadystatechange = function() {
                try { self.status = self.base.status; } catch (e) { }
                try { self.statusText = self.base.statusText; } catch (e) { }
                try { self.readyState = self.base.readyState; } catch (e) { }
                try { self.responseText = self.base.responseText; } catch(e) { }
                try { self.responseXML = self.base.responseXML; } catch(e) { }
                
                if(self.onreadystatechange != null) {
                    self.onreadystatechange.apply(this, arguments);
                }
            }
            
            this.base.open(method, url, async, user, pass);
        };
        
        init_XMLHttpRequest.prototype.send = function(data) {
            if(this.onsend != null) {
                this.onsend.apply(this, arguments);
            }
            
            this.base.send(data);
        };
        
        init_XMLHttpRequest.prototype.abort = function() {
            this.base.abort();
        };
        
        init_XMLHttpRequest.prototype.getAllResponseHeaders = function() {
            return this.base.getAllResponseHeaders();
        };
        
        init_XMLHttpRequest.prototype.getResponseHeader = function(name) {
            return this.base.getResponseHeader(name);
        };
        
        init_XMLHttpRequest.prototype.setRequestHeader = function(name, value) {
            return this.base.setRequestHeader(name, value);
        };
        
        /** hook **/
        window.XMLHttpRequest = init_XMLHttpRequest;
    }

    /** check if valid domain based on domainStrict **/
    function isValidDomain(current, target) {
        var result = false;
        
        /** check exact or subdomain match **/
        if(current == target) {
            result = true;
        } else if(%DOMAIN_STRICT% == false) {
            if(target.charAt(0) == '.') {
                result = current.endsWith(target);
            } else {
                result = current.endsWith('.' + target);
            }
        }
        
        return result;
    }

    /** determine if uri/url points to valid domain **/
    function isValidUrl(src) {
        var result = false;
        
        /** parse out domain to make sure it points to our own **/
        if(src.substring(0, 7) == "http://" || src.substring(0, 8) == "https://") {
            var token = "://";
            var index = src.indexOf(token);
            var part = src.substring(index + token.length);
            var domain = "";
            
            /** parse up to end, first slash, or anchor **/
            for(var i=0; i<part.length; i++) {
                var character = part.charAt(i);
                
                if(character == '/' || character == ':' || character == '#') {
                    break;
                } else {
                    domain += character;
                }
            }
            
            result = isValidDomain(document.domain, domain);
            /** explicitly skip anchors **/
        } else if(src.charAt(0) == '#') {
            result = false;
            /** ensure it is a local resource without a protocol **/
        } else if(!src.startsWith("//") && (src.charAt(0) == '/' || src.indexOf(':') == -1)) {
            result = true;
        }
        
        return result;
    }

    /** parse uri from url **/
    function parseUri(url) {
        var uri = "";
        var token = "://";
        var index = url.indexOf(token);
        var part = "";
        
        /**
         * ensure to skip protocol and prepend context path for non-qualified
         * resources (ex: "protect.html" vs
         * "/Owasp.CsrfGuard.Test/protect.html").
         */
        if(index > 0) {
            part = url.substring(index + token.length);
        } else if(url.charAt(0) != '/') {
            part = "%CONTEXT_PATH%/" + url;
        } else {
            part = url;
        }
        
        /** parse up to end or query string **/
        var uriContext = (index == -1);
        
        for(var i=0; i<part.length; i++) {
            var character = part.charAt(i);
            
            if(character == '/') {
                uriContext = true;
            } else if(uriContext == true && (character == '?' || character == '#')) {
                uriContext = false;
                break;
            }
            
            if(uriContext == true) {
                uri += character;
            }
        }
        
        return uri;
    }

    /** inject tokens as hidden fields into forms **/
    function injectTokenForm(form, tokenName, tokenValue, pageTokens,injectGetForms) {
      
        if (!injectGetForms) {
            var method = form.getAttribute("method");
      
            if ((typeof method != 'undefined') && method != null && method.toLowerCase() == "get") {
                return;
            }
        }
      
        var value = tokenValue;
        var action = form.getAttribute("action");
        
        if(action != null && isValidUrl(action)) {
            var uri = parseUri(action);
            value = pageTokens[uri] != null ? pageTokens[uri] : tokenValue;
        }
        
        var hidden = document.createElement("input");
        
        hidden.setAttribute("type", "hidden");
        hidden.setAttribute("name", tokenName);
        hidden.setAttribute("value", value);
        
        form.appendChild(hidden);
    }

    /** inject tokens as query string parameters into url **/
    function injectTokenAttribute(element, attr, tokenName, tokenValue, pageTokens) {
        var location = element.getAttribute(attr);
        
        if(location != null && isValidUrl(location)) {
            var uri = parseUri(location);
            var value = (pageTokens[uri] != null ? pageTokens[uri] : tokenValue);
            
            if(location.indexOf('?') != -1) {
                location = location + '&' + tokenName + '=' + value;
            } else {
                location = location + '?' + tokenName + '=' + value;
            }

            try {
                element.setAttribute(attr, location);
            } catch (e) {
                // attempted to set/update unsupported attribute
            }
        }
    }

    /** inject csrf prevention tokens throughout dom **/
    function injectTokens(tokenName, tokenValue) {
        /** obtain reference to page tokens if enabled **/
        var pageTokens = {};
        
        if(%TOKENS_PER_PAGE% == true) {
            pageTokens = requestPageTokens();
        }
        
        /** iterate over all elements and injection token **/
        var all = document.all ? document.all : document.getElementsByTagName('*');
        var len = all.length;

        //these are read from the csrf guard config file(s)
        var injectForms = %INJECT_FORMS%;
        var injectGetForms = %INJECT_GET_FORMS%;
        var injectFormAttributes = %INJECT_FORM_ATTRIBUTES%;
        var injectAttributes = %INJECT_ATTRIBUTES%;
        
        for(var i=0; i<len; i++) {
            var element = all[i];
            
            /** inject into form **/
            if(element.tagName.toLowerCase() == "form") {
                if(injectForms) {
                    injectTokenForm(element, tokenName, tokenValue, pageTokens,injectGetForms);
                }
                if (injectFormAttributes) {
                    injectTokenAttribute(element, "action", tokenName, tokenValue, pageTokens);
                }
                /** inject into attribute **/
            } else if(injectAttributes) {
                injectTokenAttribute(element, "src", tokenName, tokenValue, pageTokens);
                injectTokenAttribute(element, "href", tokenName, tokenValue, pageTokens);
            }
        }
    }

    /** obtain array of page specific tokens **/
    function requestPageTokens() {
        var xhr = window.XMLHttpRequest ? new window.XMLHttpRequest : new window.ActiveXObject("Microsoft.XMLHTTP");
        var pageTokens = {};
        
        xhr.open("POST", "%SERVLET_PATH%", false);
        xhr.send(null);
        
        var text = xhr.responseText;
        var name = "";
        var value = "";
        var nameContext = true;
        
        for(var i=0; i<text.length; i++) {
            var character = text.charAt(i);
            
            if(character == ':') {
                nameContext = false;
            } else if(character != ',') {
                if(nameContext == true) {
                    name += character;
                } else {
                    value += character;
                }
            }
            
            if(character == ',' || (i + 1) >= text.length) {
                pageTokens[name] = value;
                name = "";
                value = "";
                nameContext = true;
            }
        }
        
        return pageTokens;
    }
    
    /**
     * Only inject the tokens if the JavaScript was referenced from HTML that
     * was served by us. Otherwise, the code was referenced from malicious HTML
     * which may be trying to steal tokens using JavaScript hijacking techniques.
     * The token is now removed and fetched using another POST request to solve,
     * the token hijacking problem.
     */
    if(isValidDomain(document.domain, "%DOMAIN_ORIGIN%")) {
        /** optionally include Ajax support **/
        if(%INJECT_XHR% == true) {
            if(navigator.appName == "Microsoft Internet Explorer") {
                hijackExplorer();
            } else {
                hijackStandard();
            }
        
        var xhr = window.XMLHttpRequest ? new window.XMLHttpRequest : new window.ActiveXObject("Microsoft.XMLHTTP");
        var csrfToken = {};
        xhr.open("POST", "%SERVLET_PATH%", false);
        xhr.setRequestHeader("FETCH-CSRF-TOKEN", "1");
        xhr.send(null);
        
        var token_pair = xhr.responseText;
        token_pair = token_pair.split(":");
        var token_name = token_pair[0];
        var token_value = token_pair[1];

            XMLHttpRequest.prototype.onsend = function(data) {
                if(isValidUrl(this.url)) {
                    this.setRequestHeader("X-Requested-With", "XMLHttpRequest")
                    this.setRequestHeader(token_name, token_value);
                }
            };
        }
        
        /** update nodes in DOM after load **/
        addEvent(window,'unload',EventCache.flush);
        addEvent(window,'DOMContentLoaded', function() {
            injectTokens(token_name, token_value);
        });
    } else {
        alert("OWASP CSRFGuard JavaScript was included from within an unauthorized domain!");
    }
})();
