Author: jleroux
Date: Thu Feb 2 10:33:59 2017 New Revision: 1781366 URL: http://svn.apache.org/viewvc?rev=1781366&view=rev Log: Implemented: Improved: Documented: Completed: Reverted: Fixed: (OFBIZ-) Explanation Thanks: Added: ofbiz/trunk/applications/product/webapp/catalog/WEB-INF/Owasp.CsrfGuard.js (with props) ofbiz/trunk/applications/product/webapp/catalog/WEB-INF/Owasp.CsrfGuard.properties (with props) ofbiz/trunk/applications/product/webapp/catalog/WEB-INF/controller - Copie.xml (with props) ofbiz/trunk/applications/product/webapp/catalog/WEB-INF/web - Copie.xml (with props) ofbiz/trunk/framework/webapp/config/requestHandler - Copie.properties (with props) ofbiz/trunk/themes/tomahawk/template/Header - Copie.ftl (with props) Modified: ofbiz/trunk/applications/content/widget/compdoc/CompDocTemplateTree.xml ofbiz/trunk/applications/content/widget/content/ContentForms.xml ofbiz/trunk/applications/product/template/Main.ftl ofbiz/trunk/applications/product/template/store/EditProductStoreWebSites.ftl ofbiz/trunk/framework/base/src/main/java/org/apache/ofbiz/base/util/template/FreeMarkerWorker.java ofbiz/trunk/framework/minilang/src/main/java/org/apache/ofbiz/minilang/method/entityops/EntityOne.java ofbiz/trunk/framework/widget/dtd/widget-common.xsd ofbiz/trunk/framework/widget/src/main/java/org/apache/ofbiz/widget/renderer/macro/MacroFormRenderer.java Modified: ofbiz/trunk/applications/content/widget/compdoc/CompDocTemplateTree.xml URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/content/widget/compdoc/CompDocTemplateTree.xml?rev=1781366&r1=1781365&r2=1781366&view=diff ============================================================================== --- ofbiz/trunk/applications/content/widget/compdoc/CompDocTemplateTree.xml (original) +++ ofbiz/trunk/applications/content/widget/compdoc/CompDocTemplateTree.xml Thu Feb 2 10:33:59 2017 @@ -22,7 +22,7 @@ under the License. <tree name="CompDocTemplateTree" entity-name="Content" root-node-name="node-root" default-render-style="simple" default-wrap-style="treeWrapper"> <node name="node-root" wrap-style="treeWrapper"> - <entity-one entity-name="Content" use-cache="false"> + <entity-one entity-name="Content" value-field="content" use-cache="false"> <field-map field-name="contentId" from-field="rootContentId"/> </entity-one> <include-screen name="rootTemplateLine" location="component://content/widget/compdoc/CompDocScreens.xml"/> @@ -54,7 +54,7 @@ under the License. </sub-node> </node> <node name="node-body" join-field-name="itemContentId" entity-name="AssocRevisionItemView" wrap-style="treeWrapper"> - <entity-one entity-name="Content" use-cache="false"> + <entity-one entity-name="Content" value-field="content" use-cache="false"> <field-map field-name="contentId" from-field="itemContentId"/> </entity-one> <include-screen name="childTemplateLine" location="component://content/widget/compdoc/CompDocScreens.xml"/> @@ -90,7 +90,7 @@ under the License. <tree name="CompDocInstanceTree" entity-name="Content" root-node-name="node-root" default-render-style="simple" default-wrap-style="treeWrapper"> <node name="node-root"> - <entity-one entity-name="Content" use-cache="false"> + <entity-one entity-name="Content" value-field="content" use-cache="false"> <field-map field-name="contentId" from-field="instanceContent.instanceOfContentId"/> </entity-one> <include-screen name="rootInstanceLine" location="component://content/widget/compdoc/CompDocScreens.xml"/> @@ -122,7 +122,7 @@ under the License. </sub-node> </node> <node name="node-body" join-field-name="itemContentId" entity-name="AssocRevisionItemView"> - <entity-one entity-name="Content" use-cache="false"> + <entity-one entity-name="Content" value-field="content" use-cache="false"> <field-map field-name="contentId" from-field="itemContentId"/> </entity-one> <include-screen name="childInstanceLine" location="component://content/widget/compdoc/CompDocScreens.xml"/> Modified: ofbiz/trunk/applications/content/widget/content/ContentForms.xml URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/content/widget/content/ContentForms.xml?rev=1781366&r1=1781365&r2=1781366&view=diff ============================================================================== --- ofbiz/trunk/applications/content/widget/content/ContentForms.xml (original) +++ ofbiz/trunk/applications/content/widget/content/ContentForms.xml Thu Feb 2 10:33:59 2017 @@ -230,9 +230,9 @@ under the License. </form> <!-- ContentAssoc forms --> <form name="EditContentAssoc" target="updateContentAssoc" title="" type="single" - header-row-style="header-row" default-table-style="basic-table"> + header-row-style="header-row" default-table-style="basic-table" default-entity-name="contentAssocX"> <actions> - <entity-one entity-name="ContentAssoc" use-cache="true"> + <entity-one entity-name="ContentAssoc" use-cache="true" value-field="contentAssoc"> <field-map field-name="contentId" from-field="contentId"/> <field-map field-name="contentIdTo" from-field="contentIdTo"/> <field-map field-name="contentAssocTypeId" from-field="contentAssocTypeId"/> Modified: ofbiz/trunk/applications/product/template/Main.ftl URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/product/template/Main.ftl?rev=1781366&r1=1781365&r2=1781366&view=diff ============================================================================== --- ofbiz/trunk/applications/product/template/Main.ftl (original) +++ ofbiz/trunk/applications/product/template/Main.ftl Thu Feb 2 10:33:59 2017 @@ -29,6 +29,8 @@ under the License. </form> <div class="label">${uiLabelMap.CommonOr}: <a href="<@ofbizUrl>EditProdCatalog</@ofbizUrl>" class="buttontext">${uiLabelMap.ProductCreateNewCatalog}</a></div> <br /> +<p>Output format: ${.output_format} +<p>Auto-escaping: ${.auto_esc?c} <div class="label">${uiLabelMap.ProductEditCategoryWithCategoryId}:</div> <form method="post" action="<@ofbizUrl>EditCategory</@ofbizUrl>" style="margin: 0;" name="EditCategoryForm"> <@htmlTemplate.lookupField name="productCategoryId" id="productCategoryId" formName="EditCategoryForm" fieldFormName="LookupProductCategory"/> Modified: ofbiz/trunk/applications/product/template/store/EditProductStoreWebSites.ftl URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/product/template/store/EditProductStoreWebSites.ftl?rev=1781366&r1=1781365&r2=1781366&view=diff ============================================================================== --- ofbiz/trunk/applications/product/template/store/EditProductStoreWebSites.ftl (original) +++ ofbiz/trunk/applications/product/template/store/EditProductStoreWebSites.ftl Thu Feb 2 10:33:59 2017 @@ -37,12 +37,7 @@ under the License. <td>${webSite.httpHost?default(' ')}</td> <td>${webSite.httpPort?default(' ')}</td> <td align="center"> - <a href="javascript:document.storeUpdateWebSite_${webSite_index}.submit();" class="buttontext">${uiLabelMap.CommonDelete}</a> - <form name="storeUpdateWebSite_${webSite_index}" method="post" action="<@ofbizUrl>storeUpdateWebSite</@ofbizUrl>"> - <input type="hidden" name="viewProductStoreId" value="${productStoreId}"/> - <input type="hidden" name="productStoreId" value=""/> - <input type="hidden" name="webSiteId" value="${webSite.webSiteId}"/> - </form> + <a href="<@ofbizUrl>storeUpdateWebSite?viewProductStoreId=${productStoreId}&productStoreId=&webSiteId=${webSite.webSiteId}</@ofbizUrl>" class="buttontext">${uiLabelMap.CommonDelete}</a> </td> </tr> <#-- toggle the row color --> Added: ofbiz/trunk/applications/product/webapp/catalog/WEB-INF/Owasp.CsrfGuard.js URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/product/webapp/catalog/WEB-INF/Owasp.CsrfGuard.js?rev=1781366&view=auto ============================================================================== --- ofbiz/trunk/applications/product/webapp/catalog/WEB-INF/Owasp.CsrfGuard.js (added) +++ ofbiz/trunk/applications/product/webapp/catalog/WEB-INF/Owasp.CsrfGuard.js Thu Feb 2 10:33:59 2017 @@ -0,0 +1,447 @@ +/** + * The OWASP CSRFGuard Project, BSD License + * Eric Sheridan ([hidden email]), 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!"); + } +})(); Propchange: ofbiz/trunk/applications/product/webapp/catalog/WEB-INF/Owasp.CsrfGuard.js ------------------------------------------------------------------------------ svn:eol-style = native Propchange: ofbiz/trunk/applications/product/webapp/catalog/WEB-INF/Owasp.CsrfGuard.js ------------------------------------------------------------------------------ svn:keywords = Date Rev Author URL Id Propchange: ofbiz/trunk/applications/product/webapp/catalog/WEB-INF/Owasp.CsrfGuard.js ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: ofbiz/trunk/applications/product/webapp/catalog/WEB-INF/Owasp.CsrfGuard.properties URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/product/webapp/catalog/WEB-INF/Owasp.CsrfGuard.properties?rev=1781366&view=auto ============================================================================== --- ofbiz/trunk/applications/product/webapp/catalog/WEB-INF/Owasp.CsrfGuard.properties (added) +++ ofbiz/trunk/applications/product/webapp/catalog/WEB-INF/Owasp.CsrfGuard.properties Thu Feb 2 10:33:59 2017 @@ -0,0 +1,417 @@ +# The OWASP CSRFGuard Project, BSD License +# Eric Sheridan ([hidden email]), 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. + +# From: https://github.com/esheri3/OWASP-CSRFGuard/blob/master/csrfguard-test/src/main/webapp/WEB-INF/csrfguard.properties + +# Common substitutions +# %servletContext% is the servlet context (e.g. the configured app prefix or war file name, or blank. +# e.g. if you deploy a default warfile as someApp.war, then %servletContext% will be /someApp +# if there isnt a context it will be the empty string. So to use this in the configuration, use e.g. %servletContext%/something.html +# which will translate to e.g. /someApp/something.html + +# Logger +# +# The logger property (org.owasp.csrfguard.Logger) defines the qualified class name of +# the object responsible for processing all log messages produced by CSRFGuard. The default +# CSRFGuard logger is org.owasp.csrfguard.log.ConsoleLogger. This class logs all messages +# to System.out which JavaEE application servers redirect to a vendor specific log file. +# Developers can customize the logging behavior of CSRFGuard by implementing the +# org.owasp.csrfguard.log.ILogger interface and setting the logger property to the new +# logger's qualified class name. The following configuration snippet instructs OWASP CSRFGuard +# to capture all log messages to the console: +# +# org.owasp.csrfguard.Logger=org.owasp.csrfguard.log.ConsoleLogger +org.owasp.csrfguard.Logger=org.owasp.csrfguard.log.JavaLogger + +# Which configuration provider factory you want to use. The default is org.owasp.csrfguard.config.PropertiesConfigurationProviderFactory +# Another configuration provider has more features including config overlays: org.owasp.csrfguard.config.overlay.ConfigurationOverlayProviderFactory +# The default configuration provider is: org.owasp.csrfguard.config.overlay.ConfigurationAutodetectProviderFactory +# which will look for an overlay file, it is there, and the factory inside that file is set it will use it, otherwise will be PropertiesConfigurationProviderFactory +# it needs to implement org.owasp.csrfguard.config.ConfigurationProviderFactory +org.owasp.csrfguard.configuration.provider.factory = org.owasp.csrfguard.config.overlay.ConfigurationAutodetectProviderFactory + + +# If csrfguard filter is enabled +org.owasp.csrfguard.Enabled = false + +# If csrf guard filter should check even if there is no session for the user +# Note: this changed around 2014/04, the default behavior used to be to +# not check if there is no session. If you want the legacy behavior (if your app +# is not susceptible to CSRF if the user has no session), set this to false +org.owasp.csrfguard.ValidateWhenNoSessionExists = true + +# New Token Landing Page +# +# The new token landing page property (org.owasp.csrfguard.NewTokenLandingPage) defines where +# to send a user if the token is being generated for the first time, and the use new token landing +# page boolean property (org.owasp.csrfguard.UseNewTokenLandingPage) determines if any redirect happens. +# UseNewTokenLandingPage defaults to false if NewTokenLandingPage is not specified, and to true +# if it is specified.. If UseNewTokenLandingPage is set true then this request is generated +# using auto-posting forms and will only contain the CSRF prevention token parameter, if +# applicable. All query-string or form parameters sent with the original request will be +# discarded. If this property is not defined, CSRFGuard will instead auto-post the user to the +# original context and servlet path. The following configuration snippet instructs OWASP CSRFGuard to +# redirect the user to %servletContext%/index.html when the user visits a protected resource +# without having a corresponding CSRF token present in the HttpSession object: +# +org.owasp.csrfguard.NewTokenLandingPage=%servletContext%/control/login/* + +# Protected Methods +# +# The protected methods property (org.owasp.csrfguard.ProtectedMethods) defines a comma +# separated list of HTTP request methods that should be protected by CSRFGuard. The default +# list is an empty list which will cause all HTTP methods to be protected, thus preserving +# legacy behavior. This setting allows the user to inform CSRFGuard that only requests of the +# given types should be considered for protection. All HTTP methods not in the list will be +# considered safe (i.e. view only / unable to modify data). This should be used only when the +# user has concrete knowledge that all requests made via methods not in the list +# are safe (i.e. do not apply an action to any data) since it can actually introduce new +# security vulnerabilities. For example: the user thinks that all actionable requests are +# only available by POST requests when in fact some are available via GET requests. If the +# user has excluded GET requests from the list then they have introduced a vulnerability. +# The following configuration snippet instructs OWASP CSRFGuard to protect only the POST, +# PUT, and DELETE HTTP methods. +# +# org.owasp.csrfguard.ProtectedMethods=POST,PUT,DELETE + +# or you can configure all to be protected, and specify which is unprotected. This is the preferred approach + +# org.owasp.csrfguard.UnprotectedMethods=GET + +# Unique Per-Page Tokens +# +# The unique token per-page property (org.owasp.csrfguard.TokenPerPage) is a boolean value that +# determines if CSRFGuard should make use of unique per-page (i.e. URI) prevention tokens as +# opposed to unique per-session prevention tokens. When a user requests a protected resource, +# CSRFGuard will determine if a page specific token has been previously generated. If a page +# specific token has not yet been previously generated, CSRFGuard will verify the request was +# submitted with the per-session token intact. After verifying the presence of the per-session token, +# CSRFGuard will create a page specific token that is required for all subsequent requests to the +# associated resource. The per-session CSRF token can only be used when requesting a resource for +# the first time. All subsequent requests must have the per-page token intact or the request will +# be treated as a CSRF attack. This behavior can be changed with the org.owasp.csrfguard.TokenPerPagePrecreate +# property. Enabling this property will make CSRFGuard calculate the per page token prior to a first +# visit. This option only works with JSTL token injection and is useful for preserving the validity of +# links if the user pushes the back button. There may be a performance impact when enabling this option +# if the .jsp has a large number of proctected links that need tokens to be calculated. +# Use of the unique token per page property is currently experimental +# but provides a significant amount of improved security. Consider the exposure of a CSRF token using +# the legacy unique per-session model. Exposure of this token facilitates the attacker's ability to +# carry out a CSRF attack against the victim's active session for any resource exposed by the web +# application. Now consider the exposure of a CSRF token using the experimental unique token per-page +# model. Exposure of this token would only allow the attacker to carry out a CSRF attack against the +# victim's active session for a small subset of resources exposed by the web application. Use of the +# unique token per-page property is a strong defense in depth strategy significantly reducing the +# impact of exposed CSRF prevention tokens. The following configuration snippet instructs OWASP +# CSRFGuard to utilize the unique token per-page model: +# +# org.owasp.csrfguard.TokenPerPage=true +# org.owasp.csrfguard.TokenPerPagePrecreate=false +org.owasp.csrfguard.TokenPerPage=true +org.owasp.csrfguard.TokenPerPagePrecreate=false + +# Token Rotation +# +# The rotate token property (org.owasp.csrfguard.Rotate) is a boolean value that determines if +# CSRFGuard should generate and utilize a new token after verifying the previous token. Rotation +# helps minimize the window of opportunity an attacker has to leverage the victim's stolen token +# in a targeted CSRF attack. However, this functionality generally causes navigation problems in +# most applications. Specifically, the 'Back' button in the browser will often cease to function +# properly. When a user hits the 'Back' button and interacts with the HTML, the browser may submit +# an old token causing CSRFGuard to incorrectly believe this request is a CSRF attack in progress +# (i.e. a 'false positive'). Users can prevent this scenario by preventing the caching of HTML pages +# containing FORM submissions using the cache-control header. However, this may also introduce +# performance problems as the browser will have to request HTML on a more frequent basis. The following +# configuration snippet enables token rotation: +# +# org.owasp.csrfguard.Rotate=true + +# Ajax and XMLHttpRequest Support +# +# The Ajax property (org.owasp.csrfguard.Ajax) is a boolean value that indicates whether or not OWASP +# CSRFGuard should support the injection and verification of unique per-session prevention tokens for +# XMLHttpRequests. To leverage Ajax support, the user must not only set this property to true but must +# also reference the JavaScript DOM Manipulation code using a script element. This dynamic script will +# override the send method of the XMLHttpRequest object to ensure the submission of an X-Requested-With +# header name value pair coupled with the submission of a custom header name value pair for each request. +# The name of the custom header is the value of the token name property and the value of the header is +# always the unique per-session token value. This custom header is analogous to the HTTP parameter name +# value pairs submitted via traditional GET and POST requests. If the X-Requested-With header was sent +# in the HTTP request, then CSRFGuard will look for the presence and ensure the validity of the unique +# per-session token in the custom header name value pair. Note that verification of these headers takes +# precedence over verification of the CSRF token supplied as an HTTP parameter. More specifically, +# CSRFGuard does not verify the presence of the CSRF token if the Ajax support property is enabled and +# the corresponding X-Requested-With and custom headers are embedded within the request. The following +# configuration snippet instructs OWASP CSRFGuard to support Ajax requests by verifying the presence and +# correctness of the X-Requested-With and custom headers: +# +# org.owasp.csrfguard.Ajax=true +org.owasp.csrfguard.Ajax=true + +# The default behavior of CSRFGuard is to protect all pages. Pages marked as unprotected will not be protected. +# If the Protect property is enabled, this behavior is reversed. Pages must be marked as protected to be protected. +# All other pages will not be protected. This is useful when the CsrfGuardFilter is aggressively mapped (ex: /*), +# but you only want to protect a few pages. +# +# org.owasp.csrfguard.Protect=true + +# Unprotected Pages: +# +# The unprotected pages property (org.owasp.csrfguard.unprotected.*) defines a series of pages that +# should not be protected by CSRFGuard. Such configurations are useful when the CsrfGuardFilter is +# aggressively mapped (ex: /*). The syntax of the property name is org.owasp.csrfguard.unprotected.[PageName], +# where PageName is some arbitrary identifier that can be used to reference a resource. The syntax of +# defining the uri of unprotected pages is the same as the syntax used by the JavaEE container for uri mapping. +# Specifically, CSRFGuard will identify the first match (if any) between the requested uri and an unprotected +# page in order of declaration. Match criteria is as follows: +# +# Case 1: exact match between request uri and unprotected page +# Case 2: longest path prefix match, beginning / and ending /* +# Case 3: extension match, beginning *. +# Case 4: if the value starts with ^ and ends with $, it will be evaulated as a regex. Note that before the +# regex is compiled, any common variables will be substituted (e.g. %servletContext%) +# Default: requested resource must be validated by CSRFGuard +# +# The following code snippet illustrates the four use cases over four examples. The first two examples +# (Tag and JavaScriptServlet) look for direct URI matches. The third example (Html) looks for all resources +# ending in a .html extension. The next example (Public) looks for all resources prefixed with the URI path /MySite/Public/*. +# The last example looks for resources that end in Public.do +# +# org.owasp.csrfguard.unprotected.Tag=%servletContext%/tag.jsp +# org.owasp.csrfguard.unprotected.JavaScriptServlet=%servletContext%/JavaScriptServlet +# org.owasp.csrfguard.unprotected.Html=*.html +# org.owasp.csrfguard.unprotected.Public=%servletContext%/Public/* +# regex example starts with ^ and ends with $, and the %servletContext% is evaluated before the regex +# org.owasp.csrfguard.unprotected.PublicServlet=^%servletContext%/.*Public\.do$ + +#org.owasp.csrfguard.unprotected.Default=%servletContext%/ +#org.owasp.csrfguard.unprotected.Upload=%servletContext%/upload.html +org.owasp.csrfguard.unprotected.JavaScriptServlet=%servletContext%/control/JavaScriptServlet +#org.owasp.csrfguard.unprotected.Ajax=%servletContext%/ajax.html +#org.owasp.csrfguard.unprotected.Error=%servletContext%/error.html +#org.owasp.csrfguard.unprotected.Error=%servletContext%/error.jsp +#org.owasp.csrfguard.unprotected.Index=%servletContext%/index.html +#org.owasp.csrfguard.unprotected.JavaScript=%servletContext%/javascript.html +#org.owasp.csrfguard.unprotected.Tag=%servletContext%/tag.jsp +#org.owasp.csrfguard.unprotected.Redirect=%servletContext%/redirect.jsp +#org.owasp.csrfguard.unprotected.Forward=%servletContext%/forward.jsp +#org.owasp.csrfguard.unprotected.Session=%servletContext%/session.jsp +org.owasp.csrfguard.unprotected.Session=%servletContext%/favicon.ico +org.owasp.csrfguard.unprotected.Session=%servletContext%/control/login/* +org.owasp.csrfguard.unprotected.Index=%servletContext%/index.jsp + +# Actions: Responding to Attacks +# +# The actions directive (org.owasp.csrfguard.action.*) gives the user the ability to specify one or more +# actions that should be invoked when a CSRF attack is detected. Every action must implement the +# org.owasp.csrfguard.action.IAction interface either directly or indirectly through the +# org.owasp.csrfguard.action.AbstractAction helper class. Many actions accept parameters that can be specified +# along with the action class declaration. These parameters are consumed at runtime and impact the behavior of +# the associated action. +# +# The syntax for defining and configuring CSRFGuard actions is relatively straight forward. Let us assume we wish +# to redirect the user to a default page when a CSRF attack is detected. A redirect action already exists within +# the CSRFGuard bundle and is available via the class name org.owasp.csrfguard.actions.Redirect. In order to enable +# this action, we capture the following declaration in the Owasp.CsrfGuard.properties file: +# +# syntax: org.owasp.csrfguard.action.[actionName]=[className] +# example: org.owasp.csrfguard.action.class.Redirect=org.owasp.csrfguard.actions.Redirect +# +# The aforementioned directive declares an action called "Redirect" (i.e. [actionName]) referencing the Java class +# "org.owasp.csrfguard.actions.Redirect" (i.e. [className]). Anytime a CSRF attack is detected, the Redirect action +# will be executed. You may be asking yourself, "but how do I specify where the user is redirected?"; this is where +# action parameters come into play. In order to specify the redirect location, we capture the following declaration +# in the Owasp.CsrfGuard.properties file: +# +# syntax: org.owasp.csrfguard.action.[actionName].[parameterName]=[parameterValue] +# example: org.owasp.csrfguard.action.Redirect.ErrorPage=%servletContext%/error.html +# +# The aforementioned directive declares an action parameter called "ErrorPage" (i.e. [parameterName]) with the value +# of "%servletContext%/error.html" (i.e. [parameterValue]) for the action "Redirect" (i.e. [actionName]). The +# Redirect action expects the "ErrorPage" parameter to be defined and will redirect the user to this location when +# an attack is detected. +# +#org.owasp.csrfguard.action.Empty=org.owasp.csrfguard.action.Empty +org.owasp.csrfguard.action.Log=org.owasp.csrfguard.action.Log +org.owasp.csrfguard.action.Log.Message=potential cross-site request forgery (CSRF) attack thwarted (user:%user%, ip:%remote_ip%, method:%request_method%, uri:%request_uri%, error:%exception_message%) +#org.owasp.csrfguard.action.Invalidate=org.owasp.csrfguard.action.Invalidate +#org.owasp.csrfguard.action.Redirect=org.owasp.csrfguard.action.Redirect +#org.owasp.csrfguard.action.Redirect.Page=%servletContext%/error.html +#org.owasp.csrfguard.action.RequestAttribute=org.owasp.csrfguard.action.RequestAttribute +#org.owasp.csrfguard.action.RequestAttribute.AttributeName=Owasp_CsrfGuard_Exception_Key +#org.owasp.csrfguard.action.Rotate=org.owasp.csrfguard.action.Rotate +org.owasp.csrfguard.action.SessionAttribute=org.owasp.csrfguard.action.SessionAttribute +org.owasp.csrfguard.action.SessionAttribute.AttributeName=Owasp_CsrfGuard_Exception_Key +#org.owasp.csrfguard.action.Error=org.owasp.csrfguard.action.Error +#org.owasp.csrfguard.action.Error.Code=403 +#org.owasp.csrfguard.action.Error.Message=Security violation. + +# Token Name +# +# The token name property (org.owasp.csrfguard.TokenName) defines the name of the HTTP parameter +# to contain the value of the OWASP CSRFGuard token for each request. The following configuration +# snippet sets the CSRFGuard token parameter name to the value OWASP_CSRFTOKEN: +# +# org.owasp.csrfguard.TokenName=OWASP_CSRFTOKEN +org.owasp.csrfguard.TokenName=OWASP_CSRFTOKEN + +# Session Key +# +# The session key property (org.owasp.csrfguard.SessionKey) defines the string literal used to save +# and lookup the CSRFGuard token from the session. This value is used by the filter and the tag +# libraries to retrieve and set the token value in the session. Developers can use this key to +# programmatically lookup the token within their own code. The following configuration snippet sets +# the session key to the value OWASP_CSRFTOKEN: +# +# org.owasp.csrfguard.SessionKey=OWASP_CSRFTOKEN +org.owasp.csrfguard.SessionKey=OWASP_CSRFTOKEN + +# Token Length +# +# The token length property (org.owasp.csrfguard.TokenLength) defines the number of characters that +# should be found within the CSRFGuard token. Note that characters are delimited by dashes (-) in groups +# of four. For cosmetic reasons, users are encourage to ensure the token length is divisible by four. +# The following configuration snippet sets the token length property to 32 characters: +# +# org.owasp.csrfguard.TokenLength=32 +org.owasp.csrfguard.TokenLength=32 + +# Pseudo-random Number Generator +# +# The pseudo-random number generator property (org.owasp.csrfguard.PRNG) defines what PRNG should be used +# to generate the OWASP CSRFGuard token. Always ensure this value references a cryptographically strong +# pseudo-random number generator algorithm. The following configuration snippet sets the pseudo-random number +# generator to SHA1PRNG: +# +# org.owasp.csrfguard.PRNG=SHA1PRNG +org.owasp.csrfguard.PRNG=SHA1PRNG + +# Pseudo-random Number Generator Provider + +# The pseudo-random number generator provider property (org.owasp.csrfguard.PRNG.Provider) defines which +# provider's implementation of org.owasp.csrfguard.PRNG we should utilize. The following configuration +# snippet instructs the JVM to leverage SUN's implementation of the algorithm denoted by the +# org.owasp.csrfguard.PRNG property: + +# org.owasp.csrfguard.PRNG.Provider=SUN +org.owasp.csrfguard.PRNG.Provider=SUN + +# If not specifying the print config option in the web.xml, you can specify it here, to print the config +# on startup +org.owasp.csrfguard.Config.Print = true + +########################### +## Javascript servlet settings if not set in web.xml +## https://www.owasp.org/index.php/CSRFGuard_3_Token_Injection +########################### + +# leave this blank and blank in web.xml and it will read from META-INF/csrfguard.js from the jarfile +# Denotes the location of the JavaScript template file that should be consumed and dynamically +# augmented by the JavaScriptServlet class. The default value is WEB-INF/Owasp.CsrfGuard.js. +# Use of this property and the existence of the specified template file is required. +#org.owasp.csrfguard.JavascriptServlet.sourceFile = WEB-INF/Owasp.CsrfGuard.js +org.owasp.csrfguard.JavascriptServlet.sourceFile = WEB-INF/Owasp.CsrfGuard.js + +# Boolean value that determines whether or not the dynamic JavaScript code should be strict +# with regards to what links it should inject the CSRF prevention token. With a value of true, +# the JavaScript code will only place the token in links that point to the same exact domain +# from which the HTML originated. With a value of false, the JavaScript code will place the +# token in links that not only point to the same exact domain from which the HTML originated, +# but sub-domains as well. +org.owasp.csrfguard.JavascriptServlet.domainStrict = true + +# Allows the developer to specify the value of the Cache-Control header in the HTTP response +# when serving the dynamic JavaScript file. The default value is private, maxage=28800. +# Caching of the dynamic JavaScript file is intended to minimize traffic and improve performance. +# Note that the Cache-Control header is always set to "no-store" when either the "Rotate" +# "TokenPerPage" options is set to true in Owasp.CsrfGuard.properties. +org.owasp.csrfguard.JavascriptServlet.cacheControl = private, maxage=28800 + +# Allows the developer to specify a regular expression describing the required value of the +# Referer header. Any attempts to access the servlet with a Referer header that does not +# match the captured expression is discarded. Inclusion of referer header checking is to +# help minimize the risk of JavaScript Hijacking attacks that attempt to steal tokens from +# the dynamically generated JavaScript. While the primary defenses against JavaScript +# Hijacking attacks are implemented within the dynamic JavaScript itself, referer header +# checking is implemented to achieve defense in depth. +org.owasp.csrfguard.JavascriptServlet.refererPattern = .* + +# Similar to javascript servlet referer pattern, but this will make sure the referer of the +# javascript servlet matches the domain of the request. If there is no referer (proxy strips it?) +# then it will not fail. Generally this is a good idea to be true. +org.owasp.csrfguard.JavascriptServlet.refererMatchDomain = true + +# Boolean value that determines whether or not the dynamic JavaScript code should +# inject the CSRF prevention token as a hidden field into HTML forms. The default +# value is true. Developers are strongly discouraged from disabling this property +# as most server-side state changing actions are triggered via a POST request. +org.owasp.csrfguard.JavascriptServlet.injectIntoForms = true + +# if the token should be injected in GET forms (which will be on the URL) +# if the HTTP method GET is unprotected, then this should likely be false +org.owasp.csrfguard.JavascriptServlet.injectGetForms = true + +# if the token should be injected in the action in forms +# note, if injectIntoForms is true, then this might not need to be true +org.owasp.csrfguard.JavascriptServlet.injectFormAttributes = true + + +# Boolean value that determines whether or not the dynamic JavaScript code should +# inject the CSRF prevention token in the query string of src and href attributes. +# Injecting the CSRF prevention token in a URL resource increases its general risk +# of exposure to unauthorized parties. However, most JavaEE web applications respond +# in the exact same manner to HTTP requests and their associated parameters regardless +# of the HTTP method. The risk associated with not protecting GET requests in this +# situation is perceived greater than the risk of exposing the token in protected GET +# requests. As a result, the default value of this attribute is set to true. Developers +# that are confident their server-side state changing controllers will only respond to +# POST requests (i.e. discarding GET requests) are strongly encouraged to disable this property. +org.owasp.csrfguard.JavascriptServlet.injectIntoAttributes = true + + +org.owasp.csrfguard.JavascriptServlet.xRequestedWith = OWASP CSRFGuard Project + +########################### +## Config overlay settings if you have the provider above set to ConfigurationOverlayProvider +## This CSRF config provider uses Internet2 Configuration Overlays (documented on Internet2 wiki) +## By default the configuration is read from the Owasp.CsrfGuard.properties +## (which should not be edited), and the Owasp.CsrfGuard.overlay.properties overlays +## the base settings. See the Owasp.CsrfGuard.properties for the possible +## settings that can be applied to the Owasp.CsrfGuard.overlay.properties +########################### + +# comma separated config files that override each other (files on the right override the left) +# each should start with file: or classpath: +# e.g. classpath:Owasp.CsrfGuard.properties, file:c:/temp/myFile.properties +org.owasp.csrfguard.configOverlay.hierarchy = classpath:Owasp.CsrfGuard.properties, classpath:Owasp.CsrfGuard.overlay.properties + +# seconds between checking to see if the config files are updated +org.owasp.csrfguard.configOverlay.secondsBetweenUpdateChecks = 60 + + +########################### + Propchange: ofbiz/trunk/applications/product/webapp/catalog/WEB-INF/Owasp.CsrfGuard.properties ------------------------------------------------------------------------------ svn:eol-style = native Propchange: ofbiz/trunk/applications/product/webapp/catalog/WEB-INF/Owasp.CsrfGuard.properties ------------------------------------------------------------------------------ svn:keywords = Date Rev Author URL Id Propchange: ofbiz/trunk/applications/product/webapp/catalog/WEB-INF/Owasp.CsrfGuard.properties ------------------------------------------------------------------------------ svn:mime-type = text/plain |
Free forum by Nabble | Edit this page |