[
  {
    "path": ".github/dependabot.yml",
    "content": "# To get started with Dependabot version updates, you'll need to specify which\n# package ecosystems to update and where the package manifests are located.\n# Please see the documentation for all configuration options:\n# https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates\n\nversion: 2\nupdates:\n  - package-ecosystem: \"maven\" # See documentation for possible values\n    directory: \"/\" # Location of package manifests\n    schedule:\n      interval: \"daily\"\n"
  },
  {
    "path": ".github/workflows/maven.yml",
    "content": "name: Build\n\non:\n  push:\n  pull_request:\n    branches: [ main ]\n\njobs:\n  build:\n    runs-on: ubuntu-latest\n    name: JavaWebSecurity Build\n    steps:\n    - name: Checkout\n      uses: actions/checkout@v5\n    - name: Configure Java for Build\n      uses: actions/setup-java@v5\n      with:\n        distribution: 'temurin'\n        java-version: '17'\n        cache: 'maven'\n    - name: Build with Maven\n      run: mvn -B package --file pom.xml\n"
  },
  {
    "path": ".gitignore",
    "content": "*.class\n.idea\n.classpath\n.project\n.DS_Store\n*/target*\ntarget/\n.settings*\n# Package Files #\n*.jar\n*.war\n*.ear\n*.iml\n*.log\n*.lck\n.pmd\n.forge_settings\naccountsDB.properties\ncustomerDB.properties"
  },
  {
    "path": "Ch04_OutputEscaping/pom.xml",
    "content": "<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd\">\n\t<modelVersion>4.0.0</modelVersion>\n\t<parent>\n\t\t<groupId>de.dominikschadow.javawebsecurity</groupId>\n\t\t<artifactId>javawebsecurity</artifactId>\n\t\t<version>1.0.0</version>\n\t</parent>\n\t<artifactId>Ch04_OutputEscaping</artifactId>\n\t<packaging>war</packaging>\n\t<name>Chapter 04 - Output Escaping</name>\n\t<url>https://github.com/dschadow/Java-Web-Security</url>\n\t<description>Chapter 4 Output Escaping sample project. Requires a server like Apache Tomcat or the Maven Tomcat plugin. After starting, open the web application in your browser at http://localhost:8080/Ch04_OutputEscaping</description>\n\n\t<dependencies>\n\t\t<dependency>\n            <groupId>javax.servlet</groupId>\n            <artifactId>javax.servlet-api</artifactId>\n        </dependency>\n\t\t<dependency>\n\t\t\t<groupId>org.owasp.esapi</groupId>\n\t\t\t<artifactId>esapi</artifactId>\n\t\t</dependency>\n\t</dependencies>\n\t\n\t<build>\n\t\t<finalName>Ch04_OutputEscaping</finalName>\n        <defaultGoal>tomcat7:run-war</defaultGoal>\n\t\t<plugins>\n\t\t\t<plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n\t\t\t\t<artifactId>maven-compiler-plugin</artifactId>\n\t\t\t</plugin>\n\t\t\t<plugin>\n\t\t\t\t<groupId>org.apache.tomcat.maven</groupId>\n\t\t\t\t<artifactId>tomcat7-maven-plugin</artifactId>\n\t\t\t</plugin>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-war-plugin</artifactId>\n                <configuration>\n                    <failOnMissingWebXml>false</failOnMissingWebXml>\n                </configuration>\n            </plugin>\n\t\t</plugins>\n\t</build>\n</project>"
  },
  {
    "path": "Ch04_OutputEscaping/src/main/resources/ESAPI.properties",
    "content": "# Logging\nLogger.ApplicationName=Ch04_OutputEscaping"
  },
  {
    "path": "Ch04_OutputEscaping/src/main/webapp/index.jsp",
    "content": "<%@ page language=\"java\" contentType=\"text/html; charset=UTF-8\" pageEncoding=\"UTF-8\"%>\n<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n<html>\n<head>\n\t<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"resources/css/styles.css\" />\n\t<title>Chapter 04 - Output Escaping</title>\n</head>\n<body>\n\t<h1>Chapter 04 - Output Escaping</h1>\n\n\t<p>This demo application shows how JavaServer Pages (JSP) can be extended with safe output escaping provided by the\n        OWASP Enterprise Security API (ESAPI). Feel free to enter any attack data like\n        <strong>&lt;script&gt;alert(&apos;XSS&apos;)&lt;/script&gt;</strong>.</p>\n\n\t<form name=\"withoutOutputEscaping\" method=\"post\" action=\"withoutOutputEscaping.jsp\">\n\t\t<fieldset>\n\t\t\t<legend>Without Output Escaping</legend>\n\t\t\t<label for=\"unprotected\" title=\"Name\">Name</label>\n\t\t\t<input type=\"text\" id=\"unprotected\" name=\"unprotected\" class=\"text-input\" />\n\t\t\t<input type=\"submit\" value=\"Submit\" />\n\t\t</fieldset>\n\t</form>\n\n\t<form name=\"withOutputEscaping\" method=\"post\" action=\"withOutputEscaping.jsp\">\n\t\t<fieldset>\n\t\t\t<legend>With Output Escaping</legend>\n\t\t\t<label for=\"protected\" title=\"Name\">Name</label>\n\t\t\t<input type=\"text\" id=\"protected\" name=\"protected\" class=\"text-input\" />\n\t\t\t<input type=\"submit\" value=\"Submit\" />\n\t\t</fieldset>\n\t</form>\n</body>\n</html>\n"
  },
  {
    "path": "Ch04_OutputEscaping/src/main/webapp/resources/css/styles.css",
    "content": "h1 {\n    font-size: 1.5em;\n}\n\nh2 {\n    font-size: 1.2em;\n}\n\nfieldset {\n    width: 450px;\n    font-size: 1.2em;\n    margin-top: 20px;\n}\n\ninput {\n    display: inline-block;\n    vertical-align: middle;\n    width: 250px;\n}\n\ninput[type=submit] {\n    width: 75px;\n    height: 20px;\n    margin-left: 10px;\n}\n\nlabel {\n    margin-right: 10px;\n}\n"
  },
  {
    "path": "Ch04_OutputEscaping/src/main/webapp/withOutputEscaping.jsp",
    "content": "<%@ page language=\"java\" contentType=\"text/html; charset=UTF-8\" pageEncoding=\"UTF-8\"%>\n<%@ page import=\"org.owasp.esapi.ESAPI\" %>\n<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n<html>\n<head>\n\t<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"resources/css/styles.css\" />\n\t<title>Chapter 04 - Output Escaping</title>\n</head>\n<body>\n    <h1>Chapter 04 - Output Escaping</h1>\n\n    <p>The provided input is printed output escaped. Output escaping is done by the Enterprise Security API (ESAPI) for\n        different contexts. Only HTML is the correct context here, the others are provided for reference only. The input\n        is printed into [] to show its position.</p>\n\n    <h2>CSS</h2>\n    <p>[<%= ESAPI.encoder().encodeForCSS(request.getParameter(\"protected\")) %>]</p>\n\n    <h2>HTML</h2>\n\t<p>[<%= ESAPI.encoder().encodeForHTML(request.getParameter(\"protected\")) %>]</p>\n\n    <h2>HTML Attribute</h2>\n    <p>[<%= ESAPI.encoder().encodeForHTMLAttribute(request.getParameter(\"protected\")) %>]</p>\n\n    <h2>JavaScript</h2>\n    <p>[<%= ESAPI.encoder().encodeForJavaScript(request.getParameter(\"protected\")) %>]</p>\n\n    <h2>URL</h2>\n    <p>[<%= ESAPI.encoder().encodeForURL(request.getParameter(\"protected\")) %>]</p>\n\n    <h2>XML</h2>\n    <p>[<%= ESAPI.encoder().encodeForXML(request.getParameter(\"protected\")) %>]</p>\n\n    <h2>XML Attribute</h2>\n    <p>[<%= ESAPI.encoder().encodeForXMLAttribute(request.getParameter(\"protected\")) %>]</p>\n\n    <h2>XPath</h2>\n    <p>[<%= ESAPI.encoder().encodeForXPath(request.getParameter(\"protected\")) %>]</p>\n\n    <p><a href=\"index.jsp\">Back</a></p>\n</body>\n</html>"
  },
  {
    "path": "Ch04_OutputEscaping/src/main/webapp/withoutOutputEscaping.jsp",
    "content": "<%@ page language=\"java\" contentType=\"text/html; charset=UTF-8\" pageEncoding=\"UTF-8\"%>\n<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n<html>\n<head>\n\t<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"resources/css/styles.css\" />\n\t<title>Chapter 04 - Output Escaping</title>\n</head>\n<body>\n    <h1>Chapter 04 - Output Escaping</h1>\n\n\t<p>This is your input without any output escaping at all. The input is printed into [] to show its position.</p>\n\n\t<p>[<%= request.getParameter(\"unprotected\") %>]</p>\n\n\t<p><a href=\"index.jsp\">Back</a></p>\n</body>\n</html>"
  },
  {
    "path": "Ch04_OutputEscapingJSF/pom.xml",
    "content": "<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0    http://maven.apache.org/maven-v4_0_0.xsd\">\n\t<modelVersion>4.0.0</modelVersion>\n\t<parent>\n\t\t<groupId>de.dominikschadow.javawebsecurity</groupId>\n\t\t<artifactId>javawebsecurity</artifactId>\n\t\t<version>1.0.0</version>\n\t</parent>\n\t<artifactId>Ch04_OutputEscapingJSF</artifactId>\n\t<packaging>war</packaging>\n\t<name>Chapter 04 - JSF Output Escaping</name>\n\t<url>https://github.com/dschadow/Java-Web-Security</url>\n    <description>Chapter 4 JSF Output Escaping sample project. Requires a server like Apache Tomcat or the Maven Tomcat plugin. After starting, open the web application in your browser at http://localhost:8080/Ch04_OutputEscapingJSF</description>\n\n\t<dependencies>\n\t\t<dependency>\n\t\t\t<groupId>com.sun.faces</groupId>\n\t\t\t<artifactId>jsf-api</artifactId>\n\t\t</dependency>\n\t\t<dependency>\n\t\t\t<groupId>com.sun.faces</groupId>\n\t\t\t<artifactId>jsf-impl</artifactId>\n\t\t</dependency>\n\t</dependencies>\n\n\t<build>\n\t\t<finalName>Ch04_OutputEscapingJSF</finalName>\n        <defaultGoal>tomcat7:run-war</defaultGoal>\n\t\t<plugins>\n\t\t\t<plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n\t\t\t\t<artifactId>maven-compiler-plugin</artifactId>\n\t\t\t</plugin>\n\t\t\t<plugin>\n\t\t\t\t<groupId>org.apache.tomcat.maven</groupId>\n\t\t\t\t<artifactId>tomcat7-maven-plugin</artifactId>\n\t\t\t</plugin>\n\t\t</plugins>\n\t</build>\n</project>"
  },
  {
    "path": "Ch04_OutputEscapingJSF/src/main/java/de/dominikschadow/webappsecurity/ContactController.java",
    "content": "/*\n * Copyright (C) 2015 Dominik Schadow, info@dominikschadow.de\n *\n * This file is part of the Java-Web-Security project.\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * \n *  http://www.apache.org/licenses/LICENSE-2.0\n * \n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage de.dominikschadow.webappsecurity;\n\nimport javax.faces.bean.ManagedBean;\nimport javax.faces.bean.SessionScoped;\nimport java.io.Serial;\nimport java.io.Serializable;\n\n/**\n * Bean representing user input (no additional security related attributes).\n * \n * @author Dominik Schadow\n */\n@ManagedBean(name = \"contact\")\n@SessionScoped\npublic class ContactController implements Serializable {\n    @Serial\n    private static final long serialVersionUID = 4083596061570021965L;\n\n    private String firstname;\n    private String lastname;\n\n    public String getFirstname() {\n        return firstname;\n    }\n\n    public void setFirstname(String firstname) {\n        this.firstname = firstname;\n    }\n\n    public String getLastname() {\n        return lastname;\n    }\n\n    public void setLastname(String lastname) {\n        this.lastname = lastname;\n    }\n}"
  },
  {
    "path": "Ch04_OutputEscapingJSF/src/main/webapp/WEB-INF/faces-config.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<faces-config version=\"2.2\"\n              xmlns=\"http://xmlns.jcp.org/xml/ns/javaee\"\n              xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n              xsi:schemaLocation=\"http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-facesconfig_2_2.xsd\">\n</faces-config>"
  },
  {
    "path": "Ch04_OutputEscapingJSF/src/main/webapp/WEB-INF/web.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<web-app xmlns=\"http://xmlns.jcp.org/xml/ns/javaee\"\n         xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n         xsi:schemaLocation=\"http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd\"\n         version=\"3.1\">\n    <display-name>Ch04_OutputEscapingJSF</display-name>\n\n    <context-param>\n        <param-name>javax.faces.PROJECT_STAGE</param-name>\n        <param-value>Development</param-value>\n    </context-param>\n\n    <servlet>\n        <servlet-name>Faces Servlet</servlet-name>\n        <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>\n        <load-on-startup>1</load-on-startup>\n    </servlet>\n\n    <servlet-mapping>\n        <servlet-name>Faces Servlet</servlet-name>\n        <url-pattern>*.xhtml</url-pattern>\n    </servlet-mapping>\n\n    <welcome-file-list>\n        <welcome-file>index.xhtml</welcome-file>\n    </welcome-file-list>\n</web-app>"
  },
  {
    "path": "Ch04_OutputEscapingJSF/src/main/webapp/contact.xhtml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"\n        \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n<html xmlns=\"http://www.w3.org/1999/xhtml\" xmlns:h=\"http://xmlns.jcp.org/jsf/html\">\n<h:head>\n    <h:outputStylesheet library=\"css\" value=\"styles.css\" name=\"styles.css\" />\n    <title>Chapter 04 - JSF Output Escaping</title>\n</h:head>\n<h:body>\n    <h1>Chapter 04 - JSF Output Escaping</h1>\n\n\t<h:form>\n        <h2>Input displayed with direct value expression</h2>\n        <p>#{contact.firstname} #{contact.lastname}</p>\n\n\t\t<h2>Input displayed with &lt;h:outputText /&gt; element</h2>\n\t\t<p><h:outputText value=\"#{contact.firstname}\" /><h:outputText value=\" \" /><h:outputText value=\"#{contact.lastname}\" /></p>\n\t</h:form>\n\n    <a href=\"index.xhtml\">Back</a>\n</h:body>\n</html>"
  },
  {
    "path": "Ch04_OutputEscapingJSF/src/main/webapp/index.xhtml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"\n        \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n<html xmlns=\"http://www.w3.org/1999/xhtml\" xmlns:h=\"http://xmlns.jcp.org/jsf/html\">\n<h:head>\n    <h:outputStylesheet library=\"css\" value=\"styles.css\" name=\"styles.css\" />\n    <title>Chapter 04 - JSF Output Escaping</title>\n</h:head>\n<h:body>\n\t<h1>Chapter 04 - JSF Output Escaping</h1>\n\n    <p>This demo application shows how JavaServer Faces (JSF) handle output escaping with direct value expressions and normal elements/\n        attributes. Feel free to enter any attack data like <strong>&lt;script&gt;alert(&apos;XSS&apos;)&lt;/script&gt;</strong>.</p>\n\n    <h:form id=\"addContact\">\n        <h:panelGrid columns=\"2\">\n            <h:outputLabel value=\"First name\" for=\"firstname\" />\n            <h:inputText value=\"#{contact.firstname}\" label=\"Firstname\" id=\"firstname\"/>\n\n            <h:outputLabel value=\"Last name\" for=\"lastname\" />\n            <h:inputText value=\"#{contact.lastname}\" label=\"Lastname\" id=\"lastname\"/>\n        </h:panelGrid>\n        <h:commandButton value=\"Submit\" action=\"contact\" />\n    </h:form>\n</h:body>\n</html>"
  },
  {
    "path": "Ch04_OutputEscapingJSF/src/main/webapp/resources/css/styles.css",
    "content": "h1 {\n    font-size: 1.5em;\n}\n\nh2 {\n    font-size: 1.2em;\n}\n"
  },
  {
    "path": "Ch04_OutputEscapingJSP/pom.xml",
    "content": "<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n         xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n    <modelVersion>4.0.0</modelVersion>\n    <parent>\n        <groupId>de.dominikschadow.javawebsecurity</groupId>\n        <artifactId>javawebsecurity</artifactId>\n        <version>1.0.0</version>\n    </parent>\n    <artifactId>Ch04_OutputEscapingJSP</artifactId>\n    <packaging>war</packaging>\n    <name>Chapter 04 - JSP Output Escaping</name>\n    <url>https://github.com/dschadow/Java-Web-Security</url>\n    <description>Chapter 4 JSP Output Escaping sample project. Requires a server like Apache Tomcat or the Maven Tomcat plugin. After starting, open the web application in your browser at http://localhost:8080/Ch04_OutputEscapingJSP</description>\n\n    <dependencies>\n        <dependency>\n            <groupId>org.springframework</groupId>\n            <artifactId>spring-webmvc</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>javax.servlet</groupId>\n            <artifactId>javax.servlet-api</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>javax.servlet.jsp</groupId>\n            <artifactId>javax.servlet.jsp-api</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>javax.servlet</groupId>\n            <artifactId>jstl</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>ch.qos.logback</groupId>\n            <artifactId>logback-classic</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>org.springframework</groupId>\n            <artifactId>spring-test</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>org.junit.jupiter</groupId>\n            <artifactId>junit-jupiter-engine</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>org.hamcrest</groupId>\n            <artifactId>hamcrest-library</artifactId>\n        </dependency>\n    </dependencies>\n\n    <build>\n        <finalName>Ch04_OutputEscapingJSP</finalName>\n        <defaultGoal>tomcat7:run-war</defaultGoal>\n        <plugins>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-compiler-plugin</artifactId>\n            </plugin>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-war-plugin</artifactId>\n                <configuration>\n                    <failOnMissingWebXml>false</failOnMissingWebXml>\n                </configuration>\n            </plugin>\n            <plugin>\n                <groupId>org.apache.tomcat.maven</groupId>\n                <artifactId>tomcat7-maven-plugin</artifactId>\n            </plugin>\n        </plugins>\n    </build>\n</project>"
  },
  {
    "path": "Ch04_OutputEscapingJSP/src/main/java/de/dominikschadow/webappsecurity/OutputEscapingWebAppInitializer.java",
    "content": "/*\n * Copyright (C) 2015 Dominik Schadow, info@dominikschadow.de\n *\n * This file is part of the Java-Web-Security project.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *  http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage de.dominikschadow.webappsecurity;\n\nimport org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;\n\n/**\n *\n * @author Dominik Schadow\n */\npublic class OutputEscapingWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {\n    @Override\n    protected Class<?>[] getRootConfigClasses() {\n        return null;\n    }\n\n    @Override\n    protected Class<?>[] getServletConfigClasses() {\n        return new Class[]{WebConfig.class};\n    }\n\n    @Override\n    protected String[] getServletMappings() {\n        return new String[]{\"/\"};\n    }\n}\n"
  },
  {
    "path": "Ch04_OutputEscapingJSP/src/main/java/de/dominikschadow/webappsecurity/WebConfig.java",
    "content": "/*\n * Copyright (C) 2015 Dominik Schadow, info@dominikschadow.de\n *\n * This file is part of the Java-Web-Security project.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *  http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage de.dominikschadow.webappsecurity;\n\nimport org.springframework.context.annotation.Bean;\nimport org.springframework.context.annotation.ComponentScan;\nimport org.springframework.context.annotation.Configuration;\nimport org.springframework.web.servlet.ViewResolver;\nimport org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;\nimport org.springframework.web.servlet.config.annotation.EnableWebMvc;\nimport org.springframework.web.servlet.config.annotation.WebMvcConfigurer;\nimport org.springframework.web.servlet.view.InternalResourceViewResolver;\n\n/**\n * @author Dominik Schadow\n */\n@Configuration\n@EnableWebMvc\n@ComponentScan(\"de.dominikschadow.webappsecurity.controller\")\npublic class WebConfig implements WebMvcConfigurer {\n    @Bean\n    public ViewResolver viewResolver() {\n        InternalResourceViewResolver resolver = new InternalResourceViewResolver();\n        resolver.setPrefix(\"/WEB-INF/views/\");\n        resolver.setSuffix(\".jsp\");\n        resolver.setExposeContextBeansAsAttributes(true);\n        return resolver;\n    }\n\n    @Override\n    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {\n        configurer.enable();\n    }\n}\n"
  },
  {
    "path": "Ch04_OutputEscapingJSP/src/main/java/de/dominikschadow/webappsecurity/controller/ContactController.java",
    "content": "/*\n * Copyright (C) 2015 Dominik Schadow, info@dominikschadow.de\n *\n * This file is part of the Java-Web-Security project.\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * \n *  http://www.apache.org/licenses/LICENSE-2.0\n * \n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage de.dominikschadow.webappsecurity.controller;\n\nimport de.dominikschadow.webappsecurity.domain.Contact;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.stereotype.Controller;\nimport org.springframework.ui.Model;\nimport org.springframework.web.bind.annotation.ModelAttribute;\nimport org.springframework.web.bind.annotation.RequestMapping;\nimport org.springframework.web.bind.annotation.RequestMethod;\nimport org.springframework.web.bind.annotation.SessionAttributes;\n\n/**\n * \n * @author Dominik Schadow\n */\n@Controller\n@SessionAttributes\npublic class ContactController {\n    private static final Logger LOGGER = LoggerFactory.getLogger(ContactController.class);\n\n    @RequestMapping(value = \"/addContact\", method = RequestMethod.POST)\n    public String addContact(@ModelAttribute Contact contact, Model model) {\n        LOGGER.info(\"Contact first name: {}, last name: {}\", contact.getFirstname(), contact.getLastname());\n\n        model.addAttribute(\"contact\", contact);\n\n        return \"contact\";\n    }\n}\n"
  },
  {
    "path": "Ch04_OutputEscapingJSP/src/main/java/de/dominikschadow/webappsecurity/controller/IndexController.java",
    "content": "/*\n * Copyright (C) 2015 Dominik Schadow, info@dominikschadow.de\n *\n * This file is part of the Java-Web-Security project.\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * \n *  http://www.apache.org/licenses/LICENSE-2.0\n * \n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage de.dominikschadow.webappsecurity.controller;\n\nimport org.springframework.stereotype.Controller;\nimport org.springframework.web.bind.annotation.RequestMapping;\n\nimport static org.springframework.web.bind.annotation.RequestMethod.GET;\n\n/**\n * Controller to handle GET requests for the home page.\n *\n * @author Dominik Schadow\n */\n@Controller\n@RequestMapping(value = \"/\")\npublic class IndexController {\n    @RequestMapping(method = GET)\n    public String index() {\n        return \"index\";\n    }\n}\n"
  },
  {
    "path": "Ch04_OutputEscapingJSP/src/main/java/de/dominikschadow/webappsecurity/domain/Contact.java",
    "content": "/*\n * Copyright (C) 2015 Dominik Schadow, info@dominikschadow.de\n *\n * This file is part of the Java-Web-Security project.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *  http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage de.dominikschadow.webappsecurity.domain;\n\n/**\n * \n * @author Dominik Schadow\n */\npublic class Contact {\n    private String firstname;\n    private String lastname;\n\n    public String getFirstname() {\n        return firstname;\n    }\n\n    public void setFirstname(String firstname) {\n        this.firstname = firstname;\n    }\n\n    public String getLastname() {\n        return lastname;\n    }\n\n    public void setLastname(String lastname) {\n        this.lastname = lastname;\n    }\n}\n"
  },
  {
    "path": "Ch04_OutputEscapingJSP/src/main/resources/logback.xml",
    "content": "<configuration>\n    <appender name=\"STDOUT\" class=\"ch.qos.logback.core.ConsoleAppender\">\n        <encoder>\n            <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>\n        </encoder>\n    </appender>\n\n    <root level=\"INFO\">\n        <appender-ref ref=\"STDOUT\" />\n    </root>\n</configuration>"
  },
  {
    "path": "Ch04_OutputEscapingJSP/src/main/webapp/WEB-INF/views/contact.jsp",
    "content": "<%@ page language=\"java\" contentType=\"text/html; charset=UTF-8\" pageEncoding=\"UTF-8\"%>\n<%@ taglib prefix=\"c\" uri=\"http://java.sun.com/jsp/jstl/core\" %>\n<%@ taglib prefix=\"s\" uri=\"http://www.springframework.org/tags\" %>\n<html>\n    <head>\n        <meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n        <link rel=\"stylesheet\" type=\"text/css\" href=\"<c:url value=\"/resources/styles.css\" />\" >\n        <title>Chapter 04 - JSP Output Escaping</title>\n    </head>\n    <body>\n        <h1>Chapter 04 - JSP Output Escaping</h1>\n\n        <h2>Input displayed as direct value expression</h2>\n        <p>${contact.firstname} ${contact.lastname}</p>\n\n        <h2>Input displayed as out element</h2>\n        <p><c:out value=\"${contact.firstname}\" /> <c:out value=\"${contact.lastname}\" /></p>\n\n        <h2>Input displayed inside Spring escapeBody element as direct value expression</h2>\n        <p><s:escapeBody htmlEscape=\"true\">${contact.firstname} ${contact.lastname}</s:escapeBody></p>\n\n        <a href=\"<c:url value=\"/\" />\">Back</a>\n    </body>\n</html>"
  },
  {
    "path": "Ch04_OutputEscapingJSP/src/main/webapp/WEB-INF/views/index.jsp",
    "content": "<%@ page session=\"false\" %>\n<%@ page language=\"java\" contentType=\"text/html; charset=UTF-8\" pageEncoding=\"UTF-8\"%>\n<%@ taglib prefix=\"c\" uri=\"http://java.sun.com/jsp/jstl/core\" %>\n<html>\n<head>\n    <meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"<c:url value=\"/resources/styles.css\" />\" >\n    <title>Chapter 04 - JSP Output Escaping</title>\n</head>\n<body>\n\t<h1>Chapter 04 - JSP Output Escaping</h1>\n\n\t<p>This demo application shows how JavaServer Pages (JSP) handle output escaping with direct value expressions and\n        normal elements/ attributes. Feel free to enter any attack data like <strong>&lt;script&gt;alert(&apos;XSS&apos;)&lt;/script&gt;</strong>.</p>\n\n\t<form method=\"post\" action=\"addContact\">\n\t\t<fieldset>\n\t\t\t<legend>Add new contact</legend>\n\t\t\t<label for=\"firstname\" title=\"First name\">First name</label>\n\t\t\t<input type=\"text\" id=\"firstname\" name=\"firstname\" class=\"text-input\" />\n\t\t\t<label for=\"lastname\" title=\"Last name\">Last name</label>\n\t\t\t<input type=\"text\" id=\"lastname\" name=\"lastname\" class=\"text-input\" />\n\t\t\t<input type=\"submit\" value=\"Submit\" />\n\t\t</fieldset>\n\t</form>\n</body>\n</html>"
  },
  {
    "path": "Ch04_OutputEscapingJSP/src/main/webapp/resources/styles.css",
    "content": "h1 {\n    font-size: 1.5em;\n}\n\nh2 {\n    font-size: 1.2em;\n}\n\nfieldset {\n    width: 600px;\n    font-size: 1.2em;\n    margin-top: 20px;\n}\n\ninput {\n    display: inline-block;\n    vertical-align: middle;\n    width: 150px;\n}\n\ninput[type=submit] {\n    width: 75px;\n    height: 20px;\n    margin-left: 10px;\n}\n\nlabel {\n    margin-right: 10px;\n}\n"
  },
  {
    "path": "Ch04_OutputEscapingJSP/src/test/java/de/dominikschadow/webappsecurity/controller/ContactControllerTest.java",
    "content": "/*\n * Copyright (C) 2015 Dominik Schadow, info@dominikschadow.de\n *\n * This file is part of the Java-Web-Security project.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *  http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage de.dominikschadow.webappsecurity.controller;\n\nimport org.junit.jupiter.api.Test;\nimport org.springframework.test.web.servlet.MockMvc;\n\nimport static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;\nimport static org.springframework.test.web.servlet.result.MockMvcResultMatchers.view;\nimport static org.springframework.test.web.servlet.setup.MockMvcBuilders.standaloneSetup;\n\n/**\n *\n * @author Dominik Schadow\n */\npublic class ContactControllerTest {\n    @Test\n    public void testContactPage() throws Exception {\n        ContactController controller = new ContactController();\n        MockMvc mockMvc = standaloneSetup(controller).build();\n\n        mockMvc.perform(post(\"/addContact\")).andExpect(view().name(\"contact\"));\n    }\n}\n"
  },
  {
    "path": "Ch04_OutputEscapingJSP/src/test/java/de/dominikschadow/webappsecurity/controller/IndexControllerTest.java",
    "content": "/*\n * Copyright (C) 2015 Dominik Schadow, info@dominikschadow.de\n *\n * This file is part of the Java-Web-Security project.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *  http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage de.dominikschadow.webappsecurity.controller;\n\nimport org.junit.jupiter.api.Test;\nimport org.springframework.test.web.servlet.MockMvc;\n\nimport static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;\nimport static org.springframework.test.web.servlet.result.MockMvcResultMatchers.view;\nimport static org.springframework.test.web.servlet.setup.MockMvcBuilders.standaloneSetup;\n\n/**\n *\n * @author Dominik Schadow\n */\npublic class IndexControllerTest {\n    @Test\n    public void testIndexPage() throws Exception {\n        IndexController controller = new IndexController();\n        MockMvc mockMvc = standaloneSetup(controller).build();\n\n        mockMvc.perform(get(\"/\")).andExpect(view().name(\"index\"));\n    }\n}\n"
  },
  {
    "path": "Ch05_AccessReferenceMaps/pom.xml",
    "content": "<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n\t<modelVersion>4.0.0</modelVersion>\n\t<parent>\n\t\t<groupId>de.dominikschadow.javawebsecurity</groupId>\n\t\t<artifactId>javawebsecurity</artifactId>\n\t\t<version>1.0.0</version>\n\t</parent>\n\t<artifactId>Ch05_AccessReferenceMaps</artifactId>\n\t<packaging>war</packaging>\n\t<name>Chapter 05 - Access Reference Maps</name>\n\t<url>https://github.com/dschadow/Java-Web-Security</url>\n    <description>Chapter 5 Access Reference sample project. Requires a server like Apache Tomcat or the Maven Tomcat plugin. After starting, open the web application in your browser at http://localhost:8080/Ch05_AccessReferenceMaps</description>\n\n    <dependencies>\n        <dependency>\n            <groupId>com.sun.faces</groupId>\n            <artifactId>jsf-api</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>com.sun.faces</groupId>\n            <artifactId>jsf-impl</artifactId>\n        </dependency>\n\t\t<dependency>\n\t\t\t<groupId>org.owasp.esapi</groupId>\n\t\t\t<artifactId>esapi</artifactId>\n\t\t</dependency>\n\t\t<dependency>\n            <groupId>com.h2database</groupId>\n            <artifactId>h2</artifactId>\n\t\t</dependency>\n        <dependency>\n            <groupId>org.hibernate</groupId>\n            <artifactId>hibernate-core</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>ch.qos.logback</groupId>\n            <artifactId>logback-classic</artifactId>\n        </dependency>\n\t</dependencies>\n\t\n\t<build>\n        <finalName>Ch05_AccessReferenceMaps</finalName>\n        <defaultGoal>tomcat7:run-war</defaultGoal>\n\t\t<plugins>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-compiler-plugin</artifactId>\n            </plugin>\n            <plugin>\n                <groupId>org.apache.tomcat.maven</groupId>\n                <artifactId>tomcat7-maven-plugin</artifactId>\n                <configuration>\n                    <contextFile>${project.basedir}/src/main/resources/context.xml</contextFile>\n                </configuration>\n            </plugin>\n\t\t</plugins>\n\t</build>\n</project>"
  },
  {
    "path": "Ch05_AccessReferenceMaps/src/main/java/de/dominikschadow/webappsecurity/AccountController.java",
    "content": "/*\n * Copyright (C) 2015 Dominik Schadow, info@dominikschadow.de\n *\n * This file is part of the Java-Web-Security project.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *  http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage de.dominikschadow.webappsecurity;\n\nimport de.dominikschadow.webappsecurity.domain.Account;\n\nimport javax.faces.bean.ManagedBean;\nimport javax.faces.bean.SessionScoped;\nimport java.io.Serializable;\nimport java.util.ArrayList;\nimport java.util.List;\n\n/**\n * Managed bean to access an account by account id. Does not verify the given account id and therefore does not\n * provide any protection.\n *\n * @author Dominik Schadow\n */\n@ManagedBean(name = \"account\")\n@SessionScoped\npublic class AccountController implements Serializable {\n    private Account account;\n    private int userId = 42;\n    private int accountId = 1;\n    private transient AccountsDAO dao;\n    private List<String> accountReferences = new ArrayList<>();\n\n    public int getAccountId() {\n        return accountId;\n    }\n\n    public void setAccountId(int accountId) {\n        this.accountId = accountId;\n    }\n\n    public int getUserId() {\n        return userId;\n    }\n\n    public Account getAccount() {\n        return account;\n    }\n\n    public List<String> getAccountReferences() {\n        return accountReferences;\n    }\n\n    public AccountController() {\n        dao = new AccountsDAO();\n\n        accountReferences = dao.getAccountsForUser(userId);\n    }\n\n    public String show() {\n        account = dao.loadAccount(accountId);\n\n        return \"account\";\n    }\n}\n"
  },
  {
    "path": "Ch05_AccessReferenceMaps/src/main/java/de/dominikschadow/webappsecurity/AccountIntegerController.java",
    "content": "/*\n * Copyright (C) 2015 Dominik Schadow, info@dominikschadow.de\n *\n * This file is part of the Java-Web-Security project.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *  http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage de.dominikschadow.webappsecurity;\n\nimport de.dominikschadow.webappsecurity.domain.Account;\nimport de.dominikschadow.webappsecurity.domain.User;\n\nimport javax.faces.bean.ManagedBean;\nimport javax.faces.bean.SessionScoped;\nimport java.io.Serializable;\nimport java.util.ArrayList;\nimport java.util.List;\n\n/**\n * Managed bean to access an account by account reference (IntegerAccessReferenceMap). Only accounts belonging to the\n * current user are contained in this map.\n *\n * @author Dominik Schadow\n */\n@ManagedBean(name = \"accountInteger\")\n@SessionScoped\npublic class AccountIntegerController implements Serializable {\n    private List<String> accountReferences = new ArrayList<>();\n    private int iaAccountId = 1;\n    private int userId = 42;\n    private transient AccountsIntegerDAO dao;\n\n    public int getIaAccountId() {\n        return iaAccountId;\n    }\n\n    public void setIaAccountId(int iaAccountId) {\n        this.iaAccountId = iaAccountId;\n    }\n\n    public int getUserId() {\n        return userId;\n    }\n\n    public Account getAccount() {\n        return dao.retrieveAccount(iaAccountId);\n    }\n\n    public List<String> getAccountReferences() {\n        return accountReferences;\n    }\n\n    public AccountIntegerController() {\n        User currentUser = new User();\n        currentUser.setUserId(userId);\n\n        dao = new AccountsIntegerDAO();\n        accountReferences = dao.loadAccountsForUser(currentUser);\n    }\n\n    public String show() {\n        return \"accountInteger\";\n    }\n}\n"
  },
  {
    "path": "Ch05_AccessReferenceMaps/src/main/java/de/dominikschadow/webappsecurity/AccountRandomController.java",
    "content": "/*\n * Copyright (C) 2015 Dominik Schadow, info@dominikschadow.de\n *\n * This file is part of the Java-Web-Security project.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *  http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage de.dominikschadow.webappsecurity;\n\nimport de.dominikschadow.webappsecurity.domain.Account;\nimport de.dominikschadow.webappsecurity.domain.User;\n\nimport javax.faces.bean.ManagedBean;\nimport javax.faces.bean.SessionScoped;\nimport java.io.Serializable;\nimport java.util.ArrayList;\nimport java.util.List;\n\n/**\n * Managed bean to access an account by account reference (RandomAccessReferenceMap). Only accounts belonging to the\n * current user are contained in this map.\n *\n * @author Dominik Schadow\n */\n@ManagedBean(name = \"accountRandom\")\n@SessionScoped\npublic class AccountRandomController implements Serializable {\n    private List<String> accountReferences = new ArrayList<>();\n    private String raAccountId = \"\";\n    private int userId = 42;\n    private transient AccountsRandomDAO dao;\n\n    public String getRaAccountId() {\n        return raAccountId;\n    }\n\n    public void setRaAccountId(String raAccountId) {\n        this.raAccountId = raAccountId;\n    }\n\n    public int getUserId() {\n        return userId;\n    }\n\n    public Account getAccount() {\n        return dao.retrieveAccount(raAccountId);\n    }\n\n    public List<String> getAccountReferences() {\n        return accountReferences;\n    }\n\n    public AccountRandomController() {\n        User currentUser = new User();\n        currentUser.setUserId(userId);\n\n        dao = new AccountsRandomDAO();\n        accountReferences = dao.loadAccountsForUser(currentUser);\n    }\n\n    public String show() {\n        return \"accountRandom\";\n    }\n}\n"
  },
  {
    "path": "Ch05_AccessReferenceMaps/src/main/java/de/dominikschadow/webappsecurity/AccountsDAO.java",
    "content": "/*\n * Copyright (C) 2015 Dominik Schadow, info@dominikschadow.de\n *\n * This file is part of the Java-Web-Security project.\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * \n *  http://www.apache.org/licenses/LICENSE-2.0\n * \n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage de.dominikschadow.webappsecurity;\n\nimport de.dominikschadow.webappsecurity.domain.Account;\nimport org.hibernate.HibernateException;\nimport org.hibernate.Session;\nimport org.hibernate.query.Query;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\nimport static de.dominikschadow.webappsecurity.HibernateUtil.getSessionFactory;\n\n/**\n * Loads accounts from the in-memory-database for the unprotected managed bean.\n *\n * @author Dominik Schadow\n * @see AccountController\n */\npublic class AccountsDAO {\n    private static final Logger LOGGER = LoggerFactory.getLogger(AccountsDAO.class);\n\n    public List<String> getAccountsForUser(int userId) {\n        return queryAccounts(userId);\n    }\n\n    public Account loadAccount(int id) {\n        return queryAccount(id);\n    }\n\n    private Account queryAccount(int id) {\n        try (Session session = getSessionFactory().openSession()) {\n            Query query = session.createQuery(\"FROM Account WHERE accountId = :id\");\n            query.setParameter(\"id\", id);\n\n            return (Account) query.uniqueResult();\n        } catch (HibernateException ex) {\n            LOGGER.error(ex.getMessage(), ex);\n        }\n\n        return null;\n    }\n\n    private List<String> queryAccounts(int userId) {\n        List<String> accountReferences = new ArrayList<>();\n\n        try (Session session = getSessionFactory().openSession()) {\n            Query query = session.createNativeQuery(\"SELECT accountId FROM account WHERE ownerId = :id\");\n            query.setParameter(\"id\", userId);\n\n            accountReferences = query.list();\n\n            LOGGER.info(\"Found {} account references\", accountReferences.size());\n        } catch (HibernateException ex) {\n            LOGGER.error(ex.getMessage(), ex);\n        }\n\n        return accountReferences;\n    }\n}\n"
  },
  {
    "path": "Ch05_AccessReferenceMaps/src/main/java/de/dominikschadow/webappsecurity/AccountsIntegerDAO.java",
    "content": "/*\n * Copyright (C) 2015 Dominik Schadow, info@dominikschadow.de\n *\n * This file is part of the Java-Web-Security project.\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * \n *  http://www.apache.org/licenses/LICENSE-2.0\n * \n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage de.dominikschadow.webappsecurity;\n\nimport de.dominikschadow.webappsecurity.domain.Account;\nimport de.dominikschadow.webappsecurity.domain.User;\nimport org.owasp.esapi.errors.AccessControlException;\nimport org.owasp.esapi.reference.IntegerAccessReferenceMap;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\nimport static de.dominikschadow.webappsecurity.HibernateUtil.queryUserAccounts;\n\n/**\n * Loads accounts from the in-memory-database for the protected managed bean.\n *\n * @author Dominik Schadow\n * @see AccountIntegerController\n */\npublic class AccountsIntegerDAO {\n    private IntegerAccessReferenceMap accounts = new IntegerAccessReferenceMap();\n    private static final Logger LOGGER = LoggerFactory.getLogger(AccountsIntegerDAO.class);\n\n    public Account retrieveAccount(int accountId) {\n        String accountReference = String.valueOf(accountId);\n\n        try {\n            return accounts.getDirectReference(accountReference);\n        } catch (AccessControlException ex) {\n            LOGGER.error(\"Access to \" + accountReference + \" denied\", ex);\n\n            return null;\n        }\n    }\n\n    public List<String> loadAccountsForUser(User user) {\n        return queryAccounts(user);\n    }\n\n    private List<String> queryAccounts(User user) {\n        List<Account> ownAccounts = queryUserAccounts(user);\n        LOGGER.info(\"Found {} account references\", ownAccounts.size());\n\n        List<String> accountReferences = new ArrayList<>();\n        for (Account account : ownAccounts) {\n            accounts.addDirectReference(account);\n            accountReferences.add(accounts.getIndirectReference(account));\n        }\n\n        return accountReferences;\n    }\n}\n"
  },
  {
    "path": "Ch05_AccessReferenceMaps/src/main/java/de/dominikschadow/webappsecurity/AccountsRandomDAO.java",
    "content": "/*\n * Copyright (C) 2015 Dominik Schadow, info@dominikschadow.de\n *\n * This file is part of the Java-Web-Security project.\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * \n *  http://www.apache.org/licenses/LICENSE-2.0\n * \n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage de.dominikschadow.webappsecurity;\n\nimport de.dominikschadow.webappsecurity.domain.Account;\nimport de.dominikschadow.webappsecurity.domain.User;\nimport org.owasp.esapi.errors.AccessControlException;\nimport org.owasp.esapi.reference.RandomAccessReferenceMap;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\nimport static de.dominikschadow.webappsecurity.HibernateUtil.queryUserAccounts;\n\n/**\n * Loads accounts from the in-memory-database for the protected managed bean.\n *\n * @author Dominik Schadow\n * @see AccountRandomController\n */\npublic class AccountsRandomDAO {\n    private RandomAccessReferenceMap accounts = new RandomAccessReferenceMap();\n    private static final Logger LOGGER = LoggerFactory.getLogger(AccountsRandomDAO.class);\n\n    public Account retrieveAccount(String accountReference) {\n        try {\n            return accounts.getDirectReference(accountReference);\n        } catch (AccessControlException ex) {\n            LOGGER.error(\"Access to \" + accountReference + \" denied\", ex);\n\n            return null;\n        }\n    }\n\n    public List<String> loadAccountsForUser(User user) {\n        return queryAccounts(user);\n    }\n\n    private List<String> queryAccounts(User user) {\n        List<Account> ownAccounts = queryUserAccounts(user);\n        LOGGER.info(\"Found {} account references\", ownAccounts.size());\n\n        List<String> accountReferences = new ArrayList<>();\n        for (Account account : ownAccounts) {\n            accounts.addDirectReference(account);\n            accountReferences.add(accounts.getIndirectReference(account));\n        }\n\n        return accountReferences;\n    }\n}\n"
  },
  {
    "path": "Ch05_AccessReferenceMaps/src/main/java/de/dominikschadow/webappsecurity/HibernateUtil.java",
    "content": "/*\n * Copyright (C) 2015 Dominik Schadow, info@dominikschadow.de\n *\n * This file is part of the Java-Web-Security project.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *  http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage de.dominikschadow.webappsecurity;\n\nimport de.dominikschadow.webappsecurity.domain.Account;\nimport de.dominikschadow.webappsecurity.domain.User;\nimport org.hibernate.Session;\nimport org.hibernate.SessionFactory;\nimport org.hibernate.cfg.Configuration;\nimport org.hibernate.query.Query;\n\nimport java.util.List;\n\n/**\n * @author Dominik Schadow\n */\npublic class HibernateUtil {\n    static SessionFactory sessionFactory;\n\n    /**\n     * Util class, no constructor required.\n     */\n    private HibernateUtil() {\n    }\n\n    public static SessionFactory getSessionFactory() {\n        if (sessionFactory == null) {\n            sessionFactory = new Configuration().configure().buildSessionFactory();\n        }\n\n        return sessionFactory;\n    }\n\n    public static List<Account> queryUserAccounts(User user) {\n        Session session = getSessionFactory().openSession();\n        Query query = session.createQuery(\"FROM Account WHERE ownerId = :id\");\n        query.setParameter(\"id\", user.getUserId());\n\n        List<Account> accounts = query.list();\n\n        session.close();\n\n        return accounts;\n    }\n}\n"
  },
  {
    "path": "Ch05_AccessReferenceMaps/src/main/java/de/dominikschadow/webappsecurity/domain/Account.java",
    "content": "/*\n * Copyright (C) 2015 Dominik Schadow, info@dominikschadow.de\n *\n * This file is part of the Java-Web-Security project.\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * \n *  http://www.apache.org/licenses/LICENSE-2.0\n * \n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage de.dominikschadow.webappsecurity.domain;\n\nimport javax.persistence.Entity;\nimport javax.persistence.Id;\nimport java.io.Serializable;\n\n/**\n * Simple account object representing one user account.\n *\n * @author Dominik Schadow\n */\n@Entity\npublic class Account implements Serializable {\n    @Id\n    private int accountId;\n    private String name;\n    private String type;\n    private int ownerId;\n\n    public int getAccountId() {\n        return accountId;\n    }\n\n    public void setAccountId(int accountId) {\n        this.accountId = accountId;\n    }\n\n    public String getName() {\n        return name;\n    }\n\n    public void setName(String name) {\n        this.name = name;\n    }\n\n    public String getType() {\n        return type;\n    }\n\n    public void setType(String type) {\n        this.type = type;\n    }\n\n    public int getOwnerId() {\n        return ownerId;\n    }\n\n    public void setOwnerId(int ownerId) {\n        this.ownerId = ownerId;\n    }\n}\n"
  },
  {
    "path": "Ch05_AccessReferenceMaps/src/main/java/de/dominikschadow/webappsecurity/domain/User.java",
    "content": "/*\n * Copyright (C) 2015 Dominik Schadow, info@dominikschadow.de\n *\n * This file is part of the Java-Web-Security project.\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * \n *  http://www.apache.org/licenses/LICENSE-2.0\n * \n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage de.dominikschadow.webappsecurity.domain;\n\nimport javax.persistence.Entity;\nimport javax.persistence.Id;\nimport java.io.Serializable;\n\n/**\n * Represents a simple user.\n *\n * @author Dominik Schadow\n */\n@Entity\npublic class User implements Serializable {\n    @Id\n    private int userId;\n    private String name;\n\n    public int getUserId() {\n        return userId;\n    }\n\n    public void setUserId(int userId) {\n        this.userId = userId;\n    }\n\n    public String getName() {\n        return name;\n    }\n\n    public void setName(String name) {\n        this.name = name;\n    }\n}\n"
  },
  {
    "path": "Ch05_AccessReferenceMaps/src/main/resources/ESAPI.properties",
    "content": "# Logging\nLogger.ApplicationName=Ch05_AccessReferenceMaps"
  },
  {
    "path": "Ch05_AccessReferenceMaps/src/main/resources/context.xml",
    "content": "<?xml version='1.0' encoding='utf-8'?>\n<Context useHttpOnly=\"false\">\n    <Resource name=\"mapDS\" auth=\"Container\" type=\"javax.sql.DataSource\"\n              maxActive=\"100\" maxIdle=\"30\" maxWait=\"10000\"\n              username=\"sa\" password=\"sa\" driverClassName=\"org.h2.Driver\"\n              url=\"jdbc:h2:mem:mapDS\"/>\n</Context>"
  },
  {
    "path": "Ch05_AccessReferenceMaps/src/main/resources/hibernate.cfg.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!DOCTYPE hibernate-configuration PUBLIC\n        \"-//Hibernate/Hibernate Configuration DTD//EN\"\n        \"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd\">\n<hibernate-configuration>\n    <session-factory>\n        <property name=\"hibernate.dialect\">org.hibernate.dialect.H2Dialect</property>\n        <property name=\"hibernate.connection.datasource\">java:comp/env/mapDS</property>\n        <property name=\"hibernate.hbm2ddl.auto\">create-drop</property>\n        <property name=\"show_sql\">false</property>\n        <mapping package=\"de.dominikschadow.webappsecurity.domain\"/>\n        <mapping class=\"de.dominikschadow.webappsecurity.domain.Account\"/>\n        <mapping class=\"de.dominikschadow.webappsecurity.domain.User\"/>\n    </session-factory>\n</hibernate-configuration>"
  },
  {
    "path": "Ch05_AccessReferenceMaps/src/main/resources/import.sql",
    "content": "INSERT INTO ACCOUNT (accountid, name, type, ownerid) VALUES (1, 'Marvin Savings', 'Savings', 42);\nINSERT INTO ACCOUNT (accountid, name, type, ownerid) VALUES (2, 'Marvin Credit Card',' Credit Card', 42);\nINSERT INTO ACCOUNT (accountid, name, type, ownerid) VALUES (3, 'Zaphod Savings',' Savings', 55);\nINSERT INTO ACCOUNT (accountid, name, type, ownerid) VALUES (4, 'Ford Prefect Credit Card', 'Credit Card', 10);\nINSERT INTO ACCOUNT (accountid, name, type, ownerid) VALUES (5, 'Ford Prefect Savings', 'Savings', 10);"
  },
  {
    "path": "Ch05_AccessReferenceMaps/src/main/resources/logback.xml",
    "content": "<configuration>\n    <appender name=\"STDOUT\" class=\"ch.qos.logback.core.ConsoleAppender\">\n        <encoder>\n            <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>\n        </encoder>\n    </appender>\n\n    <root level=\"INFO\">\n        <appender-ref ref=\"STDOUT\" />\n    </root>\n</configuration>"
  },
  {
    "path": "Ch05_AccessReferenceMaps/src/main/webapp/WEB-INF/faces-config.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<faces-config version=\"2.2\"\n              xmlns=\"http://xmlns.jcp.org/xml/ns/javaee\"\n              xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n              xsi:schemaLocation=\"http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-facesconfig_2_2.xsd\">\n</faces-config>"
  },
  {
    "path": "Ch05_AccessReferenceMaps/src/main/webapp/WEB-INF/web.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<web-app xmlns=\"http://xmlns.jcp.org/xml/ns/javaee\"\n         xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n         xsi:schemaLocation=\"http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd\"\n         version=\"3.1\">\n    <display-name>Ch05_AccessReferenceMaps</display-name>\n\n    <context-param>\n        <param-name>javax.faces.PROJECT_STAGE</param-name>\n        <param-value>Development</param-value>\n    </context-param>\n\n    <servlet>\n        <servlet-name>Faces Servlet</servlet-name>\n        <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>\n        <load-on-startup>1</load-on-startup>\n    </servlet>\n\n    <servlet-mapping>\n        <servlet-name>Faces Servlet</servlet-name>\n        <url-pattern>*.xhtml</url-pattern>\n    </servlet-mapping>\n\n    <welcome-file-list>\n        <welcome-file>index.xhtml</welcome-file>\n    </welcome-file-list>\n</web-app>"
  },
  {
    "path": "Ch05_AccessReferenceMaps/src/main/webapp/account.xhtml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"\n        \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n<html xmlns=\"http://www.w3.org/1999/xhtml\" xmlns:h=\"http://xmlns.jcp.org/jsf/html\">\n<h:head>\n    <h:outputStylesheet library=\"css\" value=\"styles.css\" name=\"styles.css\" />\n    <title>Chapter 05 - Access Reference Maps</title>\n</h:head>\n<h:body>\n\t<h1>Chapter 05 - Access Reference Maps</h1>\n\n    <p>Account details (user id #{account.userId}).</p>\n\n    <h:panelGrid columns=\"2\" rendered=\"#{account.account != null}\">\n        <strong>Account name</strong> <h:outputText value=\"#{account.account.name}\" />\n        <strong>Account type</strong> <h:outputText value=\"#{account.account.type}\" />\n        <strong>Account id</strong> <h:outputText value=\"#{account.account.accountId}\" />\n        <strong>Account owner</strong> <h:outputText value=\"#{account.account.ownerId}\" />\n    </h:panelGrid>\n\n    <h:panelGrid columns=\"1\" rendered=\"#{account.account == null}\">\n        <p>No account found</p>\n    </h:panelGrid>\n\n    <p><a href=\"index.xhtml\">Back</a></p>\n</h:body>\n</html>"
  },
  {
    "path": "Ch05_AccessReferenceMaps/src/main/webapp/accountInteger.xhtml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"\n        \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n<html xmlns=\"http://www.w3.org/1999/xhtml\" xmlns:h=\"http://xmlns.jcp.org/jsf/html\">\n<h:head>\n    <h:outputStylesheet library=\"css\" value=\"styles.css\" name=\"styles.css\" />\n    <title>Chapter 05 - Access Reference Maps</title>\n</h:head>\n<h:body>\n\t<h1>Chapter 05 - Access Reference Maps</h1>\n\n    <p>Account details (user id #{accountInteger.userId}).</p>\n\n    <h:panelGrid columns=\"2\" rendered=\"#{accountInteger.account != null}\">\n        <strong>Account name</strong> <h:outputText value=\"#{accountInteger.account.name}\" />\n        <strong>Account type</strong> <h:outputText value=\"#{accountInteger.account.type}\" />\n        <strong>Account id</strong> <h:outputText value=\"#{accountInteger.account.accountId}\" />\n        <strong>Account owner</strong> <h:outputText value=\"#{accountInteger.account.ownerId}\" />\n    </h:panelGrid>\n\n    <h:panelGrid columns=\"1\" rendered=\"#{accountInteger.account == null}\">\n        <p>No account found</p>\n    </h:panelGrid>\n\n    <p><a href=\"index.xhtml\">Back</a></p>\n</h:body>\n</html>"
  },
  {
    "path": "Ch05_AccessReferenceMaps/src/main/webapp/accountRandom.xhtml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"\n        \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n<html xmlns=\"http://www.w3.org/1999/xhtml\" xmlns:h=\"http://xmlns.jcp.org/jsf/html\">\n<h:head>\n    <h:outputStylesheet library=\"css\" value=\"styles.css\" name=\"styles.css\" />\n    <title>Chapter 05 - Access Reference Maps</title>\n</h:head>\n<h:body>\n\t<h1>Chapter 05 - Access Reference Maps</h1>\n\n    <p>Account details (user id #{accountRandom.userId}).</p>\n\n    <h:panelGrid columns=\"2\" rendered=\"#{accountRandom.account != null}\">\n        <strong>Account name</strong> <h:outputText value=\"#{accountRandom.account.name}\" />\n        <strong>Account type</strong> <h:outputText value=\"#{accountRandom.account.type}\" />\n        <strong>Account id</strong> <h:outputText value=\"#{accountRandom.account.accountId}\" />\n        <strong>Account owner</strong> <h:outputText value=\"#{accountRandom.account.ownerId}\" />\n    </h:panelGrid>\n\n    <h:panelGrid columns=\"1\" rendered=\"#{accountRandom.account == null}\">\n        <p>No account found</p>\n    </h:panelGrid>\n\n    <p><a href=\"index.xhtml\">Back</a></p>\n</h:body>\n</html>"
  },
  {
    "path": "Ch05_AccessReferenceMaps/src/main/webapp/index.xhtml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"\n        \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n<html xmlns=\"http://www.w3.org/1999/xhtml\" xmlns:h=\"http://xmlns.jcp.org/jsf/html\"\n      xmlns:f=\"http://xmlns.jcp.org/jsf/core\">\n<h:head>\n    <h:outputStylesheet library=\"css\" value=\"styles.css\" name=\"styles.css\"/>\n    <title>Chapter 05 - Access Reference Maps</title>\n</h:head>\n<h:body>\n    <h1>Chapter 05 - Access Reference Maps</h1>\n\n    <p>Your user id is <strong>#{account.userId}</strong>.</p>\n\n    <h2>Unprotected</h2>\n\n    <p>Valid account references for user id #{account.userId} are <h:outputText\n            value=\"#{account.accountReferences}\"/>. All accounts between 1 and 5 are accessible.</p>\n\n    <h:form id=\"unprotected\">\n        <h:panelGrid columns=\"3\">\n            <h:outputLabel value=\"Account ID\" for=\"accountId\"/>\n            <h:inputText label=\"Account ID\" value=\"#{account.accountId}\" id=\"accountId\">\n                <f:validateLongRange minimum=\"1\" maximum=\"100\"/>\n            </h:inputText>\n            <h:commandButton value=\"Submit\" action=\"#{account.show}\" styleClass=\"send-button\"/>\n        </h:panelGrid>\n    </h:form>\n\n    <h2>Protected by IntegerAccessReferenceMap</h2>\n\n    <p>Valid account references for user id #{accountInteger.userId} are <h:outputText\n            value=\"#{accountInteger.accountReferences}\"/>. Only these accounts are accessible.</p>\n\n    <h:form id=\"protectedInteger\">\n        <h:panelGrid columns=\"3\">\n            <h:outputLabel value=\"Account Reference\" for=\"iaAccountId\"/>\n            <h:inputText label=\"Account Reference\" value=\"#{accountInteger.iaAccountId}\" id=\"iaAccountId\">\n                <f:validateLongRange minimum=\"1\" maximum=\"100\"/>\n            </h:inputText>\n            <h:commandButton value=\"Submit\" action=\"#{accountInteger.show}\" styleClass=\"send-button\"/>\n        </h:panelGrid>\n    </h:form>\n\n    <h2>Protected by RandomAccessReferenceMap</h2>\n\n    <p>Valid account references for user id #{accountRandom.userId} are <h:outputText\n            value=\"#{accountRandom.accountReferences}\"/>. Only these accounts are accessible.</p>\n\n    <h:form id=\"protectedRandom\">\n        <h:panelGrid columns=\"3\">\n            <h:outputLabel value=\"Account Reference\" for=\"raAccountId\"/>\n            <h:inputText label=\"Account Reference\" value=\"#{accountRandom.raAccountId}\" id=\"raAccountId\"/>\n            <h:commandButton value=\"Submit\" action=\"#{accountRandom.show}\" styleClass=\"send-button\"/>\n        </h:panelGrid>\n    </h:form>\n</h:body>\n</html>"
  },
  {
    "path": "Ch05_AccessReferenceMaps/src/main/webapp/resources/css/styles.css",
    "content": ".send-button {\n    margin-left: 25px;\n}\n\nh1 {\n    font-size: 1.5em;\n}\n\nh2 {\n    font-size: 1.2em;\n}\n"
  },
  {
    "path": "Ch05_HSTS/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n         xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n         xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n    <modelVersion>4.0.0</modelVersion>\n    <parent>\n        <artifactId>javawebsecurity</artifactId>\n        <groupId>de.dominikschadow.javawebsecurity</groupId>\n        <version>1.0.0</version>\n    </parent>\n    <artifactId>Ch05_HSTS</artifactId>\n    <packaging>war</packaging>\n    <name>Chapter 05 - HSTS</name>\n    <url>https://github.com/dschadow/Java-Web-Security</url>\n    <description>Chapter 5 HTTP Strict Transport Security (HSTS sample project. Requires a server like Apache Tomcat or the Maven Tomcat plugin. After starting, open the web application in your browser at http://localhost:8080/Ch05_HSTS</description>\n\n    <dependencies>\n        <dependency>\n            <groupId>javax.servlet</groupId>\n            <artifactId>javax.servlet-api</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>ch.qos.logback</groupId>\n            <artifactId>logback-classic</artifactId>\n        </dependency>\n    </dependencies>\n\n    <build>\n        <finalName>Ch05_HSTS</finalName>\n        <defaultGoal>tomcat7:run-war</defaultGoal>\n        <plugins>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-compiler-plugin</artifactId>\n            </plugin>\n            <plugin>\n                <groupId>org.apache.tomcat.maven</groupId>\n                <artifactId>tomcat7-maven-plugin</artifactId>\n            </plugin>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-war-plugin</artifactId>\n                <configuration>\n                    <failOnMissingWebXml>false</failOnMissingWebXml>\n                </configuration>\n            </plugin>\n        </plugins>\n    </build>\n\n\n</project>"
  },
  {
    "path": "Ch05_HSTS/src/main/java/de/dominikschadow/webappsecurity/filter/HSTSFilter.java",
    "content": "/*\n * Copyright (C) 2015 Dominik Schadow, info@dominikschadow.de\n *\n * This file is part of the Java-Web-Security project.\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * \n *  http://www.apache.org/licenses/LICENSE-2.0\n * \n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage de.dominikschadow.webappsecurity.filter;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport javax.servlet.*;\nimport javax.servlet.http.HttpServletResponse;\nimport java.io.IOException;\n\n/**\n * Filter to add the <code>Strict-Transport-Security</code> header to every response.\n *\n * @author Dominik Schadow\n */\npublic class HSTSFilter implements Filter {\n    private static final Logger LOGGER = LoggerFactory.getLogger(HSTSFilter.class);\n\n    @Override\n    public void init(FilterConfig filterConfig) {\n        LOGGER.info(\"HSTSFilter init\");\n    }\n\n    @Override\n    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {\n        ((HttpServletResponse) res).setHeader(\"Strict-Transport-Security\", \"max-age=12960000; includeSubdomains\");\n        LOGGER.info(\"Added Strict-Transport-Security header to response\");\n\n        chain.doFilter(req, res);\n    }\n\n    @Override\n    public void destroy() {\n    }\n}\n"
  },
  {
    "path": "Ch05_HSTS/src/main/java/de/dominikschadow/webappsecurity/servlets/LoginServlet.java",
    "content": "/*\n * Copyright (C) 2015 Dominik Schadow, info@dominikschadow.de\n *\n * This file is part of the Java-Web-Security project.\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * \n *  http://www.apache.org/licenses/LICENSE-2.0\n * \n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage de.dominikschadow.webappsecurity.servlets;\n\nimport java.io.IOException;\nimport java.io.PrintWriter;\nimport java.io.Serial;\n\nimport javax.servlet.annotation.WebServlet;\nimport javax.servlet.http.HttpServlet;\nimport javax.servlet.http.HttpServletRequest;\nimport javax.servlet.http.HttpServletResponse;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\n/**\n * Servlet faking a user login. Invalidates the current session (and its session id) and creates a new one afterwards.\n *\n * @author Dominik Schadow\n */\n@WebServlet(name = \"LoginServlet\", urlPatterns = {\"/LoginServlet\"})\npublic class LoginServlet extends HttpServlet {\n    private static final Logger LOGGER = LoggerFactory.getLogger(LoginServlet.class);\n    @Serial\n    private static final long serialVersionUID = 1L;\n\n    @Override\n    protected void doPost(HttpServletRequest request, HttpServletResponse response) {\n        String name = request.getParameter(\"name\");\n        LOGGER.info(\"Received {} as POST parameter\", name);\n\n        // invalidate the current session\n        request.getSession().invalidate();\n\n        // create a new one and continue in the \"login\" process\n        request.getSession(true);\n\n        response.setContentType(\"text/html\");\n\n        try (PrintWriter out = response.getWriter()) {\n            out.println(\"<html>\");\n            out.println(\"<head><link rel=\\\"stylesheet\\\" type=\\\"text/css\\\" href=\\\"styles.css\\\" /></head>\");\n            out.println(\"<body>\");\n            out.println(\"<h1>Ch05_HSTS</h1>\");\n            out.println(\"<script type=\\\"text/javascript\\\">document.write(\\\"<p><strong>Session ID</strong> [\\\" + \" +\n                    \"document.cookie + \\\"]</p>\\\")</script>\");\n            out.println(\"</body>\");\n            out.println(\"</html>\");\n        } catch (IOException ex) {\n            LOGGER.error(ex.getMessage(), ex);\n        }\n    }\n}\n"
  },
  {
    "path": "Ch05_HSTS/src/main/resources/logback.xml",
    "content": "<configuration>\n    <appender name=\"STDOUT\" class=\"ch.qos.logback.core.ConsoleAppender\">\n        <encoder>\n            <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>\n        </encoder>\n    </appender>\n\n    <root level=\"INFO\">\n        <appender-ref ref=\"STDOUT\" />\n    </root>\n</configuration>"
  },
  {
    "path": "Ch05_HSTS/src/main/webapp/WEB-INF/web.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<web-app xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns=\"http://java.sun.com/xml/ns/javaee\"\n         xsi:schemaLocation=\"http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd\"\n         id=\"HSTS\" version=\"3.0\">\n    <display-name>HSTS</display-name>\n    <filter>\n        <filter-name>HSTSFilter</filter-name>\n        <filter-class>de.dominikschadow.webappsecurity.filter.HSTSFilter</filter-class>\n    </filter>\n    <filter-mapping>\n        <filter-name>HSTSFilter</filter-name>\n        <url-pattern>/*</url-pattern>\n    </filter-mapping>\n    <welcome-file-list>\n        <welcome-file>index.jsp</welcome-file>\n    </welcome-file-list>\n</web-app>"
  },
  {
    "path": "Ch05_HSTS/src/main/webapp/index.jsp",
    "content": "<%@ page language=\"java\" contentType=\"text/html; charset=UTF-8\" pageEncoding=\"UTF-8\"%>\n<!DOCTYPE html>\n<html>\n<head>\n\t<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"styles.css\" />\n\t<title>Chapter 05 - HTTP Strict Transport Security (HSTS)</title>\n</head>\n<body>\n\t<h1>Chapter 05 - HTTP Strict Transport Security (HSTS)</h1>\n\n    <form name=\"login\" method=\"post\" action=\"LoginServlet\">\n        <table>\n            <tr>\n                <td><label for=\"stmt\" title=\"Name\">Name</label></td>\n                <td><input type=\"text\" id=\"stmt\" name=\"name\" class=\"text-input\" /></td>\n                <td><input type=\"submit\" value=\"Submit\" /></td>\n            </tr>\n        </table>\n    </form>\n</body>\n</html>\n"
  },
  {
    "path": "Ch05_HSTS/src/main/webapp/styles.css",
    "content": ".text-input {\n    width: 250px;\n}\n\nh1 {\n    font-size: 150%;\n}\n\nh2 {\n    font-size: 125%;\n}\n\ntd {\n    font-size: 115%;\n}\n\nth {\n    background-color: darkgrey;\n    padding: 2pt;\n    font-weight: bold;\n    font-size: 125%;\n}\n"
  },
  {
    "path": "Ch05_SessionFixation/pom.xml",
    "content": "<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n\t<modelVersion>4.0.0</modelVersion>\n\t<parent>\n\t\t<groupId>de.dominikschadow.javawebsecurity</groupId>\n\t\t<artifactId>javawebsecurity</artifactId>\n\t\t<version>1.0.0</version>\n\t</parent>\n\t<artifactId>Ch05_SessionFixation</artifactId>\n\t<packaging>war</packaging>\n\t<name>Chapter 05 - Session Fixation</name>\n\t<url>https://github.com/dschadow/Java-Web-Security</url>\n    <description>Chapter 5 Session Fixation sample project. Requires a server like Apache Tomcat or the Maven Tomcat plugin. After starting, open the web application in your browser at http://localhost:8080/Ch05_SessionFixation</description>\n\n    <dependencies>\n        <dependency>\n            <groupId>javax.servlet</groupId>\n            <artifactId>javax.servlet-api</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>ch.qos.logback</groupId>\n            <artifactId>logback-classic</artifactId>\n        </dependency>\n\t</dependencies>\n\n    <build>\n        <finalName>Ch05_SessionFixation</finalName>\n        <defaultGoal>tomcat7:run-war</defaultGoal>\n        <plugins>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-compiler-plugin</artifactId>\n            </plugin>\n            <plugin>\n                <groupId>org.apache.tomcat.maven</groupId>\n                <artifactId>tomcat7-maven-plugin</artifactId>\n                <configuration>\n                    <contextFile>${project.basedir}/src/main/resources/context.xml</contextFile>\n                </configuration>\n            </plugin>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-war-plugin</artifactId>\n                <configuration>\n                    <failOnMissingWebXml>false</failOnMissingWebXml>\n                </configuration>\n            </plugin>\n        </plugins>\n    </build>\n</project>"
  },
  {
    "path": "Ch05_SessionFixation/src/main/java/de/dominikschadow/webappsecurity/servlets/LoginServlet.java",
    "content": "/*\n * Copyright (C) 2015 Dominik Schadow, info@dominikschadow.de\n *\n * This file is part of the Java-Web-Security project.\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * \n *  http://www.apache.org/licenses/LICENSE-2.0\n * \n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage de.dominikschadow.webappsecurity.servlets;\n\nimport java.io.IOException;\nimport java.io.PrintWriter;\nimport java.io.Serial;\n\nimport javax.servlet.annotation.WebServlet;\nimport javax.servlet.http.HttpServlet;\nimport javax.servlet.http.HttpServletRequest;\nimport javax.servlet.http.HttpServletResponse;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\n/**\n * Servlet faking a user login. Invalidates the current session (and its session id) and creates a new one afterwards.\n *\n * @author Dominik Schadow\n */\n@WebServlet(name = \"LoginServlet\", urlPatterns = {\"/LoginServlet\"})\npublic class LoginServlet extends HttpServlet {\n    private static final Logger LOGGER = LoggerFactory.getLogger(LoginServlet.class);\n    @Serial\n    private static final long serialVersionUID = 1L;\n\n    @Override\n    protected void doPost(HttpServletRequest request, HttpServletResponse response) {\n        String name = request.getParameter(\"name\");\n        LOGGER.info(\"Received {} as POST parameter\", name);\n\n        // invalidate the current session\n        request.getSession().invalidate();\n\n        // create a new one and continue in the \"login\" process\n        request.getSession(true);\n\n        response.setContentType(\"text/html\");\n\n        try (PrintWriter out = response.getWriter()) {\n            out.println(\"<html>\");\n            out.println(\"<head><link rel=\\\"stylesheet\\\" type=\\\"text/css\\\" href=\\\"styles.css\\\" /></head>\");\n            out.println(\"<body>\");\n            out.println(\"<h1>Ch05_SessionFixation</h1>\");\n            out.println(\"<script type=\\\"text/javascript\\\">document.write(\\\"<p><strong>Session ID</strong> [\\\" + \" +\n                    \"document.cookie + \\\"]</p>\\\")</script>\");\n            out.println(\"</body>\");\n            out.println(\"</html>\");\n        } catch (IOException ex) {\n            LOGGER.error(ex.getMessage(), ex);\n        }\n    }\n}\n"
  },
  {
    "path": "Ch05_SessionFixation/src/main/resources/context.xml",
    "content": "<?xml version='1.0' encoding='utf-8'?>\n<Context useHttpOnly=\"false\">\n\n</Context>"
  },
  {
    "path": "Ch05_SessionFixation/src/main/resources/logback.xml",
    "content": "<configuration>\n    <appender name=\"STDOUT\" class=\"ch.qos.logback.core.ConsoleAppender\">\n        <encoder>\n            <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>\n        </encoder>\n    </appender>\n\n    <root level=\"INFO\">\n        <appender-ref ref=\"STDOUT\" />\n    </root>\n</configuration>"
  },
  {
    "path": "Ch05_SessionFixation/src/main/webapp/index.jsp",
    "content": "<%@ page language=\"java\" contentType=\"text/html; charset=UTF-8\" pageEncoding=\"UTF-8\"%>\n<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n<html>\n<head>\n\t<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"styles.css\" />\n\t<title>Chapter 05 - Session Fixation</title>\n</head>\n<body>\n\t<h1>Chapter 05 - Session Fixation</h1>\n\n    <script type=\"text/javascript\">document.write(\"<p><strong>Session ID</strong> [\" + document.cookie + \"]</p>\")</script>\n\n\t<form name=\"login\" method=\"post\" action=\"LoginServlet\">\n\t\t<table>\n\t\t\t<tr>\n\t\t\t\t<td><label for=\"stmt\" title=\"Name\">Name</label></td>\n\t\t\t\t<td><input type=\"text\" id=\"stmt\" name=\"name\" class=\"text-input\" /></td>\n\t\t\t\t<td><input type=\"submit\" value=\"Submit\" /></td>\n\t\t\t</tr>\n\t\t</table>\n\t</form>\n</body>\n</html>\n"
  },
  {
    "path": "Ch05_SessionFixation/src/main/webapp/styles.css",
    "content": ".text-input {\n    width: 250px;\n}\n\nh1 {\n    font-size: 150%;\n}\n\nh2 {\n    font-size: 125%;\n}\n\ntd {\n    font-size: 115%;\n}\n\nth {\n    background-color: darkgrey;\n    padding: 2pt;\n    font-weight: bold;\n    font-size: 125%;\n}\n"
  },
  {
    "path": "Ch05_SessionHandling/pom.xml",
    "content": "<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n\t<modelVersion>4.0.0</modelVersion>\n\t<parent>\n\t\t<groupId>de.dominikschadow.javawebsecurity</groupId>\n\t\t<artifactId>javawebsecurity</artifactId>\n\t\t<version>1.0.0</version>\n\t</parent>\n\t<artifactId>Ch05_SessionHandling</artifactId>\n\t<packaging>war</packaging>\n\t<name>Chapter 05 - Session Handling</name>\n\t<url>https://github.com/dschadow/Java-Web-Security</url>\n    <description>Chapter 5 Session Handling sample project. Requires a server like Apache Tomcat or the Maven Tomcat plugin. After starting, open the web application in your browser at http://localhost:8080/Ch05_SessionHandling</description>\n\n    <dependencies>\n        <dependency>\n            <groupId>com.sun.faces</groupId>\n            <artifactId>jsf-api</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>com.sun.faces</groupId>\n            <artifactId>jsf-impl</artifactId>\n        </dependency>\n\t</dependencies>\n\n    <build>\n        <finalName>Ch05_SessionHandling</finalName>\n        <defaultGoal>tomcat7:run-war</defaultGoal>\n        <plugins>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-compiler-plugin</artifactId>\n            </plugin>\n            <plugin>\n                <groupId>org.apache.tomcat.maven</groupId>\n                <artifactId>tomcat7-maven-plugin</artifactId>\n            </plugin>\n        </plugins>\n    </build>\n</project>"
  },
  {
    "path": "Ch05_SessionHandling/src/main/webapp/WEB-INF/faces-config.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<faces-config version=\"2.2\"\n              xmlns=\"http://xmlns.jcp.org/xml/ns/javaee\"\n              xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n              xsi:schemaLocation=\"http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-facesconfig_2_2.xsd\">\n</faces-config>"
  },
  {
    "path": "Ch05_SessionHandling/src/main/webapp/WEB-INF/web.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<web-app xmlns=\"http://xmlns.jcp.org/xml/ns/javaee\"\n         xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n         xsi:schemaLocation=\"http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd\"\n         version=\"3.1\">\n    <display-name>Ch05_SessionHandling</display-name>\n\n    <context-param>\n        <param-name>javax.faces.PROJECT_STAGE</param-name>\n        <param-value>Development</param-value>\n    </context-param>\n\n    <welcome-file-list>\n        <welcome-file>index.xhtml</welcome-file>\n    </welcome-file-list>\n\n    <servlet>\n        <servlet-name>Faces Servlet</servlet-name>\n        <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>\n        <load-on-startup>1</load-on-startup>\n    </servlet>\n    <servlet-mapping>\n        <servlet-name>Faces Servlet</servlet-name>\n        <url-pattern>*.xhtml</url-pattern>\n    </servlet-mapping>\n\n    <session-config>\n        <session-timeout>30</session-timeout>\n        <cookie-config>\n            <http-only>true</http-only>\n            <!-- secure is not working without a certificate and a properly configured webserver -->\n            <!--<secure>true</secure>-->\n        </cookie-config>\n        <tracking-mode>COOKIE</tracking-mode>\n    </session-config>\n</web-app>"
  },
  {
    "path": "Ch05_SessionHandling/src/main/webapp/index.xhtml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"\n        \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n<html xmlns=\"http://www.w3.org/1999/xhtml\" xmlns:h=\"http://xmlns.jcp.org/jsf/html\">\n<h:head>\n    <h:outputStylesheet library=\"css\" value=\"styles.css\" name=\"styles.css\" />\n    <title>Chapter 05 - Session Handling</title>\n</h:head>\n<h:body>\n\t<h1>Chapter 05 - Session Handling</h1>\n\n    <p>Cookie information in popup is empty because of web.xml protection.</p>\n\n    <script type=\"text/javascript\">alert(\"Cookie Session ID [\" + document.cookie + \"]\")</script>\n</h:body>\n</html>"
  },
  {
    "path": "Ch05_SessionHandling/src/main/webapp/resources/css/styles.css",
    "content": "h1 {\n    font-size: 125%;\n}\n"
  },
  {
    "path": "Ch06_SQLInjection/pom.xml",
    "content": "<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n         xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n    <modelVersion>4.0.0</modelVersion>\n    <parent>\n        <groupId>de.dominikschadow.javawebsecurity</groupId>\n        <artifactId>javawebsecurity</artifactId>\n        <version>1.0.0</version>\n    </parent>\n    <artifactId>Ch06_SQLInjection</artifactId>\n    <packaging>war</packaging>\n    <name>Chapter 06 - SQL Injection</name>\n    <url>https://github.com/dschadow/Java-Web-Security</url>\n    <description>Chapter 6 SQL Injection sample project. Requires a server like Apache Tomcat or the Maven Tomcat plugin. After starting, open the web application in your browser at http://localhost:8080/Ch06_SQLInjection</description>\n\n    <dependencies>\n        <dependency>\n            <groupId>javax.servlet</groupId>\n            <artifactId>javax.servlet-api</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>com.h2database</groupId>\n            <artifactId>h2</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>org.owasp.esapi</groupId>\n            <artifactId>esapi</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>org.hibernate</groupId>\n            <artifactId>hibernate-core</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>ch.qos.logback</groupId>\n            <artifactId>logback-classic</artifactId>\n        </dependency>\n    </dependencies>\n\n    <build>\n        <finalName>Ch06_SQLInjection</finalName>\n        <defaultGoal>tomcat7:run-war</defaultGoal>\n        <plugins>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-compiler-plugin</artifactId>\n            </plugin>\n            <plugin>\n                <groupId>org.apache.tomcat.maven</groupId>\n                <artifactId>tomcat7-maven-plugin</artifactId>\n                <configuration>\n                    <contextFile>${project.basedir}/src/main/resources/context.xml</contextFile>\n                </configuration>\n            </plugin>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-war-plugin</artifactId>\n                <configuration>\n                    <failOnMissingWebXml>false</failOnMissingWebXml>\n                </configuration>\n            </plugin>\n        </plugins>\n    </build>\n</project>"
  },
  {
    "path": "Ch06_SQLInjection/src/main/java/de/dominikschadow/webappsecurity/domain/Customer.java",
    "content": "/*\n * Copyright (C) 2015 Dominik Schadow, info@dominikschadow.de\n *\n * This file is part of the Java-Web-Security project.\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * \n *  http://www.apache.org/licenses/LICENSE-2.0\n * \n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage de.dominikschadow.webappsecurity.domain;\n\nimport javax.persistence.*;\n\n/**\n * @author Dominik Schadow\n */\n@Entity\npublic class Customer {\n    @Id\n    @GeneratedValue(strategy = GenerationType.AUTO)\n    @Column(name = \"cust_id\")\n    private int custId;\n    private String name;\n    private String status;\n    @Column(name = \"order_limit\")\n    private int orderLimit;\n    private String hint;\n\n    public int getCustId() {\n        return custId;\n    }\n\n    public void setCustId(int custId) {\n        this.custId = custId;\n    }\n\n    public String getName() {\n        return name;\n    }\n\n    public void setName(String name) {\n        this.name = name;\n    }\n\n    public String getStatus() {\n        return status;\n    }\n\n    public void setStatus(String status) {\n        this.status = status;\n    }\n\n    public int getOrderLimit() {\n        return orderLimit;\n    }\n\n    public void setOrderLimit(int orderLimit) {\n        this.orderLimit = orderLimit;\n    }\n\n    public String getHint() {\n        return hint;\n    }\n\n    public void setHint(String hint) {\n        this.hint = hint;\n    }\n\n    @Override\n    public String toString() {\n        return \"ID \" + custId +\n                \", Name \" + name +\n                \", Status \" + status +\n                \", Order Limit \" + orderLimit +\n                \", Hint \" + hint;\n    }\n}\n"
  },
  {
    "path": "Ch06_SQLInjection/src/main/java/de/dominikschadow/webappsecurity/servlets/CustomerTable.java",
    "content": "package de.dominikschadow.webappsecurity.servlets;\n\nimport de.dominikschadow.webappsecurity.domain.Customer;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport javax.servlet.http.HttpServletResponse;\nimport java.io.IOException;\nimport java.io.PrintWriter;\nimport java.sql.ResultSet;\nimport java.sql.SQLException;\nimport java.util.ArrayList;\nimport java.util.List;\n\n/**\n * Util class to create the customers list and to create the HTML table with all queried customers.\n *\n * @author Dominik Schadow\n */\npublic class CustomerTable {\n    private static final Logger LOGGER = LoggerFactory.getLogger(CustomerTable.class);\n\n    public static List<Customer> extractCustomers(ResultSet rs) throws SQLException {\n        List<Customer> customers = new ArrayList<>();\n\n        while (rs.next()) {\n            Customer customer = new Customer();\n            customer.setCustId(rs.getInt(1));\n            customer.setName(rs.getString(2));\n            customer.setStatus(rs.getString(3));\n            customer.setOrderLimit(rs.getInt(4));\n\n            customers.add(customer);\n        }\n\n        return customers;\n    }\n\n    public static void writeCustomers(HttpServletResponse response, String name, List<Customer> customers) {\n        response.setContentType(\"text/html\");\n\n        try (PrintWriter out = response.getWriter()) {\n            out.println(\"<html>\");\n            out.println(\"<head><link rel=\\\"stylesheet\\\" type=\\\"text/css\\\" href=\\\"styles.css\\\" /></head>\");\n            out.println(\"<body>\");\n            out.println(\"<h1>Chapter 06 - SQL Injection</h1>\");\n            out.println(\"<p><strong>Input</strong> \" + name + \"</p>\");\n            out.println(\"<h2>Customer Data</h2>\");\n            out.println(\"<table>\");\n            out.println(\"<tr>\");\n            out.println(\"<th>ID</th>\");\n            out.println(\"<th>Name</th>\");\n            out.println(\"<th>Status</th>\");\n            out.println(\"<th>Order Limit</th>\");\n            out.println(\"</tr>\");\n\n            for (Customer customer : customers) {\n                out.println(\"<tr>\");\n                out.println(\"<td>\" + customer.getCustId() + \"</td>\");\n                out.println(\"<td>\" + customer.getName() + \"</td>\");\n                out.println(\"<td>\" + customer.getStatus() + \"</td>\");\n                out.println(\"<td>\" + customer.getOrderLimit() + \"</td>\");\n                out.println(\"</tr>\");\n            }\n\n            out.println(\"<table>\");\n            out.println(\"</body>\");\n            out.println(\"</html>\");\n        } catch (IOException ex) {\n            LOGGER.error(ex.getMessage(), ex);\n        }\n    }\n}\n"
  },
  {
    "path": "Ch06_SQLInjection/src/main/java/de/dominikschadow/webappsecurity/servlets/HQLServlet.java",
    "content": "/*\n * Copyright (C) 2015 Dominik Schadow, info@dominikschadow.de\n *\n * This file is part of the Java-Web-Security project.\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * \n *  http://www.apache.org/licenses/LICENSE-2.0\n * \n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage de.dominikschadow.webappsecurity.servlets;\n\nimport org.hibernate.HibernateException;\nimport org.hibernate.Session;\nimport org.hibernate.query.Query;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport javax.servlet.annotation.WebServlet;\nimport javax.servlet.http.HttpServlet;\nimport javax.servlet.http.HttpServletRequest;\nimport javax.servlet.http.HttpServletResponse;\n\nimport static de.dominikschadow.webappsecurity.servlets.CustomerTable.writeCustomers;\nimport static de.dominikschadow.webappsecurity.servlets.HibernateUtil.getSessionFactory;\n\n/**\n * Servlet using Hibernate Query Language (HQL) to query the in-memory-database.\n * User input is not modified and used directly in the HQL query.\n *\n * @author Dominik Schadow\n */\n@WebServlet(name = \"HQLServlet\", urlPatterns = {\"/HQLServlet\"})\npublic class HQLServlet extends HttpServlet {\n    private static final Logger LOGGER = LoggerFactory.getLogger(HQLServlet.class);\n\n    @Override\n    protected void doPost(HttpServletRequest request, HttpServletResponse response) {\n        String name = request.getParameter(\"name\");\n        LOGGER.info(\"Received {} as POST parameter\", name);\n\n        try (Session session = getSessionFactory().openSession()) {\n            Query query = session.createQuery(\"FROM Customer WHERE name = :name ORDER BY custId\");\n            query.setParameter(\"name\", name);\n\n            writeCustomers(response, name, query.list());\n        } catch (HibernateException ex) {\n            LOGGER.error(ex.getMessage(), ex);\n        }\n    }\n}\n"
  },
  {
    "path": "Ch06_SQLInjection/src/main/java/de/dominikschadow/webappsecurity/servlets/HibernateUtil.java",
    "content": "/*\n * Copyright (C) 2015 Dominik Schadow, info@dominikschadow.de\n *\n * This file is part of the Java-Web-Security project.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *  http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage de.dominikschadow.webappsecurity.servlets;\n\nimport org.hibernate.SessionFactory;\nimport org.hibernate.cfg.Configuration;\n\n/**\n * @author Dominik Schadow\n */\npublic class HibernateUtil {\n    static SessionFactory sessionFactory;\n\n    /**\n     * Util class, no constructor required.\n     */\n    private HibernateUtil() {\n    }\n\n    public static SessionFactory getSessionFactory() {\n        if (sessionFactory == null) {\n            sessionFactory = new Configuration().configure().buildSessionFactory();\n        }\n\n        return sessionFactory;\n    }\n}\n"
  },
  {
    "path": "Ch06_SQLInjection/src/main/java/de/dominikschadow/webappsecurity/servlets/InitDbServlet.java",
    "content": "package de.dominikschadow.webappsecurity.servlets;\n\nimport org.hibernate.Session;\n\nimport javax.servlet.annotation.WebServlet;\nimport javax.servlet.http.HttpServlet;\n\nimport static de.dominikschadow.webappsecurity.servlets.HibernateUtil.getSessionFactory;\n\n/**\n * Servlet to initialize the database with some sample data.\n *\n * @author Dominik Schadow\n */\n@WebServlet(name = \"InitDbServlet\", urlPatterns = {\"/\"})\npublic class InitDbServlet extends HttpServlet {\n    @Override\n    public void init() {\n        Session session = getSessionFactory().openSession();\n        session.close();\n    }\n}\n"
  },
  {
    "path": "Ch06_SQLInjection/src/main/java/de/dominikschadow/webappsecurity/servlets/PreparedStatementServlet.java",
    "content": "/*\n * Copyright (C) 2015 Dominik Schadow, info@dominikschadow.de\n *\n * This file is part of the Java-Web-Security project.\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * \n *  http://www.apache.org/licenses/LICENSE-2.0\n * \n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage de.dominikschadow.webappsecurity.servlets;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport javax.servlet.annotation.WebServlet;\nimport javax.servlet.http.HttpServlet;\nimport javax.servlet.http.HttpServletRequest;\nimport javax.servlet.http.HttpServletResponse;\nimport java.sql.*;\n\nimport static de.dominikschadow.webappsecurity.servlets.CustomerTable.extractCustomers;\nimport static de.dominikschadow.webappsecurity.servlets.CustomerTable.writeCustomers;\n\n/**\n * Servlet using a Prepared Statement to query the in-memory-database.\n * User input is not modified and used directly in the SQL query.\n *\n * @author Dominik Schadow\n */\n@WebServlet(name = \"PreparedStatementServlet\", urlPatterns = {\"/PreparedStatementServlet\"})\npublic class PreparedStatementServlet extends HttpServlet {\n    private static final Logger LOGGER = LoggerFactory.getLogger(PreparedStatementServlet.class);\n\n    @Override\n    protected void doPost(HttpServletRequest request, HttpServletResponse response) {\n        String name = request.getParameter(\"name\");\n        LOGGER.info(\"Received {} as POST parameter\", name);\n\n        String query = \"SELECT * FROM customer WHERE name = ? ORDER BY CUST_ID\";\n        ResultSet rs = null;\n\n        try (Connection con = DriverManager.getConnection(\"jdbc:h2:mem:sqli\", \"sa\", \"sa\"); PreparedStatement stmt = con.prepareStatement(query)) {\n            stmt.setString(1, name);\n            rs = stmt.executeQuery();\n\n            writeCustomers(response, name, extractCustomers(rs));\n        } catch (SQLException ex) {\n            LOGGER.error(ex.getMessage(), ex);\n        } finally {\n            try {\n                if (rs != null) {\n                    rs.close();\n                }\n            } catch (SQLException ex) {\n                LOGGER.error(ex.getMessage(), ex);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Ch06_SQLInjection/src/main/java/de/dominikschadow/webappsecurity/servlets/StatementEscapingServlet.java",
    "content": "/*\n * Copyright (C) 2015 Dominik Schadow, info@dominikschadow.de\n *\n * This file is part of the Java-Web-Security project.\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * \n *  http://www.apache.org/licenses/LICENSE-2.0\n * \n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage de.dominikschadow.webappsecurity.servlets;\n\nimport org.owasp.esapi.ESAPI;\nimport org.owasp.esapi.codecs.OracleCodec;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport javax.servlet.annotation.WebServlet;\nimport javax.servlet.http.HttpServlet;\nimport javax.servlet.http.HttpServletRequest;\nimport javax.servlet.http.HttpServletResponse;\nimport java.sql.*;\n\nimport static de.dominikschadow.webappsecurity.servlets.CustomerTable.extractCustomers;\nimport static de.dominikschadow.webappsecurity.servlets.CustomerTable.writeCustomers;\n\n/**\n * Servlet using a normal Statement to query the in-memory-database.\n * User input is escaped with ESAPI and used in the SQL query afterwards.\n *\n * @author Dominik Schadow\n */\n@WebServlet(name = \"StatementEscapingServlet\", urlPatterns = {\"/StatementEscapingServlet\"})\npublic class StatementEscapingServlet extends HttpServlet {\n    private static final Logger LOGGER = LoggerFactory.getLogger(StatementEscapingServlet.class);\n\n    @Override\n    protected void doPost(HttpServletRequest request, HttpServletResponse response) {\n        String name = request.getParameter(\"name\");\n        LOGGER.info(\"Received {} as POST parameter\", name);\n\n        String safeName = ESAPI.encoder().encodeForSQL(new OracleCodec(), name);\n        LOGGER.info(\"Escaped name is {}\", safeName);\n\n        String query = \"SELECT * FROM customer WHERE name = '\" + safeName + \"' ORDER BY CUST_ID\";\n\n        LOGGER.info(\"Final SQL query {}\", query);\n\n        ResultSet rs = null;\n\n        try (Connection con = DriverManager.getConnection(\"jdbc:h2:mem:sqli\", \"sa\", \"sa\"); Statement stmt = con.createStatement()) {\n            rs = stmt.executeQuery(query);\n\n            writeCustomers(response, name, extractCustomers(rs));\n        } catch (SQLException ex) {\n            LOGGER.error(ex.getMessage(), ex);\n        } finally {\n            try {\n                if (rs != null) {\n                    rs.close();\n                }\n            } catch (SQLException ex) {\n                LOGGER.error(ex.getMessage(), ex);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Ch06_SQLInjection/src/main/java/de/dominikschadow/webappsecurity/servlets/StatementServlet.java",
    "content": "/*\n * Copyright (C) 2015 Dominik Schadow, info@dominikschadow.de\n *\n * This file is part of the Java-Web-Security project.\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * \n *  http://www.apache.org/licenses/LICENSE-2.0\n * \n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage de.dominikschadow.webappsecurity.servlets;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport javax.servlet.annotation.WebServlet;\nimport javax.servlet.http.HttpServlet;\nimport javax.servlet.http.HttpServletRequest;\nimport javax.servlet.http.HttpServletResponse;\nimport java.sql.*;\n\nimport static de.dominikschadow.webappsecurity.servlets.CustomerTable.extractCustomers;\nimport static de.dominikschadow.webappsecurity.servlets.CustomerTable.writeCustomers;\n\n/**\n * Servlet using a normal Statement to query the in-memory-database.\n * User input is not modified and used directly in the SQL query.\n *\n * @author Dominik Schadow\n */\n@WebServlet(name = \"StatementServlet\", urlPatterns = {\"/StatementServlet\"})\npublic class StatementServlet extends HttpServlet {\n    private static final Logger LOGGER = LoggerFactory.getLogger(StatementServlet.class);\n\n    @Override\n    protected void doPost(HttpServletRequest request, HttpServletResponse response) {\n        String name = request.getParameter(\"name\");\n        LOGGER.info(\"Received {} as POST parameter\", name);\n\n        String query = \"SELECT * FROM customer WHERE name = '\" + name + \"' ORDER BY CUST_ID\";\n\n        LOGGER.info(\"Final SQL query {}\", query);\n\n        ResultSet rs = null;\n\n        try (Connection con = DriverManager.getConnection(\"jdbc:h2:mem:sqli\", \"sa\", \"sa\"); Statement stmt = con.createStatement()) {\n            rs = stmt.executeQuery(query);\n\n            writeCustomers(response, name, extractCustomers(rs));\n        } catch (SQLException ex) {\n            LOGGER.error(ex.getMessage(), ex);\n        } finally {\n            try {\n                if (rs != null) {\n                    rs.close();\n                }\n            } catch (SQLException ex) {\n                LOGGER.error(ex.getMessage(), ex);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Ch06_SQLInjection/src/main/resources/ESAPI.properties",
    "content": "# Logging\nLogger.ApplicationName=Ch06_SQLInjection"
  },
  {
    "path": "Ch06_SQLInjection/src/main/resources/context.xml",
    "content": "<?xml version='1.0' encoding='utf-8'?>\n<Context useHttpOnly=\"false\">\n    <Resource name=\"sqliDS\" auth=\"Container\" type=\"javax.sql.DataSource\"\n              maxActive=\"100\" maxIdle=\"30\" maxWait=\"10000\"\n              username=\"sa\" password=\"sa\" driverClassName=\"org.h2.Driver\"\n              url=\"jdbc:h2:mem:sqli\"/>\n</Context>"
  },
  {
    "path": "Ch06_SQLInjection/src/main/resources/hibernate.cfg.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!DOCTYPE hibernate-configuration PUBLIC\n        \"-//Hibernate/Hibernate Configuration DTD//EN\"\n        \"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd\">\n<hibernate-configuration>\n    <session-factory>\n        <property name=\"hibernate.dialect\">org.hibernate.dialect.H2Dialect</property>\n        <property name=\"hibernate.connection.datasource\">java:comp/env/sqliDS</property>\n        <property name=\"hibernate.hbm2ddl.auto\">create-drop</property>\n        <property name=\"show_sql\">false</property>\n        <mapping package=\"de.dominikschadow.webappsecurity.domain\"/>\n        <mapping class=\"de.dominikschadow.webappsecurity.domain.Customer\"/>\n    </session-factory>\n</hibernate-configuration>"
  },
  {
    "path": "Ch06_SQLInjection/src/main/resources/import.sql",
    "content": "INSERT INTO CUSTOMER (CUST_ID, NAME, STATUS, ORDER_LIMIT, HINT) VALUES (1001, 'Arthur Dent', 'A', 10000, '');\nINSERT INTO CUSTOMER (CUST_ID, NAME, STATUS, ORDER_LIMIT, HINT) VALUES (1002, 'Ford Prefect', 'B', 5000, '');\nINSERT INTO CUSTOMER (CUST_ID, NAME, STATUS, ORDER_LIMIT, HINT) VALUES (1003, 'Tricia Trillian McMillan', 'C', 1000, '');\nINSERT INTO CUSTOMER (CUST_ID, NAME, STATUS, ORDER_LIMIT, HINT) VALUES (1004, 'Zaphod Beeblebrox', 'D', 500, 'President of the Galaxy');\nINSERT INTO CUSTOMER (CUST_ID, NAME, STATUS, ORDER_LIMIT, HINT) VALUES (1005, 'Marvin', 'A', 100000, 'Depressive');\nINSERT INTO CUSTOMER (CUST_ID, NAME, STATUS, ORDER_LIMIT, HINT) VALUES (1006, 'Slartibartfast', 'D', 100, '42');\n"
  },
  {
    "path": "Ch06_SQLInjection/src/main/resources/logback.xml",
    "content": "<configuration>\n    <appender name=\"STDOUT\" class=\"ch.qos.logback.core.ConsoleAppender\">\n        <encoder>\n            <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>\n        </encoder>\n    </appender>\n\n    <root level=\"INFO\">\n        <appender-ref ref=\"STDOUT\" />\n    </root>\n</configuration>"
  },
  {
    "path": "Ch06_SQLInjection/src/main/webapp/index.jsp",
    "content": "<%@ page language=\"java\" contentType=\"text/html; charset=UTF-8\" pageEncoding=\"UTF-8\"%>\n<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n<html>\n<head>\n\t<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"styles.css\" />\n\t<title>Chapter 06 - SQL Injection</title>\n</head>\n<body>\n\t<h1>Chapter 06 - SQL Injection</h1>\n\n    <p>You can use different options to access the database. Not every field is attackable by SQL Injection.\n\t\t<strong>Valid customers are:</strong> Arthur Dent, Ford Prefect, Tricia Trillian McMillan, Zaphod Beeblebrox, Marvin, Slartibartfast</p>\n\n\t<h2>Using Statement</h2>\n\t\n\t<form name=\"stmt\" method=\"post\" action=\"StatementServlet\">\n\t\t<table>\n\t\t\t<tr>\n\t\t\t\t<td><label for=\"stmt\" title=\"Name\">Name</label></td>\n\t\t\t\t<td><input type=\"text\" id=\"stmt\" name=\"name\" class=\"text-input\" /></td>\n\t\t\t\t<td><input type=\"submit\" value=\"Submit\" /></td>\n\t\t\t</tr>\n\t\t</table>\n\t</form>\n\n    <h2>Using Statement with Escaping</h2>\n\n    <form name=\"stmtEsc\" method=\"post\" action=\"StatementEscapingServlet\">\n        <table>\n            <tr>\n                <td><label for=\"stmtEsc\" title=\"Name\">Name</label></td>\n                <td><input type=\"text\" id=\"stmtEsc\" name=\"name\" class=\"text-input\" /></td>\n                <td><input type=\"submit\" value=\"Submit\" /></td>\n            </tr>\n        </table>\n    </form>\n\n\t<h2>Using Prepared Statement</h2>\n\t\n\t<form name=\"pstmt\" method=\"post\" action=\"PreparedStatementServlet\">\n\t\t<table>\n\t\t\t<tr>\n\t\t\t\t<td><label for=\"pstmt\" title=\"Name\">Name</label></td>\n\t\t\t\t<td><input type=\"text\" id=\"pstmt\" name=\"name\" class=\"text-input\" /></td>\n\t\t\t\t<td><input type=\"submit\" name=\"submit\" value=\"Submit\" /></td>\n\t\t\t</tr>\n\t\t</table>\n\t</form>\n\n    <h2>Using Hibernate Query Language (HQL)</h2>\n\n    <form name=\"hql\" method=\"post\" action=\"HQLServlet\">\n        <table>\n            <tr>\n                <td><label for=\"hql\" title=\"Name\">Name</label></td>\n                <td><input type=\"text\" id=\"hql\" name=\"name\" class=\"text-input\" /></td>\n                <td><input type=\"submit\" name=\"submit\" value=\"Submit\" /></td>\n            </tr>\n        </table>\n    </form>\n</body>\n</html>\n"
  },
  {
    "path": "Ch06_SQLInjection/src/main/webapp/styles.css",
    "content": ".text-input {\n    width: 250px;\n}\n\nh1 {\n    font-size: 1.5em;\n}\n\nh2 {\n    font-size: 1.2em;\n}\n\nth {\n    background-color: darkgrey;\n    padding: 2pt;\n    font-weight: bold;\n    font-size: 1.1em;\n}\n"
  },
  {
    "path": "Ch06_XPathInjection/pom.xml",
    "content": "<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n         xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n    <modelVersion>4.0.0</modelVersion>\n    <parent>\n        <groupId>de.dominikschadow.javawebsecurity</groupId>\n        <artifactId>javawebsecurity</artifactId>\n        <version>1.0.0</version>\n    </parent>\n    <artifactId>Ch06_XPathInjection</artifactId>\n    <packaging>war</packaging>\n    <name>Chapter 06 - XPath Injection</name>\n    <url>https://github.com/dschadow/Java-Web-Security</url>\n    <description>Chapter 6 XPath Injection sample project. Requires a server like Apache Tomcat or the Maven Tomcat plugin. After starting, open the web application in your browser at http://localhost:8080/Ch06_XPathInjection</description>\n\n    <dependencies>\n        <dependency>\n            <groupId>javax.servlet</groupId>\n            <artifactId>javax.servlet-api</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>org.owasp.esapi</groupId>\n            <artifactId>esapi</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>ch.qos.logback</groupId>\n            <artifactId>logback-classic</artifactId>\n        </dependency>\n    </dependencies>\n\n    <build>\n        <finalName>Ch06_XPathInjection</finalName>\n        <defaultGoal>tomcat7:run-war</defaultGoal>\n        <plugins>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-compiler-plugin</artifactId>\n            </plugin>\n            <plugin>\n                <groupId>org.apache.tomcat.maven</groupId>\n                <artifactId>tomcat7-maven-plugin</artifactId>\n            </plugin>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-war-plugin</artifactId>\n                <configuration>\n                    <failOnMissingWebXml>false</failOnMissingWebXml>\n                </configuration>\n            </plugin>\n        </plugins>\n    </build>\n</project>"
  },
  {
    "path": "Ch06_XPathInjection/src/main/java/de/dominikschadow/webappsecurity/servlets/XPathEscapingServlet.java",
    "content": "/*\n * Copyright (C) 2015 Dominik Schadow, info@dominikschadow.de\n *\n * This file is part of the Java-Web-Security project.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *  http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage de.dominikschadow.webappsecurity.servlets;\n\nimport org.owasp.esapi.ESAPI;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.w3c.dom.Document;\nimport org.w3c.dom.NodeList;\nimport org.xml.sax.SAXException;\n\nimport javax.servlet.annotation.WebServlet;\nimport javax.servlet.http.HttpServlet;\nimport javax.servlet.http.HttpServletRequest;\nimport javax.servlet.http.HttpServletResponse;\nimport javax.xml.parsers.DocumentBuilder;\nimport javax.xml.parsers.DocumentBuilderFactory;\nimport javax.xml.parsers.ParserConfigurationException;\nimport javax.xml.xpath.XPathConstants;\nimport javax.xml.xpath.XPathExpression;\nimport javax.xml.xpath.XPathExpressionException;\nimport javax.xml.xpath.XPathFactory;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.io.PrintWriter;\n\n/**\n * Servlet using an XPath expression to query the customer XML document.\n * User input is escaped before being used in the XPath expression.\n * <p>\n * Use <code>' or '1' = '1</code> or <code>'] | /* | /foo[bar='</code> as password.\n *\n * @author Dominik Schadow\n */\n@WebServlet(name = \"XPathEscapingServlet\", urlPatterns = {\"/XPathEscapingServlet\"})\npublic class XPathEscapingServlet extends HttpServlet {\n    private static final Logger LOGGER = LoggerFactory.getLogger(XPathEscapingServlet.class);\n    private static Document doc;\n\n    @Override\n    public void init() {\n        try (InputStream inputStream = getClass().getClassLoader().getResourceAsStream(\"/customer.xml\")) {\n            DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();\n            DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();\n            doc = dBuilder.parse(inputStream);\n        } catch (SAXException | IOException | ParserConfigurationException ex) {\n            LOGGER.error(ex.getMessage(), ex);\n        }\n    }\n\n    @Override\n    protected void doPost(HttpServletRequest request, HttpServletResponse response) {\n        String name = request.getParameter(\"name\");\n        String password = request.getParameter(\"password\");\n        LOGGER.info(\"Received {} and {} as parameter\", name, password);\n\n        String safeName = ESAPI.encoder().encodeForXPath(name);\n        String safePassword = ESAPI.encoder().encodeForXPath(password);\n        LOGGER.info(\"Using safe name {} and {}\", safeName, safePassword);\n\n        String xpathExpression = \"/customers/customer[name='\" +\n                safeName +\n                \"' and @password='\" +\n                safePassword +\n                \"']/orderLimit\";\n\n        printOrderLimit(xpathExpression, name, response);\n    }\n\n    private void printOrderLimit(String xpath, String name, HttpServletResponse response) {\n        LOGGER.info(\"XPath expression is {}\", xpath);\n\n        try (PrintWriter out = response.getWriter()) {\n            XPathExpression expression = XPathFactory.newInstance().newXPath().compile(xpath);\n            Object result = expression.evaluate(doc, XPathConstants.NODESET);\n\n            response.setContentType(\"text/html\");\n\n            out.println(\"<html>\");\n            out.println(\"<head><link rel=\\\"stylesheet\\\" type=\\\"text/css\\\" href=\\\"styles.css\\\" /></head>\");\n            out.println(\"<body>\");\n            out.println(\"<h1>Ch06_XPathInjection</h1>\");\n            out.println(\"<h2>Order limit for \" + name + \"</h2>\");\n\n            NodeList nodes = (NodeList) result;\n            for (int i = 0; i < nodes.getLength(); i++) {\n                out.println(\"<p>\" + nodes.item(i).getTextContent() + \"</p>\");\n            }\n\n            out.println(\"</body>\");\n            out.println(\"</html>\");\n        } catch (XPathExpressionException | IOException ex) {\n            LOGGER.error(ex.getMessage(), ex);\n        }\n    }\n}\n"
  },
  {
    "path": "Ch06_XPathInjection/src/main/java/de/dominikschadow/webappsecurity/servlets/XPathServlet.java",
    "content": "/*\n * Copyright (C) 2015 Dominik Schadow, info@dominikschadow.de\n *\n * This file is part of the Java-Web-Security project.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *  http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage de.dominikschadow.webappsecurity.servlets;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.w3c.dom.Document;\nimport org.w3c.dom.NodeList;\nimport org.xml.sax.SAXException;\n\nimport javax.servlet.annotation.WebServlet;\nimport javax.servlet.http.HttpServlet;\nimport javax.servlet.http.HttpServletRequest;\nimport javax.servlet.http.HttpServletResponse;\nimport javax.xml.parsers.DocumentBuilder;\nimport javax.xml.parsers.DocumentBuilderFactory;\nimport javax.xml.parsers.ParserConfigurationException;\nimport javax.xml.xpath.XPathConstants;\nimport javax.xml.xpath.XPathExpression;\nimport javax.xml.xpath.XPathExpressionException;\nimport javax.xml.xpath.XPathFactory;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.io.PrintWriter;\n\n/**\n * Servlet using an XPath expression to query the customer XML document.\n * User input is not modified and used directly in the XPath expression.\n * <p>\n * Use <code>' or '1' = '1</code> or <code>'] | /* | /foo[bar='</code> as password.\n *\n * @author Dominik Schadow\n */\n@WebServlet(name = \"XPathServlet\", urlPatterns = {\"/XPathServlet\"})\npublic class XPathServlet extends HttpServlet {\n    private static final Logger LOGGER = LoggerFactory.getLogger(XPathServlet.class);\n    private static Document doc;\n\n    @Override\n    public void init() {\n        try (InputStream inputStream = getClass().getClassLoader().getResourceAsStream(\"/customer.xml\")) {\n            DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();\n            DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();\n            doc = dBuilder.parse(inputStream);\n        } catch (SAXException | IOException | ParserConfigurationException ex) {\n            LOGGER.error(ex.getMessage(), ex);\n        }\n    }\n\n    @Override\n    protected void doPost(HttpServletRequest request, HttpServletResponse response) {\n        String name = request.getParameter(\"name\");\n        String password = request.getParameter(\"password\");\n        LOGGER.info(\"Received {} and {} as parameter\", name, password);\n\n        String xpathExpression = \"/customers/customer[name='\" +\n                name +\n                \"' and @password='\" +\n                password +\n                \"']/orderLimit\";\n\n        printOrderLimit(xpathExpression, name, response);\n    }\n\n    private void printOrderLimit(String xpath, String name, HttpServletResponse response) {\n        LOGGER.info(\"XPath expression is {}\", xpath);\n\n        try (PrintWriter out = response.getWriter()) {\n            XPathExpression expression = XPathFactory.newInstance().newXPath().compile(xpath);\n            Object result = expression.evaluate(doc, XPathConstants.NODESET);\n\n            response.setContentType(\"text/html\");\n\n            out.println(\"<html>\");\n            out.println(\"<head><link rel=\\\"stylesheet\\\" type=\\\"text/css\\\" href=\\\"styles.css\\\" /></head>\");\n            out.println(\"<body>\");\n            out.println(\"<h1>Ch06_XPathInjection</h1>\");\n            out.println(\"<h2>Order limit for \" + name + \"</h2>\");\n\n            NodeList nodes = (NodeList) result;\n            for (int i = 0; i < nodes.getLength(); i++) {\n                out.println(\"<p>\" + nodes.item(i).getTextContent() + \"</p>\");\n            }\n\n            out.println(\"</body>\");\n            out.println(\"</html>\");\n        } catch (XPathExpressionException | IOException ex) {\n            LOGGER.error(ex.getMessage(), ex);\n        }\n    }\n}\n"
  },
  {
    "path": "Ch06_XPathInjection/src/main/resources/ESAPI.properties",
    "content": "# Logging\nLogger.ApplicationName=Ch06_XPathInjection"
  },
  {
    "path": "Ch06_XPathInjection/src/main/resources/customer.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<customers>\n\t<customer id=\"1\" password=\"Arthur\">\n        <name>Arthur Dent</name>\n\t\t<status>A</status>\n\t\t<orderLimit>10000</orderLimit>\n\t</customer>\t\n\t<customer id=\"2\" password=\"Ford\">\n        <name>Ford Prefect</name>\n\t\t<status>B</status>\n\t\t<orderLimit>5000</orderLimit>\n\t</customer>\t\n\t<customer id=\"3\" password=\"Tricia\">\n        <name>Tricia Trillian McMillan</name>\n\t\t<status>C</status>\n\t\t<orderLimit>1000</orderLimit>\n\t</customer>\t\n\t<customer id=\"4\" password=\"Zaphod\">\n        <name>Zaphod Beeblebrox</name>\n\t\t<status>D</status>\n\t\t<orderLimit>500</orderLimit>\n\t</customer>\t\n\t<customer id=\"5\" password=\"Marvin\">\n        <name>Marvin</name>\n\t\t<status>A</status>\n\t\t<orderLimit>100000</orderLimit>\n\t</customer>\n    <customer id=\"5\" password=\"Slartibartfast\">\n        <name>Slartibartfast</name>\n        <status>D</status>\n        <orderLimit>100</orderLimit>\n    </customer>\n</customers>"
  },
  {
    "path": "Ch06_XPathInjection/src/main/resources/logback.xml",
    "content": "<configuration>\n    <appender name=\"STDOUT\" class=\"ch.qos.logback.core.ConsoleAppender\">\n        <encoder>\n            <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>\n        </encoder>\n    </appender>\n\n    <root level=\"INFO\">\n        <appender-ref ref=\"STDOUT\" />\n    </root>\n</configuration>"
  },
  {
    "path": "Ch06_XPathInjection/src/main/webapp/index.jsp",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"styles.css\" />\n\t<title>Chapter 06 - XPath Injection</title>\n</head>\n<body>\n\t<h1>Chapter 06 - XPath Injection</h1>\n\n    <p><strong>Valid customers are:</strong> Arthur Dent, Ford Prefect, Tricia Trillian McMillan, Zaphod Beeblebrox, Marvin, Slartibartfast<br/>\n    Password is always their first name.</p>\n\n\t<h2>Without Escaping</h2>\n\t\n\t<form name=\"stmt\" method=\"post\" action=\"XPathServlet\">\n\t\t<table>\n\t\t\t<tr>\n\t\t\t\t<td><label for=\"name\" title=\"Name\">Name</label></td>\n\t\t\t\t<td><input type=\"text\" id=\"name\" name=\"name\" class=\"text-input\" /></td>\n                <td>&nbsp;</td>\n            </tr>\n            <tr>\n                <td><label for=\"password\" title=\"Password\">Password</label></td>\n                <td><input type=\"password\" id=\"password\" name=\"password\" class=\"text-input\" /></td>\n\t\t\t\t<td><input type=\"submit\" value=\"Submit\" /></td>\n\t\t\t</tr>\n\t\t</table>\n\t</form>\n\n    <h2>With Escaping</h2>\n\n    <form name=\"stmtEsc\" method=\"post\" action=\"XPathEscapingServlet\">\n        <table>\n            <tr>\n                <td><label for=\"name\" title=\"Name\">Name</label></td>\n                <td><input type=\"text\" id=\"name\" name=\"name\" class=\"text-input\" /></td>\n                <td>&nbsp;</td>\n            </tr>\n            <tr>\n                <td><label for=\"password\" title=\"Password\">Password</label></td>\n                <td><input type=\"password\" id=\"password\" name=\"password\" class=\"text-input\" /></td>\n                <td><input type=\"submit\" value=\"Submit\" /></td>\n            </tr>\n        </table>\n    </form>\n</body>\n</html>\n"
  },
  {
    "path": "Ch06_XPathInjection/src/main/webapp/styles.css",
    "content": ".text-input {\n    width: 250px;\n}\n\nh1 {\n    font-size: 150%;\n}\n\nh2 {\n    font-size: 125%;\n}\n\ntd {\n    font-size: 115%;\n}\n\nth {\n    background-color: darkgrey;\n    padding: 2pt;\n    font-weight: bold;\n    font-size: 125%;\n}\n"
  },
  {
    "path": "Ch07_CSP/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n         xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n         xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n    <modelVersion>4.0.0</modelVersion>\n    <parent>\n        <groupId>de.dominikschadow.javawebsecurity</groupId>\n        <artifactId>javawebsecurity</artifactId>\n        <version>1.0.0</version>\n    </parent>\n    <artifactId>Ch07_CSP</artifactId>\n    <packaging>war</packaging>\n    <name>Chapter 07 - CSP</name>\n    <url>https://github.com/dschadow/Java-Web-Security</url>\n    <description>Chapter 7 Content Security Policy (CSP) sample project. Requires a server like Apache Tomcat or the Maven Tomcat7 plugin. After starting, open the web application in your browser at http://localhost:8080/Ch07_CSP</description>\n\n    <dependencies>\n        <dependency>\n            <groupId>javax.servlet</groupId>\n            <artifactId>javax.servlet-api</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>ch.qos.logback</groupId>\n            <artifactId>logback-classic</artifactId>\n        </dependency>\n    </dependencies>\n\n    <build>\n        <finalName>Ch07_CSP</finalName>\n        <defaultGoal>tomcat7:run-war</defaultGoal>\n        <plugins>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-compiler-plugin</artifactId>\n            </plugin>\n            <plugin>\n                <groupId>org.apache.tomcat.maven</groupId>\n                <artifactId>tomcat7-maven-plugin</artifactId>\n            </plugin>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-war-plugin</artifactId>\n                <configuration>\n                    <failOnMissingWebXml>false</failOnMissingWebXml>\n                </configuration>\n            </plugin>\n        </plugins>\n    </build>\n</project>"
  },
  {
    "path": "Ch07_CSP/src/main/java/de/dominikschadow/webappsecurity/CSPReporting.java",
    "content": "/*\n * Copyright (C) 2015 Dominik Schadow, info@dominikschadow.de\n *\n * This file is part of the Java-Web-Security project.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *  http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage de.dominikschadow.webappsecurity;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport javax.servlet.annotation.WebServlet;\nimport javax.servlet.http.HttpServlet;\nimport javax.servlet.http.HttpServletRequest;\nimport javax.servlet.http.HttpServletResponse;\nimport java.io.BufferedReader;\nimport java.io.IOException;\nimport java.io.InputStreamReader;\nimport java.io.Serial;\nimport java.nio.charset.Charset;\n\n/**\n * Simple CSP-Reporting servlet to receive and print out any JSON style CSP report with violations.\n *\n * @author Dominik Schadow\n */\n@WebServlet(name = \"CSPReporting\", urlPatterns = {\"/CSPReporting\"})\npublic class CSPReporting extends HttpServlet {\n    @Serial\n    private static final long serialVersionUID = 1L;\n    private static final Logger LOGGER = LoggerFactory.getLogger(CSPReporting.class);\n\n    @Override\n    protected void doPost(HttpServletRequest request, HttpServletResponse response) {\n        try (BufferedReader reader = new BufferedReader(new InputStreamReader(request.getInputStream(), Charset.defaultCharset()))) {\n            StringBuilder responseBuilder = new StringBuilder();\n\n            String inputStr;\n            while ((inputStr = reader.readLine()) != null) {\n                responseBuilder.append(inputStr);\n            }\n\n            LOGGER.info(\"\\n{}\", responseBuilder.toString());\n        } catch (IOException ex) {\n            LOGGER.error(ex.getMessage(), ex);\n        }\n    }\n}\n"
  },
  {
    "path": "Ch07_CSP/src/main/java/de/dominikschadow/webappsecurity/WithCSPReportingServlet.java",
    "content": "/*\n * Copyright (C) 2015 Dominik Schadow, info@dominikschadow.de\n *\n * This file is part of the Java-Web-Security project.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *  http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage de.dominikschadow.webappsecurity;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport javax.servlet.annotation.WebServlet;\nimport javax.servlet.http.HttpServlet;\nimport javax.servlet.http.HttpServletRequest;\nimport javax.servlet.http.HttpServletResponse;\nimport java.io.IOException;\nimport java.io.PrintWriter;\nimport java.io.Serial;\n\n/**\n * Servlet which sets the <code>Content-Security-Policy-Report-Only</code> response header and reports\n * any JavaScript code that would have been stopped by the policy.\n *\n * @author Dominik Schadow\n */\n@WebServlet(name = \"WithCSPReportingServlet\", urlPatterns = {\"/WithCSPReportingServlet\"})\npublic class WithCSPReportingServlet extends HttpServlet {\n    @Serial\n    private static final long serialVersionUID = 1L;\n    private static final Logger LOGGER = LoggerFactory.getLogger(WithCSPReportingServlet.class);\n\n    @Override\n    protected void doPost(HttpServletRequest request, HttpServletResponse response) {\n        LOGGER.info(\"Processing POST request with Content Security Policy Reporting\");\n\n        String name = request.getParameter(\"reporting\");\n        LOGGER.info(\"Received {} as POST parameter\", name);\n\n        response.setContentType(\"text/html\");\n        // the following line only reports violations and does not block anything\n        response.setHeader(\"Content-Security-Policy-Report-Only\", \"default-src 'self'; report-uri CSPReporting\");\n\n        // use the following line to activate the policy and still report all violations\n        //response.setHeader(\"Content-Security-Policy\", \"default-src 'self'; report-uri CSPReporting\");\n\n        try (PrintWriter out = response.getWriter()) {\n            out.println(\"<html>\");\n            out.println(\"<head><link rel=\\\"stylesheet\\\" type=\\\"text/css\\\" href=\\\"styles.css\\\" /></head>\");\n            out.println(\"<body>\");\n            out.println(\"<h1>Ch07_CSP</h1>\");\n            out.println(\"<h2>With Content Security Policy Reporting</h2>\");\n            out.println(\"<p><strong>Hello</strong> \" + name + \"</p>\");\n            out.println(\"</body>\");\n            out.println(\"</html>\");\n        } catch (IOException ex) {\n            LOGGER.error(ex.getMessage(), ex);\n        }\n    }\n}\n"
  },
  {
    "path": "Ch07_CSP/src/main/java/de/dominikschadow/webappsecurity/WithCSPServlet.java",
    "content": "/*\n * Copyright (C) 2015 Dominik Schadow, info@dominikschadow.de\n *\n * This file is part of the Java-Web-Security project.\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * \n *  http://www.apache.org/licenses/LICENSE-2.0\n * \n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage de.dominikschadow.webappsecurity;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport javax.servlet.annotation.WebServlet;\nimport javax.servlet.http.HttpServlet;\nimport javax.servlet.http.HttpServletRequest;\nimport javax.servlet.http.HttpServletResponse;\nimport java.io.IOException;\nimport java.io.PrintWriter;\nimport java.io.Serial;\n\n/**\n * Servlet which sets the <code>Content-Security-Policy</code> response header and stops any JavaScript code entered\n * in the textfield.\n * Any entered script-tag will not be rendered any more in the result page.\n *\n * @author Dominik Schadow\n */\n@WebServlet(name = \"WithCSPServlet\", urlPatterns = {\"/WithCSPServlet\"})\npublic class WithCSPServlet extends HttpServlet {\n    @Serial\n    private static final long serialVersionUID = 1L;\n    private static final Logger LOGGER = LoggerFactory.getLogger(WithCSPServlet.class);\n\n    @Override\n    protected void doPost(HttpServletRequest request, HttpServletResponse response) {\n        LOGGER.info(\"Processing POST request with Content Security Policy\");\n\n        String name = request.getParameter(\"protected\");\n        LOGGER.info(\"Received {} as POST parameter\", name);\n\n        response.setContentType(\"text/html\");\n        response.setHeader(\"Content-Security-Policy\", \"default-src 'self'\");\n        // following line enables unsafe inline JavaScript\n//        response.setHeader(\"Content-Security-Policy\", \"default-src 'self' 'unsafe-inline'\");\n\n        try (PrintWriter out = response.getWriter()) {\n            out.println(\"<html>\");\n            out.println(\"<head><link rel=\\\"stylesheet\\\" type=\\\"text/css\\\" href=\\\"styles.css\\\" /></head>\");\n            out.println(\"<body>\");\n            out.println(\"<h1>Ch07_CSP</h1>\");\n            out.println(\"<h2>With Content Security Policy</h2>\");\n            out.println(\"<p><strong>Hello</strong> \" + name + \"</p>\");\n            out.println(\"</body>\");\n            out.println(\"</html>\");\n        } catch (IOException ex) {\n            LOGGER.error(ex.getMessage(), ex);\n        }\n    }\n}\n"
  },
  {
    "path": "Ch07_CSP/src/main/java/de/dominikschadow/webappsecurity/WithoutCSPServlet.java",
    "content": "/*\n * Copyright (C) 2015 Dominik Schadow, info@dominikschadow.de\n *\n * This file is part of the Java-Web-Security project.\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * \n *  http://www.apache.org/licenses/LICENSE-2.0\n * \n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage de.dominikschadow.webappsecurity;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport javax.servlet.annotation.WebServlet;\nimport javax.servlet.http.HttpServlet;\nimport javax.servlet.http.HttpServletRequest;\nimport javax.servlet.http.HttpServletResponse;\nimport java.io.IOException;\nimport java.io.PrintWriter;\nimport java.io.Serial;\n\n/**\n * Default servlet without any additional protection. Any entered script-tag will be executed on the result page.\n *\n * @author Dominik Schadow\n */\n@WebServlet(name = \"WithoutCSPServlet\", urlPatterns = {\"/WithoutCSPServlet\"})\npublic class WithoutCSPServlet extends HttpServlet {\n    @Serial\n    private static final long serialVersionUID = 1L;\n    private static final Logger LOGGER = LoggerFactory.getLogger(WithoutCSPServlet.class);\n\n    @Override\n    protected void doPost(HttpServletRequest request, HttpServletResponse response) {\n        LOGGER.info(\"Processing POST request without Content Security Policy\");\n\n        String name = request.getParameter(\"unprotected\");\n        LOGGER.info(\"Received {} as POST parameter\", name);\n\n        response.setContentType(\"text/html\");\n\n        try (PrintWriter out = response.getWriter()) {\n            out.println(\"<html>\");\n            out.println(\"<head><link rel=\\\"stylesheet\\\" type=\\\"text/css\\\" href=\\\"styles.css\\\" /></head>\");\n            out.println(\"<body>\");\n            out.println(\"<h1>Ch07_CSP</h1>\");\n            out.println(\"<h2>Without Content Security Policy</h2>\");\n            out.println(\"<p><strong>Hello</strong> \" + name + \"</p>\");\n            out.println(\"</body>\");\n            out.println(\"</html>\");\n        } catch (IOException ex) {\n            LOGGER.error(ex.getMessage(), ex);\n        }\n    }\n}\n"
  },
  {
    "path": "Ch07_CSP/src/main/resources/logback.xml",
    "content": "<configuration>\n    <appender name=\"STDOUT\" class=\"ch.qos.logback.core.ConsoleAppender\">\n        <encoder>\n            <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>\n        </encoder>\n    </appender>\n\n    <root level=\"INFO\">\n        <appender-ref ref=\"STDOUT\" />\n    </root>\n</configuration>"
  },
  {
    "path": "Ch07_CSP/src/main/webapp/index.jsp",
    "content": "<%@ page language=\"java\" contentType=\"text/html; charset=UTF-8\" pageEncoding=\"UTF-8\"%>\n<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n<html>\n<head>\n\t<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"styles.css\" />\n\t<title>Chapter 07 - Content Security Policy (CSP)</title>\n</head>\n<body>\n\t<h1>Chapter 07 - Content Security Policy (CSP)</h1>\n\n\t<h2>Without Content Security Policy</h2>\n\t\n\t<form name=\"withoutCSP\" method=\"post\" action=\"WithoutCSPServlet\">\n\t\t<table>\n\t\t\t<tr>\n\t\t\t\t<td><label for=\"unprotected\" title=\"Name\">Name</label></td>\n\t\t\t\t<td><input type=\"text\" id=\"unprotected\" name=\"unprotected\" class=\"text-input\" /></td>\n\t\t\t\t<td><input type=\"submit\" value=\"Submit\" /></td>\n\t\t\t</tr>\n\t\t</table>\n\t</form>\n\n\t<h2>With Content Security Policy</h2>\n\n\t<form name=\"withCSP\" method=\"post\" action=\"WithCSPServlet\">\n\t\t<table>\n\t\t\t<tr>\n\t\t\t\t<td><label for=\"protected\" title=\"Name\">Name</label></td>\n\t\t\t\t<td><input type=\"text\" id=\"protected\" name=\"protected\" class=\"text-input\" /></td>\n\t\t\t\t<td><input type=\"submit\" name=\"submit\" value=\"Submit\" /></td>\n\t\t\t</tr>\n\t\t</table>\n\t</form>\n\n    <h2>With Content Security Policy Reporting</h2>\n\n    <form name=\"withCSPReporting\" method=\"post\" action=\"WithCSPReportingServlet\">\n        <table>\n            <tr>\n                <td><label for=\"reporting\" title=\"Name\">Name</label></td>\n                <td><input type=\"text\" id=\"reporting\" name=\"reporting\" class=\"text-input\" /></td>\n                <td><input type=\"submit\" name=\"submit\" value=\"Submit\" /></td>\n            </tr>\n        </table>\n    </form>\n</body>\n</html>\n"
  },
  {
    "path": "Ch07_CSP/src/main/webapp/styles.css",
    "content": ".text-input {\n    width: 250px;\n}\n\nh1 {\n    font-size: 150%;\n}\n\nh2 {\n    font-size: 125%;\n}\n\ntd {\n    font-size: 115%;\n}\n"
  },
  {
    "path": "Ch07_XSS/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\r\n\txsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd\">\r\n    <modelVersion>4.0.0</modelVersion>\r\n    <parent>\r\n        <groupId>de.dominikschadow.javawebsecurity</groupId>\r\n        <artifactId>javawebsecurity</artifactId>\r\n        <version>1.0.0</version>\r\n    </parent>\r\n    <artifactId>Ch07_XSS</artifactId>\r\n    <packaging>war</packaging>\r\n    <name>Chapter 07 - XSS</name>\r\n    <url>https://github.com/dschadow/Java-Web-Security</url>\r\n    <description>Chapter 7 XSS sample project. Requires a server like Apache Tomcat or the Maven Tomcat plugin. After starting, open the web application in your browser at http://localhost:8080/Ch07_XSS</description>\r\n\r\n    <dependencies>\r\n        <dependency>\r\n            <groupId>com.sun.faces</groupId>\r\n            <artifactId>jsf-api</artifactId>\r\n        </dependency>\r\n        <dependency>\r\n            <groupId>com.sun.faces</groupId>\r\n            <artifactId>jsf-impl</artifactId>\r\n        </dependency>\r\n        <dependency>\r\n            <groupId>org.hibernate</groupId>\r\n            <artifactId>hibernate-core</artifactId>\r\n        </dependency>\r\n        <dependency>\r\n            <groupId>com.h2database</groupId>\r\n            <artifactId>h2</artifactId>\r\n        </dependency>\r\n        <dependency>\r\n            <groupId>ch.qos.logback</groupId>\r\n            <artifactId>logback-classic</artifactId>\r\n        </dependency>\r\n        <dependency>\r\n            <groupId>org.apache.commons</groupId>\r\n            <artifactId>commons-lang3</artifactId>\r\n        </dependency>\r\n    </dependencies>\r\n\r\n    <build>\r\n        <finalName>Ch07_XSS</finalName>\r\n        <defaultGoal>tomcat7:run-war</defaultGoal>\r\n        <plugins>\r\n            <plugin>\r\n                <groupId>org.apache.maven.plugins</groupId>\r\n                <artifactId>maven-compiler-plugin</artifactId>\r\n            </plugin>\r\n            <plugin>\r\n                <groupId>org.apache.tomcat.maven</groupId>\r\n                <artifactId>tomcat7-maven-plugin</artifactId>\r\n                <configuration>\r\n                    <contextFile>${project.basedir}/src/main/resources/context.xml</contextFile>\r\n                </configuration>\r\n            </plugin>\r\n        </plugins>\r\n    </build>\r\n</project>\r\n"
  },
  {
    "path": "Ch07_XSS/src/main/java/de/dominikschadow/webappsecurity/beans/CustomerController.java",
    "content": "/*\n * Copyright (C) 2015 Dominik Schadow, info@dominikschadow.de\n *\n * This file is part of the Java-Web-Security project.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *  http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage de.dominikschadow.webappsecurity.beans;\n\nimport de.dominikschadow.webappsecurity.daos.CustomerDAO;\nimport de.dominikschadow.webappsecurity.domain.Customer;\n\nimport javax.faces.bean.ManagedBean;\nimport javax.faces.bean.RequestScoped;\nimport java.util.List;\n\n/**\n *\n * @author Dominik Schadow\n */\n@ManagedBean(name = \"customer\")\n@RequestScoped\npublic class CustomerController {\n    private Customer customer;\n    private CustomerDAO customerDAO;\n\n    public CustomerController() {\n        customer = new Customer();\n        customerDAO = new CustomerDAO();\n    }\n\n    public Customer getCustomer() {\n        return customer;\n    }\n\n    public void setCustomer(Customer customer) {\n        this.customer = customer;\n    }\n\n    public List<Customer> getCustomers() {\n        return customerDAO.getAllCustomers();\n    }\n\n    public String save() {\n        customerDAO.createCustomer(customer);\n\n        return \"showCustomers\";\n    }\n}\n"
  },
  {
    "path": "Ch07_XSS/src/main/java/de/dominikschadow/webappsecurity/beans/SearchController.java",
    "content": "/*\n * Copyright (C) 2015 Dominik Schadow, info@dominikschadow.de\n *\n * This file is part of the Java-Web-Security project.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *  http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage de.dominikschadow.webappsecurity.beans;\n\nimport de.dominikschadow.webappsecurity.daos.CustomerDAO;\nimport de.dominikschadow.webappsecurity.domain.Customer;\nimport org.apache.commons.lang3.StringUtils;\n\nimport javax.faces.bean.ManagedBean;\nimport javax.faces.bean.RequestScoped;\nimport javax.faces.context.FacesContext;\nimport java.util.List;\nimport java.util.Map;\n\n/**\n * Searches customers by the given customer name. The search string can be passed via\n * <code>customerName</code> setter method or as a <code>customerName</code> parameter.\n *\n * @author Dominik Schadow\n */\n@ManagedBean(name = \"search\")\n@RequestScoped\npublic class SearchController {\n    private String customerName;\n    private CustomerDAO customerDAO;\n    private List<Customer> customers;\n\n    public SearchController() {\n        customerDAO = new CustomerDAO();\n    }\n\n    public String getCustomerName() {\n        return customerName;\n    }\n\n    public void setCustomerName(String customerName) {\n        this.customerName = customerName;\n    }\n\n    public List<Customer> getCustomers() {\n        return customers;\n    }\n\n    public String search() {\n        if (StringUtils.isEmpty(customerName)) {\n            Map<String, String> requestMap = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap();\n            customerName = requestMap.get(\"customerName\");\n        }\n\n        Customer search = new Customer();\n        search.setName(customerName);\n\n        customers = customerDAO.findCustomers(search);\n\n        return \"searchCustomer\";\n    }\n}\n"
  },
  {
    "path": "Ch07_XSS/src/main/java/de/dominikschadow/webappsecurity/daos/CustomerDAO.java",
    "content": "/*\n * Copyright (C) 2015 Dominik Schadow, info@dominikschadow.de\n *\n * This file is part of the Java-Web-Security project.\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * \n *  http://www.apache.org/licenses/LICENSE-2.0\n * \n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage de.dominikschadow.webappsecurity.daos;\n\nimport de.dominikschadow.webappsecurity.domain.Customer;\nimport org.hibernate.Criteria;\nimport org.hibernate.HibernateException;\nimport org.hibernate.Session;\nimport org.hibernate.Transaction;\nimport org.hibernate.criterion.Restrictions;\nimport org.hibernate.query.Query;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\nimport static de.dominikschadow.webappsecurity.daos.HibernateUtil.getSessionFactory;\n\n/**\n * Loads customers from the in-memory-database for the managed beans.\n *\n * @author Dominik Schadow\n * @see de.dominikschadow.webappsecurity.beans.CustomerController\n */\npublic class CustomerDAO {\n    private static final Logger LOGGER = LoggerFactory.getLogger(CustomerDAO.class);\n\n    public List<Customer> getAllCustomers() {\n        List<Customer> customers = new ArrayList<>();\n\n        try (Session session = getSessionFactory().openSession()) {\n            Query query = session.createQuery(\"FROM Customer\");\n            customers = query.list();\n\n            LOGGER.info(\"Found {} customers\", customers.size());\n        } catch (HibernateException ex) {\n            LOGGER.error(ex.getMessage(), ex);\n        }\n\n        return customers;\n    }\n\n    public void createCustomer(Customer customer) {\n        try (Session session = getSessionFactory().openSession()) {\n            Transaction tx = session.beginTransaction();\n            session.persist(customer);\n            tx.commit();\n        } catch (HibernateException ex) {\n            LOGGER.error(ex.getMessage(), ex);\n        }\n    }\n\n    public List<Customer> findCustomers(Customer customer) {\n        List<Customer> customers = new ArrayList<>();\n\n        try (Session session = getSessionFactory().openSession()) {\n            Criteria criteria = session.createCriteria(Customer.class);\n            criteria.add(Restrictions.like(\"name\", \"%\" + customer.getName() + \"%\"));\n\n            customers = criteria.list();\n\n            LOGGER.info(\"Found {} customers\", customers.size());\n        } catch (HibernateException ex) {\n            LOGGER.error(ex.getMessage(), ex);\n        }\n\n        return customers;\n    }\n}\n"
  },
  {
    "path": "Ch07_XSS/src/main/java/de/dominikschadow/webappsecurity/daos/HibernateUtil.java",
    "content": "/*\n * Copyright (C) 2015 Dominik Schadow, info@dominikschadow.de\n *\n * This file is part of the Java-Web-Security project.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *  http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage de.dominikschadow.webappsecurity.daos;\n\nimport org.hibernate.SessionFactory;\nimport org.hibernate.cfg.Configuration;\n\n/**\n * @author Dominik Schadow\n */\npublic class HibernateUtil {\n    private static SessionFactory sessionFactory;\n\n    /**\n     * Util class, no constructor required.\n     */\n    private HibernateUtil() {\n    }\n\n    public static SessionFactory getSessionFactory() {\n        if (sessionFactory == null) {\n            sessionFactory = new Configuration().configure().buildSessionFactory();\n        }\n\n        return sessionFactory;\n    }\n}\n"
  },
  {
    "path": "Ch07_XSS/src/main/java/de/dominikschadow/webappsecurity/domain/Customer.java",
    "content": "/*\n * Copyright (C) 2015 Dominik Schadow, info@dominikschadow.de\n *\n * This file is part of the Java-Web-Security project.\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * \n *  http://www.apache.org/licenses/LICENSE-2.0\n * \n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage de.dominikschadow.webappsecurity.domain;\n\nimport javax.persistence.*;\n\n/**\n * @author Dominik Schadow\n */\n@Entity\npublic class Customer {\n    @Id\n    @GeneratedValue(strategy = GenerationType.AUTO)\n    @Column(name = \"cust_id\")\n    private int custId;\n    private String name;\n    private String status;\n    @Column(name = \"order_limit\")\n    private int orderLimit;\n    private String hint;\n\n    public int getCustId() {\n        return custId;\n    }\n\n    public void setCustId(int custId) {\n        this.custId = custId;\n    }\n\n    public String getName() {\n        return name;\n    }\n\n    public void setName(String name) {\n        this.name = name;\n    }\n\n    public String getStatus() {\n        return status;\n    }\n\n    public void setStatus(String status) {\n        this.status = status;\n    }\n\n    public int getOrderLimit() {\n        return orderLimit;\n    }\n\n    public void setOrderLimit(int orderLimit) {\n        this.orderLimit = orderLimit;\n    }\n\n    public String getHint() {\n        return hint;\n    }\n\n    public void setHint(String hint) {\n        this.hint = hint;\n    }\n\n    @Override\n    public String toString() {\n        return \"ID \" + custId +\n                \", Name \" + name +\n                \", Status \" + status +\n                \", Order Limit \" + orderLimit +\n                \", Hint \" + hint;\n    }\n}\n"
  },
  {
    "path": "Ch07_XSS/src/main/resources/context.xml",
    "content": "<?xml version='1.0' encoding='utf-8'?>\n<Context useHttpOnly=\"false\">\n    <Resource name=\"xssDS\" auth=\"Container\" type=\"javax.sql.DataSource\"\n              maxActive=\"100\" maxIdle=\"30\" maxWait=\"10000\"\n              username=\"sa\" password=\"sa\" driverClassName=\"org.h2.Driver\"\n              url=\"jdbc:h2:mem:xss\"/>\n</Context>"
  },
  {
    "path": "Ch07_XSS/src/main/resources/hibernate.cfg.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!DOCTYPE hibernate-configuration PUBLIC\n        \"-//Hibernate/Hibernate Configuration DTD//EN\"\n        \"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd\">\n<hibernate-configuration>\n    <session-factory>\n        <property name=\"hibernate.dialect\">org.hibernate.dialect.H2Dialect</property>\n        <property name=\"hibernate.connection.datasource\">java:comp/env/xssDS</property>\n        <property name=\"hibernate.hbm2ddl.auto\">create-drop</property>\n        <property name=\"show_sql\">false</property>\n        <mapping package=\"de.dominikschadow.webappsecurity.domain\"/>\n        <mapping class=\"de.dominikschadow.webappsecurity.domain.Customer\"/>\n    </session-factory>\n</hibernate-configuration>"
  },
  {
    "path": "Ch07_XSS/src/main/resources/import.sql",
    "content": "INSERT INTO CUSTOMER (CUST_ID, NAME, STATUS, ORDER_LIMIT, HINT) VALUES (1001, 'Arthur Dent', 'A', 10000, '');\nINSERT INTO CUSTOMER (CUST_ID, NAME, STATUS, ORDER_LIMIT, HINT) VALUES (1002, 'Ford Prefect', 'B', 5000, '');\nINSERT INTO CUSTOMER (CUST_ID, NAME, STATUS, ORDER_LIMIT, HINT) VALUES (1003, 'Tricia Trillian McMillan', 'C', 1000, '');\nINSERT INTO CUSTOMER (CUST_ID, NAME, STATUS, ORDER_LIMIT, HINT) VALUES (1004, 'Zaphod Beeblebrox', 'D', 500, 'President of the Galaxy');\nINSERT INTO CUSTOMER (CUST_ID, NAME, STATUS, ORDER_LIMIT, HINT) VALUES (1005, 'Marvin', 'A', 100000, 'Depressive');\nINSERT INTO CUSTOMER (CUST_ID, NAME, STATUS, ORDER_LIMIT, HINT) VALUES (1006, 'Slartibartfast', 'D', 100, '42');\nINSERT INTO CUSTOMER (CUST_ID, NAME, STATUS, ORDER_LIMIT, HINT) VALUES (1007, 'Stored XSS', 'X', 9999, '<script>alert(\"Stored XSS - Session ID: \" + document.cookie)</script>');\n"
  },
  {
    "path": "Ch07_XSS/src/main/resources/logback.xml",
    "content": "<configuration>\n    <appender name=\"STDOUT\" class=\"ch.qos.logback.core.ConsoleAppender\">\n        <encoder>\n            <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>\n        </encoder>\n    </appender>\n\n    <root level=\"INFO\">\n        <appender-ref ref=\"STDOUT\" />\n    </root>\n</configuration>"
  },
  {
    "path": "Ch07_XSS/src/main/webapp/WEB-INF/faces-config.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n<faces-config version=\"2.2\"\r\n              xmlns=\"http://xmlns.jcp.org/xml/ns/javaee\"\r\n              xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\r\n              xsi:schemaLocation=\"http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-facesconfig_2_2.xsd\">\r\n</faces-config>"
  },
  {
    "path": "Ch07_XSS/src/main/webapp/WEB-INF/web.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<web-app xmlns=\"http://xmlns.jcp.org/xml/ns/javaee\"\n         xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n         xsi:schemaLocation=\"http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd\"\n         version=\"3.1\">\n    <display-name>Ch07_XSS</display-name>\n\n    <context-param>\n        <param-name>javax.faces.PROJECT_STAGE</param-name>\n        <param-value>Development</param-value>\n    </context-param>\n\n    <welcome-file-list>\n        <welcome-file>index.xhtml</welcome-file>\n    </welcome-file-list>\n\n    <servlet>\n        <servlet-name>Faces Servlet</servlet-name>\n        <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>\n        <load-on-startup>1</load-on-startup>\n    </servlet>\n\n    <servlet-mapping>\n        <servlet-name>Faces Servlet</servlet-name>\n        <url-pattern>*.xhtml</url-pattern>\n    </servlet-mapping>\n\t\n\t<session-config>\n\t    <!-- http-only must be on false in order for a working XSS sample attack -->\n\t\t<cookie-config>\n\t\t\t<http-only>false</http-only>\n\t\t</cookie-config>\n\t\t<tracking-mode>COOKIE</tracking-mode>\n\t</session-config>\n</web-app>"
  },
  {
    "path": "Ch07_XSS/src/main/webapp/createCustomer.xhtml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"\n        \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n<html xmlns=\"http://www.w3.org/1999/xhtml\" xmlns:h=\"http://xmlns.jcp.org/jsf/html\"\n      xmlns:f=\"http://xmlns.jcp.org/jsf/core\">\n<h:head>\n    <h:outputStylesheet library=\"css\" value=\"styles.css\" name=\"styles.css\" />\n    <title>Chapter 07 - XSS</title>\n</h:head>\n<h:body>\n    <h1>Chapter 07 - XSS</h1>\n\n    <h:form>\n        <h:link outcome=\"index\" value=\"Home\"/> | <h:link outcome=\"showCustomers\" value=\"Show Customers\"><f:param\n            name=\"currency\" value=\"EUR\"/></h:link> | <h:link outcome=\"search\" value=\"Search Customer\"/>\n    </h:form>\n\n    <p>Enter all information to create a new customer:</p>\n\n    <h:form id=\"createCustomer\">\n        <h:panelGrid columns=\"2\">\n            <h:outputLabel value=\"Name\" for=\"name\"/>\n            <h:inputText value=\"#{customer.customer.name}\" label=\"Name\" id=\"name\"/>\n\n            <h:outputLabel value=\"Status\" for=\"status\"/>\n            <h:inputText value=\"#{customer.customer.status}\" label=\"Status\" id=\"status\"/>\n\n            <h:outputLabel value=\"Order Limit\" for=\"orderLimit\"/>\n            <h:inputText value=\"#{customer.customer.orderLimit}\" label=\"Order Limit\" id=\"orderLimit\"/>\n\n            <h:outputLabel value=\"Hint\" for=\"hint\" title=\"Customer hint with HTML enabled\"/>\n            <h:inputTextarea value=\"#{customer.customer.hint}\" label=\"Hint\" id=\"hint\"/>\n        </h:panelGrid>\n        <h:commandButton value=\"Save\" action=\"#{customer.save}\"/>\n    </h:form>\n</h:body>\n</html>"
  },
  {
    "path": "Ch07_XSS/src/main/webapp/index.xhtml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"\n        \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n<html xmlns=\"http://www.w3.org/1999/xhtml\" xmlns:h=\"http://xmlns.jcp.org/jsf/html\"\n      xmlns:f=\"http://xmlns.jcp.org/jsf/core\">\n<h:head>\n    <h:outputStylesheet library=\"css\" value=\"styles.css\" name=\"styles.css\" />\n    <title>Chapter 07 - XSS</title>\n</h:head>\n<h:body>\n    <h1>Chapter 07 - XSS</h1>\n\n    <p>This demo application shows Cross-Site Scripting (XSS) with JavaServer Faces (JSF). The first block of links\n    enables normal usage of the demo application (like a normal user). The second block contains attack possibilities\n    with XSS.</p>\n\n    <h2>Normal Usage</h2>\n\n    <ul>\n        <li><h:link outcome=\"createCustomer\" value=\"Create Customer\"/></li>\n        <li>\n            <h:link outcome=\"showCustomers\" value=\"Show Customers\">\n                <f:param name=\"currency\" value=\"EUR\"/>\n            </h:link>\n        </li>\n        <li><h:link outcome=\"search\" value=\"Search Customer\"/></li>\n    </ul>\n\n    <h2>Attacks</h2>\n\n    <ul>\n        <li><h:link outcome=\"showCustomers\" value=\"Stored XSS\"/></li>\n        <li>\n            <h:form>\n                <h:commandLink action=\"#{search.search}\" value=\"Reflected XSS\">\n                    <f:param name=\"customerName\"\n                             value=\"Dummy&lt;script&gt;alert('Reflected XSS - Session ID: ' + document.cookie)&lt;/script&gt;\"/>\n                </h:commandLink>\n            </h:form>\n        </li>\n        <li>\n            <h:link outcome=\"showCustomers\" value=\"DOM Based XSS\">\n                <f:param name=\"currency\"\n                         value=\"&lt;script&gt;alert(&quot;DOM&nbsp;Based&nbsp;XSS&nbsp;-&nbsp;Session&nbsp;ID:&nbsp;&quot;+document.cookie)&lt;/script&gt;\"/>\n            </h:link>\n        </li>\n    </ul>\n\n</h:body>\n</html>"
  },
  {
    "path": "Ch07_XSS/src/main/webapp/resources/css/styles.css",
    "content": "th {\n    font-size: 1.1em;\n    font-weight: bold;\n    padding: 5px;\n}\n\ntd {\n    padding: 5px;\n}\n\nh1 {\n    font-size: 1.5em;\n}\n\nh2 {\n    font-size: 1.2em;\n}\n"
  },
  {
    "path": "Ch07_XSS/src/main/webapp/search.xhtml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"\n        \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n<html xmlns=\"http://www.w3.org/1999/xhtml\" xmlns:h=\"http://xmlns.jcp.org/jsf/html\"\n      xmlns:f=\"http://xmlns.jcp.org/jsf/core\">\n<h:head>\n    <h:outputStylesheet library=\"css\" value=\"styles.css\" name=\"styles.css\" />\n    <title>Chapter 07 - XSS</title>\n</h:head>\n<h:body>\n    <h1>Chapter 07 - XSS</h1>\n\n    <h:form>\n        <h:link outcome=\"index\" value=\"Home\"/> | <h:link outcome=\"createCustomer\" value=\"Create Customer\"/> | <h:link\n            outcome=\"showCustomers\" value=\"Show Customers\"><f:param name=\"currency\" value=\"EUR\"/></h:link>\n    </h:form>\n\n    <h:form id=\"searchCustomers\">\n        <h:panelGrid columns=\"3\">\n            <h:outputLabel value=\"Name\" for=\"name\"/>\n            <h:inputText value=\"#{search.customerName}\" label=\"Name\" id=\"name\"/>\n            <h:commandButton value=\"Search\" action=\"#{search.search}\"/>\n        </h:panelGrid>\n    </h:form>\n</h:body>\n</html>"
  },
  {
    "path": "Ch07_XSS/src/main/webapp/searchCustomer.xhtml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"\n        \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n<html xmlns=\"http://www.w3.org/1999/xhtml\" xmlns:h=\"http://xmlns.jcp.org/jsf/html\"\n      xmlns:f=\"http://xmlns.jcp.org/jsf/core\">\n<h:head>\n    <h:outputStylesheet library=\"css\" value=\"styles.css\" name=\"styles.css\"/>\n    <title>Chapter 07 - XSS</title>\n</h:head>\n<h:body>\n    <h1>Chapter 07 - XSS</h1>\n\n    <h:form>\n        <h:link outcome=\"index\" value=\"Home\"/> | <h:link outcome=\"createCustomer\" value=\"Create Customer\"/> | <h:link\n            outcome=\"showCustomers\" value=\"Show Customers\"><f:param name=\"currency\" value=\"EUR\"/></h:link> | <h:link\n            outcome=\"search\" value=\"Search Customer\"/>\n    </h:form>\n\n    <p>Your search for <strong>[<h:outputText value=\"#{search.customerName}\"\n                                             escape=\"false\"/>]</strong> returned the following results:</p>\n\n    <h:form>\n        <h:dataTable var=\"c\" value=\"#{search.customers}\">\n            <h:column>\n                <f:facet name=\"header\">ID</f:facet>\n                <h:outputText value=\"#{c.custId}\"/>\n            </h:column>\n            <h:column>\n                <f:facet name=\"header\">Name</f:facet>\n                <h:outputText value=\"#{c.name}\"/>\n            </h:column>\n            <h:column>\n                <f:facet name=\"header\">Status</f:facet>\n                <h:outputText value=\"#{c.status}\"/>\n            </h:column>\n            <h:column>\n                <f:facet name=\"header\">Order Limit</f:facet>\n                <h:outputText value=\"#{c.orderLimit}\"/>\n            </h:column>\n            <h:column>\n                <f:facet name=\"header\">Hint</f:facet>\n                <h:outputText escape=\"false\" value=\"#{c.hint}\"/>\n            </h:column>\n        </h:dataTable>\n    </h:form>\n</h:body>\n</html>"
  },
  {
    "path": "Ch07_XSS/src/main/webapp/showCustomers.xhtml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"\n        \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n<html xmlns=\"http://www.w3.org/1999/xhtml\" xmlns:h=\"http://xmlns.jcp.org/jsf/html\"\n      xmlns:f=\"http://xmlns.jcp.org/jsf/core\">\n<h:head>\n    <h:outputStylesheet library=\"css\" value=\"styles.css\" name=\"styles.css\" />\n    <title>Chapter 07 - XSS</title>\n</h:head>\n<h:body>\n    <h1>Chapter 07 - XSS</h1>\n\n    <h:form>\n        <h:link outcome=\"index\" value=\"Home\"/> | <h:link outcome=\"createCustomer\" value=\"Create Customer\"/> | <h:link\n            outcome=\"search\" value=\"Search Customer\"/>\n    </h:form>\n\n    <p>These are all customers currently available in the database:</p>\n\n    <h:form>\n        <h:dataTable var=\"c\" value=\"#{customer.customers}\">\n            <h:column>\n                <f:facet name=\"header\">ID</f:facet>\n                <h:outputText value=\"#{c.custId}\"/>\n            </h:column>\n            <h:column>\n                <f:facet name=\"header\">Name</f:facet>\n                <h:outputText value=\"#{c.name}\"/>\n            </h:column>\n            <h:column>\n                <f:facet name=\"header\">Status</f:facet>\n                <h:outputText value=\"#{c.status}\"/>\n            </h:column>\n            <h:column>\n                <f:facet name=\"header\">Order Limit</f:facet>\n                <h:outputText value=\"#{c.orderLimit}\"/>\n                <script type=\"text/javascript\">\n                    let pos = document.URL.indexOf(\"currency=\");\n                    let currency = \"EUR\";\n\n                    if (pos > 0) {\n                        pos = pos + 9;\n                        currency = document.URL.substring(pos, document.URL.length);\n                    }\n\n                    document.write(decodeURIComponent(currency));\n                </script>\n            </h:column>\n            <h:column>\n                <f:facet name=\"header\">Hint</f:facet>\n                <h:outputText escape=\"false\" value=\"#{c.hint}\"/>\n            </h:column>\n        </h:dataTable>\n    </h:form>\n</h:body>\n</html>"
  },
  {
    "path": "Ch07_XSSFilter/pom.xml",
    "content": "<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n\t<modelVersion>4.0.0</modelVersion>\n\t<parent>\n\t\t<groupId>de.dominikschadow.javawebsecurity</groupId>\n\t\t<artifactId>javawebsecurity</artifactId>\n\t\t<version>1.0.0</version>\n\t</parent>\n\t<artifactId>Ch07_XSSFilter</artifactId>\n\t<packaging>war</packaging>\n\t<name>Chapter 07 - XSS Filter</name>\n\t<url>https://github.com/dschadow/Java-Web-Security</url>\n\t<description>Chapter 7 XSS Filter sample project. Requires a server like Apache Tomcat. Open the web application in your browser at http://localhost:8080/Ch07_XSSFilter</description>\n\n\t<dependencies>\n\t\t<dependency>\n\t\t\t<groupId>org.owasp.esapi</groupId>\n\t\t\t<artifactId>esapi</artifactId>\n\t\t</dependency>\n\t\t<dependency>\n\t\t\t<groupId>javax.servlet</groupId>\n\t\t\t<artifactId>javax.servlet-api</artifactId>\n\t\t</dependency>\n\t\t<dependency>\n\t\t\t<groupId>javax.servlet.jsp</groupId>\n\t\t\t<artifactId>javax.servlet.jsp-api</artifactId>\n\t\t</dependency>\n\t\t<dependency>\n\t\t\t<groupId>javax.servlet</groupId>\n\t\t\t<artifactId>jstl</artifactId>\n\t\t</dependency>\n\t</dependencies>\n\n\t<build>\n\t\t<finalName>Ch07_XSSFilter</finalName>\n\t\t<plugins>\n\t\t\t<plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n\t\t\t\t<artifactId>maven-compiler-plugin</artifactId>\n\t\t\t</plugin>\n\t\t\t<plugin>\n\t\t\t\t<groupId>org.apache.tomcat.maven</groupId>\n\t\t\t\t<artifactId>tomcat7-maven-plugin</artifactId>\n\t\t\t</plugin>\n\t\t</plugins>\n\t</build>\n</project>"
  },
  {
    "path": "Ch07_XSSFilter/src/main/java/de/dominikschadow/webappsecurity/filter/BlacklistFilter.java",
    "content": "/*\n * Copyright (C) 2015 Dominik Schadow, info@dominikschadow.de\n *\n * This file is part of the Java-Web-Security project.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *  http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage de.dominikschadow.webappsecurity.filter;\n\nimport javax.servlet.*;\nimport javax.servlet.http.HttpServletRequest;\nimport java.io.IOException;\n\n/**\n * Request filter calling the <code>BlacklistRequestWrapper</code> for filtering.\n *\n * @see de.dominikschadow.webappsecurity.filter.BlacklistRequestWrapper\n *\n * @author Dominik Schadow\n */\npublic class BlacklistFilter implements Filter {\n    @Override\n    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)\n            throws IOException, ServletException {\n        filterChain.doFilter(new BlacklistRequestWrapper((HttpServletRequest) servletRequest), servletResponse);\n    }\n\n    @Override\n    public void init(FilterConfig filterConfig) {\n    }\n\n    @Override\n    public void destroy() {\n    }\n}\n"
  },
  {
    "path": "Ch07_XSSFilter/src/main/java/de/dominikschadow/webappsecurity/filter/BlacklistRequestWrapper.java",
    "content": "/*\n * Copyright (C) 2015 Dominik Schadow, info@dominikschadow.de\n *\n * This file is part of the Java-Web-Security project.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *  http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage de.dominikschadow.webappsecurity.filter;\n\nimport org.owasp.esapi.ESAPI;\n\nimport javax.servlet.http.HttpServletRequest;\nimport javax.servlet.http.HttpServletRequestWrapper;\nimport java.util.regex.Pattern;\n\n/**\n * Filter HTML tags which can be used for a XSS attack with a blacklist.<br/>\n * <p>\n * Originally based on <a href=\"http://www.javacodegeeks.com/2012/07/anti-cross-site-scripting-xss-filter.html\">Ricardo Zuasti</a>.\n *\n * @author Dominik Schadow\n */\npublic class BlacklistRequestWrapper extends HttpServletRequestWrapper {\n    public BlacklistRequestWrapper(HttpServletRequest servletRequest) {\n        super(servletRequest);\n    }\n\n    @Override\n    public String[] getParameterValues(String parameter) {\n        String[] values = super.getParameterValues(parameter);\n\n        if (values == null) {\n            return null;\n        }\n\n        int count = values.length;\n        String[] encodedValues = new String[count];\n        for (int i = 0; i < count; i++) {\n            encodedValues[i] = stripXSS(values[i]);\n        }\n\n        return encodedValues;\n    }\n\n    @Override\n    public String getParameter(String parameter) {\n        String value = super.getParameter(parameter);\n\n        return stripXSS(value);\n    }\n\n    @Override\n    public String getHeader(String name) {\n        String value = super.getHeader(name);\n\n        return stripXSS(value);\n    }\n\n    private static String stripXSS(String value) {\n        if (value != null) {\n            value = ESAPI.encoder().canonicalize(value);\n\n            // Avoid null characters\n            value = value.replaceAll(\"\", \"\");\n\n            // Avoid anything between script tags\n            Pattern scriptPattern = Pattern.compile(\"<script>(.*?)</script>\", Pattern.CASE_INSENSITIVE);\n            value = scriptPattern.matcher(value).replaceAll(\"\");\n\n            // Avoid anything in a src='...' type of expression\n            scriptPattern = Pattern.compile(\"src[\\r\\n]*=[\\r\\n]*\\\\'(.*?)\\\\'\", Pattern.CASE_INSENSITIVE\n                    | Pattern.MULTILINE | Pattern.DOTALL);\n            value = scriptPattern.matcher(value).replaceAll(\"\");\n\n            scriptPattern = Pattern.compile(\"src[\\r\\n]*=[\\r\\n]*\\\\\\\"(.*?)\\\\\\\"\", Pattern.CASE_INSENSITIVE\n                    | Pattern.MULTILINE | Pattern.DOTALL);\n            value = scriptPattern.matcher(value).replaceAll(\"\");\n\n            // Remove any lonesome </script> tag\n            scriptPattern = Pattern.compile(\"</script>\", Pattern.CASE_INSENSITIVE);\n            value = scriptPattern.matcher(value).replaceAll(\"\");\n\n            // Remove any lonesome <script ...> tag\n            scriptPattern = Pattern.compile(\"<script(.*?)>\", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE\n                    | Pattern.DOTALL);\n            value = scriptPattern.matcher(value).replaceAll(\"\");\n\n            // Avoid eval(...) expressions\n            scriptPattern = Pattern.compile(\"eval\\\\((.*?)\\\\)\", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE\n                    | Pattern.DOTALL);\n            value = scriptPattern.matcher(value).replaceAll(\"\");\n\n            // Avoid expression(...) expressions\n            scriptPattern = Pattern.compile(\"expression\\\\((.*?)\\\\)\", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE\n                    | Pattern.DOTALL);\n            value = scriptPattern.matcher(value).replaceAll(\"\");\n\n            // Avoid javascript:... expressions\n            scriptPattern = Pattern.compile(\"javascript:\", Pattern.CASE_INSENSITIVE);\n            value = scriptPattern.matcher(value).replaceAll(\"\");\n\n            // Avoid vbscript:... expressions\n            scriptPattern = Pattern.compile(\"vbscript:\", Pattern.CASE_INSENSITIVE);\n            value = scriptPattern.matcher(value).replaceAll(\"\");\n\n            // Avoid onload= expressions\n            scriptPattern = Pattern.compile(\"onload(.*?)=\", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE\n                    | Pattern.DOTALL);\n            value = scriptPattern.matcher(value).replaceAll(\"\");\n        }\n        return value;\n    }\n}"
  },
  {
    "path": "Ch07_XSSFilter/src/main/java/de/dominikschadow/webappsecurity/filter/ESAPIFilter.java",
    "content": "/*\n * Copyright (C) 2015 Dominik Schadow, info@dominikschadow.de\n *\n * This file is part of the Java-Web-Security project.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *  http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage de.dominikschadow.webappsecurity.filter;\n\nimport javax.servlet.*;\nimport javax.servlet.http.HttpServletRequest;\nimport java.io.IOException;\n\n/**\n * Request filter calling the <code>ESAPIRequestWrapper</code> for filtering.\n *\n * @see de.dominikschadow.webappsecurity.filter.ESAPIRequestWrapper\n *\n * @author Dominik Schadow\n */\npublic class ESAPIFilter implements Filter {\n    @Override\n    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)\n            throws IOException, ServletException {\n        filterChain.doFilter(new ESAPIRequestWrapper((HttpServletRequest) servletRequest), servletResponse);\n    }\n\n    @Override\n    public void init(FilterConfig filterConfig) {\n    }\n\n    @Override\n    public void destroy() {\n    }\n}\n"
  },
  {
    "path": "Ch07_XSSFilter/src/main/java/de/dominikschadow/webappsecurity/filter/ESAPIRequestWrapper.java",
    "content": "/*\n * Copyright (C) 2015 Dominik Schadow, info@dominikschadow.de\n *\n * This file is part of the Java-Web-Security project.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *  http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage de.dominikschadow.webappsecurity.filter;\n\nimport org.owasp.esapi.ESAPI;\n\nimport javax.servlet.http.HttpServletRequest;\nimport javax.servlet.http.HttpServletRequestWrapper;\n\n/**\n * Filter HTML tags which can be used for a XSS attack with the ESAPI library.<br/>\n *\n * @author Dominik Schadow\n */\npublic class ESAPIRequestWrapper extends HttpServletRequestWrapper {\n    public ESAPIRequestWrapper(HttpServletRequest servletRequest) {\n        super(servletRequest);\n    }\n\n    @Override\n    public String[] getParameterValues(String parameter) {\n        String[] values = super.getParameterValues(parameter);\n\n        if (values == null) {\n            return null;\n        }\n\n        int count = values.length;\n        String[] encodedValues = new String[count];\n\n        for (int i = 0; i < count; i++) {\n            encodedValues[i] = escapeHTML(values[i]);\n        }\n\n        return encodedValues;\n    }\n\n    @Override\n    public String getParameter(String parameter) {\n        String value = super.getParameter(parameter);\n\n        return escapeHTML(value);\n    }\n\n    @Override\n    public String getHeader(String name) {\n        String value = super.getHeader(name);\n        return escapeHTML(value);\n    }\n\n    // Modified stripXSS without blacklist\n    private String escapeHTML(String value) {\n        if (value != null) {\n            value = ESAPI.encoder().canonicalize(value);\n            value = ESAPI.encoder().encodeForHTML(value);\n        }\n\n        return value;\n    }\n}"
  },
  {
    "path": "Ch07_XSSFilter/src/main/resources/ESAPI.properties",
    "content": "# Logging\nLogger.ApplicationName=Ch07_XSSFilter"
  },
  {
    "path": "Ch07_XSSFilter/src/main/webapp/WEB-INF/web.xml",
    "content": "<?xml version=\"1.0\"?>\n<web-app id=\"Ch07_XSSFilter\" version=\"3.0\"\n\txmlns=\"http://java.sun.com/xml/ns/javaee\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n\txsi:schemaLocation=\"http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd\">\n\t<display-name>Ch07_XSSFilter</display-name>\n\t<filter>\n\t\t<display-name>ESAPIFilter</display-name>\n\t\t<filter-name>ESAPIFilter</filter-name>\n\t\t<filter-class>de.dominikschadow.webappsecurity.filter.ESAPIFilter</filter-class>\n\t</filter>\n    <filter>\n        <display-name>BlacklistFilter</display-name>\n        <filter-name>BlacklistFilter</filter-name>\n        <filter-class>de.dominikschadow.webappsecurity.filter.BlacklistFilter</filter-class>\n    </filter>\n    <filter-mapping>\n        <filter-name>ESAPIFilter</filter-name>\n        <url-pattern>/outputEsapi.jsp</url-pattern>\n    </filter-mapping>\n\t<filter-mapping>\n\t\t<filter-name>BlacklistFilter</filter-name>\n\t\t<url-pattern>/outputBlacklist.jsp</url-pattern>\n\t</filter-mapping>\n</web-app>\n"
  },
  {
    "path": "Ch07_XSSFilter/src/main/webapp/index.jsp",
    "content": "<%@ page language=\"java\" contentType=\"text/html; charset=UTF-8\" pageEncoding=\"UTF-8\"%>\n<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n<html lang=\"en\">\n<head>\n    <meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n    <title>Chapter 07 - XSS Filter</title>\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"resources/css/styles.css\" />\n</head>\n<body>\n\t<h1>Chapter 07 - XSS Filter</h1>\n\n    <p>This demo application shows how the Enterprise Security API (ESAPI) can escape potentially dangerous input. The\n        second form uses a blacklist to remove dangerous tags and attributes from the input before displaying it.\n        Feel free to enter any attack data like <strong>&lt;script&gt;alert(&apos;XSS&apos;)&lt;/script&gt;</strong>\n        and try to outsmart the filter.</p>\n\n    <form method=\"post\" name=\"esapiForm\" action=\"outputEsapi.jsp\">\n        <fieldset>\n            <legend>ESAPI Filter</legend>\n            <label for=\"esapi\" title=\"Name\">Name</label>\n            <input type=\"text\" id=\"esapi\" name=\"esapi\" class=\"text-input\" />\n            <input type=\"submit\" value=\"Submit\" />\n        </fieldset>\n    </form>\n\n    <form method=\"post\" name=\"blacklistForm\" action=\"outputBlacklist.jsp\">\n        <fieldset>\n            <legend>Blacklist Filter</legend>\n            <label for=\"blacklist\" title=\"Name\">Name</label>\n            <input type=\"text\" id=\"blacklist\" name=\"blacklist\" class=\"text-input\" />\n            <input type=\"submit\" value=\"Submit\" />\n        </fieldset>\n    </form>\n</body>\n</html>\n"
  },
  {
    "path": "Ch07_XSSFilter/src/main/webapp/outputBlacklist.jsp",
    "content": "<%@ page language=\"java\" contentType=\"text/html; charset=UTF-8\" pageEncoding=\"UTF-8\"%>\n<%@ taglib prefix=\"c\" uri=\"http://java.sun.com/jsp/jstl/core\" %>\n<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n<html lang=\"en\">\n<head>\n    <meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n    <title>Chapter 07 - XSS Filter</title>\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"resources/css/styles.css\" />\n</head>\n<body>\n    <h1>Chapter 07 - XSS Filter</h1>\n\n\t<p>This output is filtered by a blacklist filter and removes dangerous input before displaying the data. Depending\n        on your input, the next line might be empty. [] are used to indicate the position of the given input.</p>\n\n\t<p>[<%= request.getParameter(\"blacklist\") %>]</p>\n\n    <a href=\"<c:url value=\"/\" />\">Back</a>\n</body>\n</html>"
  },
  {
    "path": "Ch07_XSSFilter/src/main/webapp/outputEsapi.jsp",
    "content": "<%@ page language=\"java\" contentType=\"text/html; charset=UTF-8\" pageEncoding=\"UTF-8\"%>\n<%@ taglib prefix=\"c\" uri=\"http://java.sun.com/jsp/jstl/core\" %>\n<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n<html lang=\"en\">\n<head>\n    <meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n    <title>Chapter 07 - XSS Filter</title>\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"resources/css/styles.css\" />\n</head>\n<body>\n    <h1>Chapter 07 - XSS Filter</h1>\n\n    <p>This output is filtered by an ESAPI filter. This filter escapes potentially dangerous input. [] are used to\n        indicate the position of the given input.</p>\n\n    <p>[<%= request.getParameter(\"esapi\") %>]</p>\n\n    <a href=\"<c:url value=\"/\" />\">Back</a>\n</body>\n</html>"
  },
  {
    "path": "Ch07_XSSFilter/src/main/webapp/resources/css/styles.css",
    "content": "h1 {\n    font-size: 1.5em;\n}\n\nfieldset {\n    width: 500px;\n    font-size: 1.2em;\n    margin-top: 20px;\n}\n\ninput {\n    display: inline-block;\n    vertical-align: middle;\n    width: 300px;\n}\n\ninput[type=submit] {\n    width: 75px;\n    height: 20px;\n    margin-left: 10px;\n}\n\nlabel {\n    margin-right: 10px;\n}\n"
  },
  {
    "path": "Ch07_XSSJSF/pom.xml",
    "content": "<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0    http://maven.apache.org/maven-v4_0_0.xsd\">\r\n\t<modelVersion>4.0.0</modelVersion>\r\n\t<parent>\r\n\t\t<groupId>de.dominikschadow.javawebsecurity</groupId>\r\n\t\t<artifactId>javawebsecurity</artifactId>\r\n\t\t<version>1.0.0</version>\r\n\t</parent>\r\n\t<artifactId>Ch07_XSSJSF</artifactId>\r\n\t<packaging>war</packaging>\r\n\t<name>Chapter 07 - XSS with JSF</name>\r\n\t<url>https://github.com/dschadow/Java-Web-Security</url>\r\n\t<description>Chapter 7 XSS with JSF sample project. Requires a server like Apache Tomcat. Open the web application in your browser at http://localhost:8080/Ch07_XSSJSF</description>\r\n\r\n\t<dependencies>\r\n\t\t<dependency>\r\n\t\t\t<groupId>com.sun.faces</groupId>\r\n\t\t\t<artifactId>jsf-api</artifactId>\r\n\t\t</dependency>\r\n\t\t<dependency>\r\n\t\t\t<groupId>com.sun.faces</groupId>\r\n\t\t\t<artifactId>jsf-impl</artifactId>\r\n\t\t</dependency>\r\n\t</dependencies>\r\n\r\n\t<build>\r\n\t\t<finalName>Ch07_XSSJSF</finalName>\r\n\t\t<plugins>\r\n\t\t\t<plugin>\r\n                <groupId>org.apache.maven.plugins</groupId>\r\n\t\t\t\t<artifactId>maven-compiler-plugin</artifactId>\r\n\t\t\t</plugin>\r\n\t\t\t<plugin>\r\n\t\t\t\t<groupId>org.apache.tomcat.maven</groupId>\r\n\t\t\t\t<artifactId>tomcat7-maven-plugin</artifactId>\r\n\t\t\t</plugin>\r\n\t\t</plugins>\r\n\t</build>\r\n</project>"
  },
  {
    "path": "Ch07_XSSJSF/src/main/java/de/dominikschadow/webappsecurity/MaximumController.java",
    "content": "/*\n * Copyright (C) 2015 Dominik Schadow, info@dominikschadow.de\n *\n * This file is part of the Java-Web-Security project.\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * \n *  http://www.apache.org/licenses/LICENSE-2.0\n * \n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage de.dominikschadow.webappsecurity;\n\nimport javax.faces.bean.ManagedBean;\nimport javax.faces.bean.SessionScoped;\nimport java.io.Serial;\nimport java.io.Serializable;\nimport java.util.LinkedHashMap;\nimport java.util.Map;\n\n/**\n * Bean representing user input into the maximum protected output page\n * (with additional security related attributes).\n *\n * @author Dominik Schadow\n */\n@ManagedBean(name = \"maximum\")\n@SessionScoped\npublic class MaximumController implements Serializable {\n    @Serial\n    private static final long serialVersionUID = 600561947836364528L;\n    private String input = \"<script>alert('XSS with JSF')</script>\";\n    private Map<String, String> maximumMap = null;\n    private Status[] maximumArray = null;\n\n    public Map<String, String> getMaximumMap() {\n        return maximumMap;\n    }\n\n    public Status[] getMaximumArray() {\n        return maximumArray;\n    }\n\n    public String getInput() {\n        return input;\n    }\n\n    public void setInput(String input) {\n        this.input = input;\n\n        maximumMap = new LinkedHashMap<>();\n        maximumMap.put(input, input);\n\n        maximumArray = new Status[1];\n        maximumArray[0] = new Status(input);\n    }\n}"
  },
  {
    "path": "Ch07_XSSJSF/src/main/java/de/dominikschadow/webappsecurity/StandardController.java",
    "content": "/*\n * Copyright (C) 2015 Dominik Schadow, info@dominikschadow.de\n *\n * This file is part of the Java-Web-Security project.\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * \n *  http://www.apache.org/licenses/LICENSE-2.0\n * \n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage de.dominikschadow.webappsecurity;\n\nimport javax.faces.bean.ManagedBean;\nimport javax.faces.bean.SessionScoped;\nimport java.io.Serial;\nimport java.io.Serializable;\nimport java.util.LinkedHashMap;\nimport java.util.Map;\n\n/**\n * Bean representing user input into the standard protected output page\n * (no additional security related attributes).\n *\n * @author Dominik Schadow\n */\n@ManagedBean(name = \"standard\")\n@SessionScoped\npublic class StandardController implements Serializable {\n    @Serial\n    private static final long serialVersionUID = 4083596061570021965L;\n\n    private String input = \"<script>alert('XSS with JSF')</script>\";\n\n    private Map<String, String> standardMap = null;\n    private Status[] standardArray = null;\n\n    public Map<String, String> getStandardMap() {\n        return standardMap;\n    }\n\n    public Status[] getStandardArray() {\n        return standardArray;\n    }\n\n    public String getInput() {\n        return input;\n    }\n\n    public void setInput(String input) {\n        this.input = input;\n\n        standardMap = new LinkedHashMap<>();\n        standardMap.put(input, input);\n\n        standardArray = new Status[1];\n        standardArray[0] = new Status(input);\n    }\n}"
  },
  {
    "path": "Ch07_XSSJSF/src/main/java/de/dominikschadow/webappsecurity/Status.java",
    "content": "/*\n * Copyright (C) 2015 Dominik Schadow, info@dominikschadow.de\n *\n * This file is part of the Java-Web-Security project.\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * \n *  http://www.apache.org/licenses/LICENSE-2.0\n * \n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage de.dominikschadow.webappsecurity;\n\nimport java.io.Serial;\nimport java.io.Serializable;\n\n/**\n * Represents one Status array entry.\n *\n * @author Dominik Schadow\n */\npublic class Status implements Serializable {\n    @Serial\n    private static final long serialVersionUID = -5176873476153674154L;\n    private String label;\n    private String value;\n\n    public Status(String text) {\n        this.label = text;\n        this.value = text;\n    }\n\n    public String getLabel() {\n        return label;\n    }\n\n    public String getValue() {\n        return value;\n    }\n}\n"
  },
  {
    "path": "Ch07_XSSJSF/src/main/webapp/WEB-INF/faces-config.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<faces-config version=\"2.2\"\n              xmlns=\"http://xmlns.jcp.org/xml/ns/javaee\"\n              xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n              xsi:schemaLocation=\"http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-facesconfig_2_2.xsd\">\n</faces-config>"
  },
  {
    "path": "Ch07_XSSJSF/src/main/webapp/WEB-INF/web.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<web-app xmlns=\"http://xmlns.jcp.org/xml/ns/javaee\"\n         xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n         xsi:schemaLocation=\"http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd\"\n         version=\"3.1\">\n    <display-name>Ch07_XSSJSF</display-name>\n\n    <context-param>\n        <param-name>javax.faces.PROJECT_STAGE</param-name>\n        <param-value>Development</param-value>\n    </context-param>\n\n    <servlet>\n        <servlet-name>Faces Servlet</servlet-name>\n        <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>\n        <load-on-startup>1</load-on-startup>\n    </servlet>\n\n    <servlet-mapping>\n        <servlet-name>Faces Servlet</servlet-name>\n        <url-pattern>*.xhtml</url-pattern>\n    </servlet-mapping>\n\n    <welcome-file-list>\n        <welcome-file>index.xhtml</welcome-file>\n    </welcome-file-list>\n</web-app>"
  },
  {
    "path": "Ch07_XSSJSF/src/main/webapp/index.xhtml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"\r\n        \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\r\n<html xmlns=\"http://www.w3.org/1999/xhtml\" xmlns:h=\"http://xmlns.jcp.org/jsf/html\">\r\n<h:head>\r\n    <h:outputStylesheet library=\"css\" value=\"styles.css\" name=\"styles.css\" />\r\n    <title>Chapter 07 - XSS with JSF</title>\r\n</h:head>\r\n<h:body>\r\n    <h1>Chapter 07 - XSS with JSF</h1>\r\n\t<p>The first form posts to a page processing the input in elements with default attributes. The second form posts\r\n    to a page which is configured as secure as possible using all available attributes to escape the output.</p>\r\n\t\r\n\t<h2>Default Attributes</h2>\r\n\t\r\n\t<h:form id=\"standardForm\">\r\n\t\t<h:inputText value=\"#{standard.input}\" id=\"standard\" styleClass=\"text-input\" />\r\n\r\n\t\t<h:commandButton value=\"Submit\" action=\"standard\" styleClass=\"send-button\" />\r\n\t</h:form>\r\n\t\r\n\t<h2>Secure Attributes</h2>\r\n\t\r\n\t<h:form id=\"maximumForm\">\r\n\t\t<h:inputText value=\"#{maximum.input}\" id=\"maximum\" styleClass=\"text-input\" />\r\n\r\n\t\t<h:commandButton value=\"Submit\" action=\"maximum\" styleClass=\"send-button\" />\r\n\t</h:form>\r\n</h:body>\r\n</html>"
  },
  {
    "path": "Ch07_XSSJSF/src/main/webapp/maximum.xhtml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"\r\n        \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\r\n<html xmlns=\"http://www.w3.org/1999/xhtml\" xmlns:h=\"http://xmlns.jcp.org/jsf/html\"\r\n      xmlns:f=\"http://xmlns.jcp.org/jsf/core\">\r\n<h:head>\r\n    <h:outputStylesheet library=\"css\" value=\"styles.css\" name=\"styles.css\" />\r\n    <title>Chapter 07 - XSS with JSF</title>\r\n</h:head>\r\n<h:body>\r\n\t<h1>Chapter 07 - XSS with JSF</h1>\r\n\r\n\t<p>All available security attributes are set for all elements on this page.</p>\r\n\r\n\t<h:form>\r\n\t    <h2>selectOneMenu with Map</h2> \r\n\t  \t<h:selectOneMenu>\r\n\t\t\t<f:selectItems value=\"#{maximum.maximumMap}\" itemEscaped=\"true\" itemLabelEscaped=\"true\" escape=\"true\" />\r\n\t\t</h:selectOneMenu>\r\n\t    \r\n\t    <h2>selectOneMenu with Array</h2>\r\n\t  \t<h:selectOneMenu>\r\n\t\t\t<f:selectItems value=\"#{maximum.maximumArray}\" var=\"a\"\r\n\t\t\t\titemLabel=\"#{a.label}\" itemValue=\"#{a.value}\" itemEscaped=\"true\" itemLabelEscaped=\"true\" escape=\"true\" />\r\n\t\t</h:selectOneMenu>\r\n\t\t\r\n\t\t<h2>selectOneMenu with selectItem</h2>\r\n\t  \t<h:selectOneMenu>\r\n\t\t\t<f:selectItem itemLabel=\"#{maximum.input}\" itemValue=\"#{maximum.input}\" itemEscaped=\"true\" itemLabelEscaped=\"true\" escape=\"true\" />\r\n\t\t</h:selectOneMenu>\r\n\t\t\r\n\t\t<h2>outputText element</h2>\r\n\t\t<h:outputText value=\"#{maximum.input}\" escape=\"true\" />\r\n\t\t\r\n\t\t<h2>outputText direct value expression</h2>\r\n\t\t#{maximum.input}\r\n\t</h:form>\r\n\r\n    <p><a href=\"index.xhtml\">Back</a></p>\r\n</h:body>\r\n</html>"
  },
  {
    "path": "Ch07_XSSJSF/src/main/webapp/resources/css/styles.css",
    "content": ".text-input {\n    width: 250px;\n}\n\n.send-button {\n    margin-left: 25px;\n}\n\nh1 {\n    font-size: 1.5em;\n}\n\nh2 {\n    font-size: 1.2em;\n}\n"
  },
  {
    "path": "Ch07_XSSJSF/src/main/webapp/standard.xhtml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"\r\n        \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\r\n<html xmlns=\"http://www.w3.org/1999/xhtml\" xmlns:h=\"http://xmlns.jcp.org/jsf/html\"\r\n      xmlns:f=\"http://xmlns.jcp.org/jsf/core\">\r\n<h:head>\r\n    <h:outputStylesheet library=\"css\" value=\"styles.css\" name=\"styles.css\" />\r\n    <title>Chapter 07 - XSS with JSF</title>\r\n</h:head>\r\n<h:body>\r\n\t<h1>Chapter 07 - XSS with JSF</h1>\r\n\t<p>Only the default attributes are active for all elements on this page.</p>\r\n\r\n\t<h:form>\r\n\t    <h2>selectOneMenu with Map</h2> \r\n\t  \t<h:selectOneMenu>\r\n\t\t\t<f:selectItems value=\"#{standard.standardMap}\" />\r\n\t\t</h:selectOneMenu>\r\n\t    \r\n\t    <h2>selectOneMenu with Array</h2>\r\n\t  \t<h:selectOneMenu>\r\n\t\t\t<f:selectItems value=\"#{standard.standardArray}\" var=\"a\"\r\n\t\t\t\titemLabel=\"#{a.label}\" itemValue=\"#{a.value}\" />\r\n\t\t</h:selectOneMenu>\r\n\t\t\r\n\t\t<h2>selectOneMenu with selectItem</h2>\r\n\t  \t<h:selectOneMenu>\r\n\t\t\t<f:selectItem itemLabel=\"#{standard.input}\" itemValue=\"#{standard.input}\" />\r\n\t\t</h:selectOneMenu>\r\n\t\t\r\n\t\t<h2>outputText element</h2>\r\n\t\t<h:outputText value=\"#{standard.input}\" />\r\n\t\t\r\n\t\t<h2>outputText direct value expression</h2>\r\n\t\t#{standard.input}\r\n\t</h:form>\r\n\r\n    <p><a href=\"index.xhtml\">Back</a></p>\r\n</h:body>\r\n</html>"
  },
  {
    "path": "Ch08_CSRF/pom.xml",
    "content": "<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n\t<modelVersion>4.0.0</modelVersion>\n\t<parent>\n\t\t<groupId>de.dominikschadow.javawebsecurity</groupId>\n\t\t<artifactId>javawebsecurity</artifactId>\n\t\t<version>1.0.0</version>\n\t</parent>\n\t<artifactId>Ch08_CSRF</artifactId>\n\t<packaging>war</packaging>\n\t<name>Chapter 08 - CSRF</name>\n\t<url>https://github.com/dschadow/Java-Web-Security</url>\n\t<description>Chapter 8 CSRF sample project. Requires a server like Apache Tomcat. Open the web application in your browser at http://localhost:8080/Ch08_CSRF</description>\n\n\t<dependencies>\n\t\t<dependency>\n\t\t\t<groupId>javax.servlet</groupId>\n\t\t\t<artifactId>javax.servlet-api</artifactId>\n\t\t</dependency>\n\t\t<dependency>\n\t\t\t<groupId>org.owasp.esapi</groupId>\n\t\t\t<artifactId>esapi</artifactId>\n\t\t</dependency>\n\t\t<dependency>\n\t\t\t<groupId>ch.qos.logback</groupId>\n\t\t\t<artifactId>logback-classic</artifactId>\n\t\t</dependency>\n\t</dependencies>\n\t\n\t<build>\n\t\t<finalName>Ch08_CSRF</finalName>\n\t\t<plugins>\n\t\t\t<plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n\t\t\t\t<artifactId>maven-compiler-plugin</artifactId>\n\t\t\t</plugin>\n\t\t\t<plugin>\n\t\t\t\t<groupId>org.apache.maven.plugins</groupId>\n\t\t\t\t<artifactId>maven-war-plugin</artifactId>\n\t\t\t\t<configuration>\n\t\t\t\t\t<failOnMissingWebXml>false</failOnMissingWebXml>\n\t\t\t\t</configuration>\n\t\t\t</plugin>\n\t\t\t<plugin>\n\t\t\t\t<groupId>org.apache.tomcat.maven</groupId>\n\t\t\t\t<artifactId>tomcat7-maven-plugin</artifactId>\n\t\t\t</plugin>\n\t\t</plugins>\n\t</build>\n</project>"
  },
  {
    "path": "Ch08_CSRF/src/main/java/de/dominikschadow/webappsecurity/servlets/ProtectedServlet.java",
    "content": "/*\n * Copyright (C) 2015 Dominik Schadow, info@dominikschadow.de\n *\n * This file is part of the Java-Web-Security project.\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * \n *  http://www.apache.org/licenses/LICENSE-2.0\n * \n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage de.dominikschadow.webappsecurity.servlets;\n\nimport de.dominikschadow.webappsecurity.token.CSRFTokenHandler;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport javax.servlet.ServletException;\nimport javax.servlet.annotation.WebServlet;\nimport javax.servlet.http.HttpServlet;\nimport javax.servlet.http.HttpServletRequest;\nimport javax.servlet.http.HttpServletResponse;\nimport java.io.IOException;\nimport java.io.PrintWriter;\nimport java.io.Serial;\nimport java.security.NoSuchAlgorithmException;\nimport java.security.NoSuchProviderException;\n\n/**\n * Basic protected servlet for GET and POST requests. Checks the CSRF-Token value to identify\n * CSRF attacks. Prints out all information to standard out and returns the received parameter\n * as response.\n *\n * @author Dominik Schadow\n */\n@WebServlet(name = \"ProtectedServlet\", urlPatterns = {\"/ProtectedServlet\"})\npublic class ProtectedServlet extends HttpServlet {\n    @Serial\n    private static final long serialVersionUID = 1L;\n    private static final Logger LOGGER = LoggerFactory.getLogger(ProtectedServlet.class);\n\n    @Override\n    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException {\n        LOGGER.info(\"Processing protected GET request\");\n\n        response.setContentType(\"text/html\");\n\n        try {\n            if (!CSRFTokenHandler.isValid(request)) {\n                LOGGER.warn(\"CSRF token is invalid\");\n                response.setStatus(401);\n\n                try (PrintWriter out = response.getWriter()) {\n                    out.println(\"CSRF token is invalid\");\n                } catch (IOException ex) {\n                    LOGGER.error(ex.getMessage(), ex);\n                }\n\n                return;\n            }\n        } catch (NoSuchAlgorithmException | NoSuchProviderException ex) {\n            LOGGER.error(ex.getMessage(), ex);\n        }\n\n        LOGGER.info(\"CSRF token is valid\");\n\n        String newPassword = request.getParameter(\"newPassword\");\n        String confirmPassword = request.getParameter(\"confirmPassword\");\n\n        LOGGER.info(\"Received {} and {} as GET parameter.\", newPassword, confirmPassword);\n\n        try (PrintWriter out = response.getWriter()) {\n            out.println(\"<html>\");\n            out.println(\"<head>\");\n            out.println(\"<title>Chapter 08 - CSRF</title>\");\n            out.println(\"<link rel=\\\"stylesheet\\\" type=\\\"text/css\\\" href=\\\"resources/css/styles.css\\\" />\");\n            out.println(\"</head>\");\n            out.println(\"<body>\");\n            out.println(\"<h1>Chapter 08 - CSRF</h1>\");\n            out.println(\"<p>Received <b>\" + newPassword + \"</b> and <b>\" + confirmPassword + \"</b> as GET parameter.</p>\");\n            out.println(\"<p><a href=\\\"requests-protected.html\\\">Back</a></p>\");\n            out.println(\"</body>\");\n            out.println(\"</html>\");\n        } catch (IOException ex) {\n            LOGGER.error(ex.getMessage(), ex);\n        }\n    }\n\n    @Override\n    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException {\n        LOGGER.info(\"Processing protected POST request\");\n\n        response.setContentType(\"text/html\");\n\n        try {\n            if (!CSRFTokenHandler.isValid(request)) {\n                LOGGER.warn(\"CSRF token is invalid\");\n                response.setStatus(401);\n\n                return;\n            }\n        } catch (NoSuchAlgorithmException | NoSuchProviderException ex) {\n            LOGGER.error(ex.getMessage(), ex);\n        }\n\n        LOGGER.info(\"CSRF token is valid\");\n\n        String newPassword = request.getParameter(\"newPassword\");\n        String confirmPassword = request.getParameter(\"confirmPassword\");\n\n        LOGGER.info(\"Received {} and {} as POST parameter.\", newPassword, confirmPassword);\n\n        try (PrintWriter out = response.getWriter()) {\n            out.println(\"<html>\");\n            out.println(\"<head>\");\n            out.println(\"<title>Chapter 08 - CSRF</title>\");\n            out.println(\"<link rel=\\\"stylesheet\\\" type=\\\"text/css\\\" href=\\\"resources/css/styles.css\\\" />\");\n            out.println(\"</head>\");\n            out.println(\"<body>\");\n            out.println(\"<h1>Chapter 08 - CSRF</h1>\");\n            out.println(\"<p>Received <b>\" + newPassword + \"</b> and <b>\" + confirmPassword + \"</b> as POST parameter.</p>\");\n            out.println(\"<p><a href=\\\"requests-protected.html\\\">Back</a></p>\");\n            out.println(\"</body>\");\n            out.println(\"</html>\");\n        } catch (IOException ex) {\n            LOGGER.error(ex.getMessage(), ex);\n        }\n    }\n}\n"
  },
  {
    "path": "Ch08_CSRF/src/main/java/de/dominikschadow/webappsecurity/servlets/UnprotectedServlet.java",
    "content": "/*\n * Copyright (C) 2015 Dominik Schadow, info@dominikschadow.de\n *\n * This file is part of the Java-Web-Security project.\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * \n *  http://www.apache.org/licenses/LICENSE-2.0\n * \n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage de.dominikschadow.webappsecurity.servlets;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport javax.servlet.annotation.WebServlet;\nimport javax.servlet.http.HttpServlet;\nimport javax.servlet.http.HttpServletRequest;\nimport javax.servlet.http.HttpServletResponse;\nimport java.io.IOException;\nimport java.io.PrintWriter;\nimport java.io.Serial;\n\n/**\n * Basic unprotected servlet for GET and POST requests. Prints out all information to standard out\n * and returns the received parameter as response.\n *\n * @author Dominik Schadow\n */\n@WebServlet(name = \"UnprotectedServlet\", urlPatterns = {\"/UnprotectedServlet\"})\npublic class UnprotectedServlet extends HttpServlet {\n    @Serial\n    private static final long serialVersionUID = 1L;\n    private static final Logger LOGGER = LoggerFactory.getLogger(UnprotectedServlet.class);\n\n    @Override\n    protected void doGet(HttpServletRequest request, HttpServletResponse response) {\n        String newPassword = request.getParameter(\"newPassword\");\n        String confirmPassword = request.getParameter(\"confirmPassword\");\n\n        LOGGER.info(\"Processing unprotected GET request: Received {} and {} as parameter.\", newPassword, confirmPassword);\n\n        response.setContentType(\"text/html\");\n\n        try (PrintWriter out = response.getWriter()) {\n            out.println(\"<html>\");\n            out.println(\"<head>\");\n            out.println(\"<title>Chapter 08 - CSRF</title>\");\n            out.println(\"<link rel=\\\"stylesheet\\\" type=\\\"text/css\\\" href=\\\"resources/css/styles.css\\\" />\");\n            out.println(\"</head>\");\n            out.println(\"<body>\");\n            out.println(\"<h1>Chapter 08 - CSRF</h1>\");\n            out.println(\"<p>Received <b>\" + newPassword + \"</b> and <b>\" + confirmPassword + \"</b> as GET parameter.</p>\");\n            out.println(\"<p><a href=\\\"requests-unprotected.html\\\">Back</a></p>\");\n            out.println(\"</body>\");\n            out.println(\"</html>\");\n        } catch (IOException ex) {\n            LOGGER.error(ex.getMessage(), ex);\n        }\n    }\n\n    @Override\n    protected void doPost(HttpServletRequest request, HttpServletResponse response) {\n        String newPassword = request.getParameter(\"newPassword\");\n        String confirmPassword = request.getParameter(\"confirmPassword\");\n\n        LOGGER.info(\"Processing unprotected POST request: Received {} and {} as parameter.\", newPassword, confirmPassword);\n\n        response.setContentType(\"text/html\");\n\n        try (PrintWriter out = response.getWriter()) {\n            out.println(\"<html>\");\n            out.println(\"<head>\");\n            out.println(\"<title>Chapter 08 - CSRF</title>\");\n            out.println(\"<link rel=\\\"stylesheet\\\" type=\\\"text/css\\\" href=\\\"resources/css/styles.css\\\" />\");\n            out.println(\"</head>\");\n            out.println(\"<body>\");\n            out.println(\"<h1>Chapter 08 - CSRF</h1>\");\n            out.println(\"<p>Received <b>\" + newPassword + \"</b> and <b>\" + confirmPassword + \"</b> as POST parameter.</p>\");\n            out.println(\"<p><a href=\\\"requests-unprotected.html\\\">Back</a></p>\");\n            out.println(\"</body>\");\n            out.println(\"</html>\");\n        } catch (IOException ex) {\n            LOGGER.error(ex.getMessage(), ex);\n        }\n    }\n}\n"
  },
  {
    "path": "Ch08_CSRF/src/main/java/de/dominikschadow/webappsecurity/token/CSRFTokenHandler.java",
    "content": "/*\n * Copyright (C) 2015 Dominik Schadow, info@dominikschadow.de\n *\n * This file is part of Java-Web-Security\n.\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * \n *  http://www.apache.org/licenses/LICENSE-2.0\n * \n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage de.dominikschadow.webappsecurity.token;\n\nimport org.apache.commons.lang.StringUtils;\n\nimport javax.servlet.ServletException;\nimport javax.servlet.http.HttpServletRequest;\nimport javax.servlet.http.HttpSession;\nimport java.security.NoSuchAlgorithmException;\nimport java.security.NoSuchProviderException;\nimport java.security.SecureRandom;\n\n/**\n * Calculates a new token and adds it to the session. Compares the session toke value with the\n * token value included in the request.\n *\n * @author Dominik Schadow\n */\npublic final class CSRFTokenHandler {\n    public static final String CSRF_TOKEN = \"CSRF_TOKEN\";\n    private static final String MISSING_SESSION = \"No session available\";\n\n    /**\n     * Private constructor to prevent initialization.\n     */\n    private CSRFTokenHandler() {\n    }\n\n    private static String getToken() throws NoSuchAlgorithmException, NoSuchProviderException {\n        SecureRandom sr = SecureRandom.getInstance(\"SHA1PRNG\", \"SUN\");\n        sr.nextBytes(new byte[20]);\n        return String.valueOf(sr.nextLong());\n    }\n\n    public static String getToken(HttpSession session) throws ServletException, NoSuchAlgorithmException,\n            NoSuchProviderException {\n        if (session == null) {\n            throw new ServletException(MISSING_SESSION);\n        }\n\n        String token = (String) session.getAttribute(CSRF_TOKEN);\n\n        if (StringUtils.isEmpty(token)) {\n            token = getToken();\n            session.setAttribute(CSRF_TOKEN, token);\n        }\n\n        return token;\n    }\n\n    public static boolean isValid(HttpServletRequest request) throws ServletException, NoSuchAlgorithmException,\n            NoSuchProviderException {\n        if (request.getSession(false) == null) {\n            throw new ServletException(MISSING_SESSION);\n        }\n\n        return StringUtils.equals(getToken(request.getSession(false)), request.getParameter(CSRF_TOKEN));\n    }\n}"
  },
  {
    "path": "Ch08_CSRF/src/main/resources/logback.xml",
    "content": "<configuration>\n    <appender name=\"STDOUT\" class=\"ch.qos.logback.core.ConsoleAppender\">\n        <encoder>\n            <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>\n        </encoder>\n    </appender>\n\n    <root level=\"INFO\">\n        <appender-ref ref=\"STDOUT\" />\n    </root>\n</configuration>"
  },
  {
    "path": "Ch08_CSRF/src/main/webapp/form-protected.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <title>Chapter 08 - CSRF</title>\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"resources/css/styles.css\" />\n</head>\n<body onload=\"document.changePasswordForm.submit()\">\n    <h1>Chapter 08 - CSRF: Hidden Form</h1>\n\n    <form action=\"ProtectedServlet\" name=\"changePasswordForm\" method=\"POST\" target=\"hiddenFrame\">\n        <input type=\"hidden\" name=\"newPassword\" value=\"HiddenForm\">\n        <input type=\"hidden\" name=\"confirmPassword\" value=\"HiddenForm\">\n    </form>\n\n    <p><a href=\"requests-protected.html\">Back</a></p>\n\n    <iframe name=\"hiddenFrame\" style=\"display: none;\"></iframe>\n</body>\n</html>"
  },
  {
    "path": "Ch08_CSRF/src/main/webapp/form-unprotected.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <title>Chapter 08 - CSRF</title>\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"resources/css/styles.css\" />\n</head>\n<body onload=\"document.changePasswordForm.submit()\">\n    <h1>Chapter 08 - CSRF: Hidden Form</h1>\n\n    <form action=\"UnprotectedServlet\" name=\"changePasswordForm\" method=\"post\" target=\"hiddenFrame\">\n        <input type=\"hidden\" name=\"newPassword\" value=\"HiddenForm\">\n        <input type=\"hidden\" name=\"confirmPassword\" value=\"HiddenForm\">\n    </form>\n\n    <p><a href=\"requests-unprotected.html\">Back</a></p>\n\n    <iframe name=\"hiddenFrame\" style=\"display: none;\"></iframe>\n</body>\n</html>"
  },
  {
    "path": "Ch08_CSRF/src/main/webapp/form-working.jsp",
    "content": "<%@ page language=\"java\" contentType=\"text/html; charset=UTF-8\" pageEncoding=\"UTF-8\"%>\n<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n<%@ page import=\"de.dominikschadow.webappsecurity.token.CSRFTokenHandler\" %>\n<html lang=\"en\">\n<head>\n    <meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n    <title>Chapter 08 - CSRF</title>\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"resources/css/styles.css\" />\n</head>\n<body>\n    <h1>Chapter 08 - CSRF: Working Form</h1>\n\n    <form action=\"ProtectedServlet\" name=\"changePasswordForm\" method=\"POST\">\n        <input type=\"hidden\" name=\"<%=CSRFTokenHandler.CSRF_TOKEN%>\"\n               value=\"<%=CSRFTokenHandler.getToken(request.getSession(false))%>\">\n        <table>\n            <tr>\n                <td><label for=\"newPassword\">New Password</label></td>\n                <td><input type=\"password\" id=\"newPassword\" name=\"newPassword\" class=\"text-input\"></td>\n            </tr>\n            <tr>\n                <td><label for=\"confirmPassword\">Confirm Password</label></td>\n                <td><input type=\"password\" id=\"confirmPassword\" name=\"confirmPassword\" class=\"text-input\"></td>\n            </tr>\n            <tr>\n                <td>&nbsp;</td>\n                <td><input type=\"submit\" value=\"Submit\"></td>\n            </tr>\n        </table>\n    </form>\n</body>\n</html>"
  },
  {
    "path": "Ch08_CSRF/src/main/webapp/image-protected.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <title>Chapter 08 - CSRF</title>\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"resources/css/styles.css\" />\n</head>\n<body>\n    <h1>Chapter 08 - CSRF: Hidden Image</h1>\n\n    <p><a href=\"requests-protected.html\">Back</a></p>\n\n    <img src=\"ProtectedServlet?newPassword=HiddenImage&confirmPassword=HiddenImage\" width=\"0\" height=\"0\" />\n</body>\n</html>"
  },
  {
    "path": "Ch08_CSRF/src/main/webapp/image-unprotected.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <title>Chapter 08 - CSRF</title>\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"resources/css/styles.css\" />\n</head>\n<body>\n    <h1>Chapter 08 - CSRF: Hidden Image</h1>\n\n    <p><a href=\"requests-unprotected.html\">Back</a></p>\n\n    <img src=\"UnprotectedServlet?newPassword=HiddenImage&confirmPassword=HiddenImage\" width=\"0\" height=\"0\" />\n</body>\n</html>"
  },
  {
    "path": "Ch08_CSRF/src/main/webapp/index.jsp",
    "content": "<%@ page language=\"java\" contentType=\"text/html; charset=UTF-8\" pageEncoding=\"UTF-8\"%>\n<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n<%@ page import=\"de.dominikschadow.webappsecurity.token.CSRFTokenHandler\" %>\n<html lang=\"en\">\n<head>\n    <meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n    <title>Chapter 08 - CSRF</title>\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"resources/css/styles.css\" />\n</head>\n<body>\n    <h1>Chapter 08 - CSRF</h1>\n\n    <p>The generated CSRF token for this session is: <%=CSRFTokenHandler.getToken(request.getSession(false))%></p>\n\n    <ul>\n        <li><a href=\"requests-unprotected.html\">Unprotected Requests</a></li>\n        <li><a href=\"requests-protected.html\">Protected Requests</a></li>\n    </ul>\n</body>\n</html>\n"
  },
  {
    "path": "Ch08_CSRF/src/main/webapp/requests-protected.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <title>Chapter 08 - CSRF</title>\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"resources/css/styles.css\" />\n</head>\n<body>\n\t<h1>Chapter 08 - CSRF: Protected Requests</h1>\n    <p>The following links show different ways to trigger a GET or POST request with CSRF protection in the backend.</p>\n\t\n\t<h2>GET Requests</h2>\n    <p>GET requests are easy to trigger and only require some HTML.</p>\n\n    <ul>\n        <li><a href=\"ProtectedServlet?newPassword=UrlParameter&confirmPassword=UrlParameter\">Link</a></li>\n        <li><a href=\"image-protected.html\">Image</a></li>\n    </ul>\n\n\t<h2>POST Requests</h2>\n    <p>POST requests are a little bit harder to trigger and require JavaScript.</p>\n\n    <ul>\n        <li><a href=\"form-protected.html\">Hidden Form</a></li>\n        <li><a href=\"form-working.jsp\">Working Form</a></li>\n        <li><a href=\"xmlhttprequest-protected.html\">XMLHttpRequest</a></li>\n    </ul>\n\n    <p><a href=\"index.jsp\">Back</a></p>\n</body>\n</html>\n"
  },
  {
    "path": "Ch08_CSRF/src/main/webapp/requests-unprotected.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <title>Chapter 08 - CSRF</title>\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"resources/css/styles.css\" />\n</head>\n<body>\n\t<h1>Chapter 08 - CSRF: Unprotected Requests</h1>\n\t<p>The following links show different ways to trigger a GET or POST request without any CSRF protection in the backend.</p>\n\n\t<h2>GET Requests</h2>\n    <p>GET requests are easy to trigger and only require some HTML.</p>\n\n    <ul>\n        <li><a href=\"UnprotectedServlet?newPassword=UrlParameter&confirmPassword=UrlParameter\">Link</a></li>\n        <li><a href=\"image-unprotected.html\">Image</a></li>\n    </ul>\n\t\n\t<h2>POST Requests</h2>\n    <p>POST requests are a little bit harder to trigger and require JavaScript.</p>\n\n    <ul>\n        <li><a href=\"form-unprotected.html\">Form</a></li>\n        <li><a href=\"xmlhttprequest-unprotected.html\">XMLHttpRequest</a></li>\n    </ul>\n\n    <p><a href=\"index.jsp\">Back</a></p>\n</body>\n</html>\n"
  },
  {
    "path": "Ch08_CSRF/src/main/webapp/resources/css/styles.css",
    "content": ".text-input {\n    width: 250px;\n}\n\nh1 {\n    font-size: 1.5em;\n}\n\nh2 {\n    font-size: 1.2em;\n}\n"
  },
  {
    "path": "Ch08_CSRF/src/main/webapp/xmlhttprequest-protected.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <title>Chapter 08 - CSRF</title>\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"resources/css/styles.css\" />\n\n    <script type=\"text/javascript\">\n        function sendForm() {\n            const params = \"newPassword=XMLHttpRequest&confirmPassword=XMLHttpRequest\";\n            const request = new XMLHttpRequest();\n\n            request.open(\"POST\", \"http://localhost:8080/Ch08_CSRF/ProtectedServlet\", true);\n            request.setRequestHeader(\"Content-type\", \"application/x-www-form-urlencoded\");\n            request.send(params);\n        }\n    </script>\n</head>\n<body onload=\"sendForm()\">\n    <h1>Chapter 08 - CSRF</h1>\n\n    <p><a href=\"requests-protected.html\">Back</a></p>\n</body>\n</html>"
  },
  {
    "path": "Ch08_CSRF/src/main/webapp/xmlhttprequest-unprotected.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <title>Chapter 08 - CSRF</title>\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"resources/css/styles.css\" />\n\n    <script type=\"text/javascript\">\n        function sendForm() {\n            const params = \"newPassword=XMLHttpRequest&confirmPassword=XMLHttpRequest\";\n            const request = new XMLHttpRequest();\n\n            request.open(\"POST\", \"http://localhost:8080/Ch08_CSRF/UnprotectedServlet\", true);\n            request.setRequestHeader(\"Content-type\", \"application/x-www-form-urlencoded\");\n            request.send(params);\n        }\n    </script>\n</head>\n<body onload=\"sendForm()\">\n    <h1>Chapter 08 - CSRF: XMLHttpRequest</h1>\n\n    <p><a href=\"requests-unprotected.html\">Back</a></p>\n</body>\n</html>"
  },
  {
    "path": "LICENSE",
    "content": "Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"{}\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright {yyyy} {name of copyright owner}\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n\n"
  },
  {
    "path": "README.md",
    "content": "Java-Web-Security\n==============\n\nThis repository contains the complete code samples from my book **Java-Web-Security - Sichere Webanwendungen mit Java entwickeln** (dpunkt.verlag, ISBN 978-3-86490-146-1), available as [Print](http://www.dpunkt.de/buecher/4198/java-web-security.html), as [PDF/EPub](http://www.dpunkt.de/buecher/4825/java-web-security.html) and for [Kindle](http://www.amazon.de/gp/product/B00IUJM3J4/ref=as_li_qf_sp_asin_tl?ie=UTF8&camp=1638&creative=6742&creativeASIN=B00IUJM3J4&linkCode=as2&tag=dominikswelt).\n\nAll Java projects are created as **Maven** projects and require [Java 17](https://adoptium.net/temurin/) and [Apache Maven 3](http://maven.apache.org) or newer. In **Eclipse** you therefore need to install the Maven integration via the Eclipse update manager. After that, you can either use the **git m2e connector (m2e-egit)** to import the new projects directly from the repository. Alternatively, you can clone the repository and use **Import Maven Projects** instead (no connector required here). **IntelliJ IDEA** supports this out of the box.\n\n**Mozilla Firefox** is the recommended and up until today working browser for all vulnerable web applications in this repository. Keep in mind that browsers or some add-ons may block or filter certain attacks already. Deactivate all blocking or intercepting add-ons or try a different browser if a sample application is not working.\n\nThe easiest way to start a web application is to use the **Maven-Tomcat7-Plug-in** in each project: **mvn tomcat7:run-war** (or simply **mvn** in the console, since this is the default goal). Open your browser and point it to **http://localhost:8080/PROJECT_NAME**, e.g. **http://localhost:8080/Ch04_OutputEscaping**. The project name is always the final part of the URL.\n\nSee the following subsections for a short description and the requirements to execute the sample code and launch the web application.\n\n## Ch04_OutputEscaping\nWeb application using JavaServer Pages (JSP) to show the difference between output escaping via Enterprise Security API (ESAPI) and no output escaping at all. Use an input like *&lt;script&gt;alert(&#x27;XSS&#x27;)&lt;/script&gt;* to examine the difference.\n\n**Requirements:** Apache Tomcat, Webbrowser\n\n## Ch04_OutputEscapingJSF\nWeb application using JavaServer Faces (JSF) to demonstrate the two different possibilities to show user input in a web page with *#{contact.firstname}* and *&lt;h:outputText value=\"#{contact.firstname}\" /&gt;*. Use an input like *&lt;script&gt;alert(&#x27;XSS&#x27;)&lt;/script&gt;* to examine the difference.\n\n**Requirements:** Apache Tomcat, Webbrowser\n\n## Ch04_OutputEscapingJSP\nSpring based web application using JavaServer Pages (JSP) to demonstrate the two different possibilities to show user input in a web page with *${contact.firstname}* and *&lt;c:out value=\"${contact.firstname}\" /&gt;*. Use an input like *&lt;script&gt;alert(&#x27;XSS&#x27;)&lt;/script&gt;* to examine the difference.\n\n**Requirements:** Apache Tomcat, Webbrowser\n\n## Ch05_AccessReferenceMaps\nWeb application using JavaServer Faces (JSF) to show the difference between using unprotected and protected Maps (with *IntegerAccessReferenceMaps* and *RandomAccessReferenceMaps*) with user data.\n\n**Requirements:** Apache Tomcat, Webbrowser\n\n## Ch05_HSTS\nWeb application using a Servlet filter to add the *Strict-Transport-Security* header to each response.\n\n**Requirements:** Apache Tomcat, Webbrowser\n\n## Ch05_SessionFixation\nWeb application invalidating an existing session and its session id before continuing the login process. This web application requires the included special *context.xml* configuration for Tomcat in order to display the current session id via JavaScript.\n\n**Requirements:** Apache Tomcat, Webbrowser\n\n## Ch05_SessionHandling\nWeb application containing a complete *web.xml* configuration showing how to protect cookies and other session data. Contains only a start page which fails trying to show the session cookie in a JavaScript popup.\n\n**Requirements:** Apache Tomcat, Webbrowser\n\n## Ch06_SQLInjection\nWeb application using user input to query a in-memory-database. The entered data is used as part of a normal *Statement*, an *escaped Statement*, a *Prepared Statement* and as input for a *Hibernate Query Language*.\n\n**Requirements:** Apache Tomcat, Webbrowser\n\n## Ch06_XPathInjection\nWeb application using user input to query a simple XML document. The entered data (name and password) is used as part of a normal *XPath expression* without any escaping and escaped as part of another *XPath expression*. The unescaped version is prune to XPath Injection, which makes it possible to retrieve more data of the XML document as the intended order limit.\n\n**Requirements:** Apache Tomcat, Webbrowser\n\n## Ch07_CSP\nWeb application with three input processing servlets. One is unprotected and processes any input without input validation or output escaping and is prone to Cross-Site Scripting. The second servlet adds a minimal *Content-Security-Policy* header to the response and allows to use any source from the same page (URL). This already protects the response page from Cross-Site Scripting in supported browsers. The third form adds a *Content-Security-Policy-Report-Only* header and shows how easy the reported data can be processed.\n\n**Requirements:** Apache Tomcat, Webbrowser\n\n## Ch07_XSS\nWeb application to test the three XSS types *stored*, *reflected* and *DOM based*. The input textfield is vulnerable to XSS and can be easily protected by enabling output escaping. Cookie could be protected by removing the special *context.xml* and by setting the corresponding *web.xml* parameter.\n\nThis web application requires the included special *context.xml* configuration for Tomcat in order to display the current session id via JavaScript.\n\n**Requirements:** Apache Tomcat, Webbrowser\n\n## Ch07_XSSFilter\nWeb application showing the differences between a blacklist and an ESAPI based request filtering. Use an input like *&lt;script&gt;alert(&#x27;XSS&#x27;)&lt;/script&gt;* to see the different output on the output pages.\n\n**Requirements:** Apache Tomcat, Webbrowser\n\n## Ch07_XSSJSF\nJavaServer Faces (JSF) based web application accepting user input in two forms. The first form results into an output page showing the user input in drop down boxes and output text fields with all default attributes active. The second form results into an output page using the same output fields with any additional security related attribute set to the maximum. Use an input like *&lt;script&gt;alert(&#x27;XSS&#x27;)&lt;/script&gt;* to challenge the JSF XSS protection.\n\n**Requirements:** Apache Tomcat, Webbrowser\n\n## Ch08_CSRF\nWeb application showing Cross-Site Request Forgery (CSRF) with GET and POST requests and how to protect forms with an anti CSRF token. All requests on the **Unprotected Requests** page are successful and reach the backend as a normal request. The **Protected Requests** page contains successful (with token) and unsuccessful (without token) requests; only the valid requests are processed in the backend.\n\n**Requirements:** Apache Tomcat, Webbrowser\n\n## Meta\n![Build](https://github.com/dschadow/Java-Web-Security/workflows/Build/badge.svg) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)\n"
  },
  {
    "path": "pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n         xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n    <modelVersion>4.0.0</modelVersion>\n    <artifactId>javawebsecurity</artifactId>\n    <groupId>de.dominikschadow.javawebsecurity</groupId>\n    <version>1.0.0</version>\n    <packaging>pom</packaging>\n    <name>Java-Web-Security</name>\n    <url>https://github.com/dschadow/Java-Web-Security</url>\n    <description>This repository contains the complete code samples from my book 'Java-Web-Security - Sichere\n        Webanwendungen mit Java entwickeln' (dpunkt.verlag, ISBN 978-3-86490-146-1).\n    </description>\n\n    <organization>\n        <name>Dominik Schadow</name>\n        <url>https://blog.dominikschadow.de</url>\n    </organization>\n\n    <issueManagement>\n        <system>GitHub</system>\n        <url>https://github.com/dschadow/Java-Web-Security/issues</url>\n    </issueManagement>\n\n    <scm>\n        <connection>scm:git:git@github.com:dschadow/Java-Web-Security.git</connection>\n        <developerConnection>scm:git:git@github.com:dschadow/Java-Web-Security.git</developerConnection>\n        <url>https://github.com/dschadow/Java-Web-Security</url>\n    </scm>\n\n    <licenses>\n        <license>\n            <name>Apache License 2.0</name>\n            <url>https://www.apache.org/licenses/LICENSE-2.0</url>\n        </license>\n    </licenses>\n\n    <properties>\n        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>\n        <spring.version>5.3.29</spring.version>\n        <slf4j.version>1.7.33</slf4j.version>\n        <jsf.version>2.2.20</jsf.version>\n        <hibernate.version>5.6.15.Final</hibernate.version>\n        <junit.jupiter.version>6.0.3</junit.jupiter.version>\n        <hamcrest.version>3.0</hamcrest.version>\n        <java.version>17</java.version>\n    </properties>\n\n    <dependencyManagement>\n        <dependencies>\n            <dependency>\n                <groupId>javax.servlet</groupId>\n                <artifactId>javax.servlet-api</artifactId>\n                <version>4.0.1</version>\n                <scope>provided</scope>\n            </dependency>\n            <dependency>\n                <groupId>javax.servlet.jsp</groupId>\n                <artifactId>javax.servlet.jsp-api</artifactId>\n                <version>2.3.3</version>\n                <scope>provided</scope>\n            </dependency>\n            <dependency>\n                <groupId>javax.servlet</groupId>\n                <artifactId>jstl</artifactId>\n                <version>1.2</version>\n                <scope>compile</scope>\n            </dependency>\n            <dependency>\n                <groupId>org.owasp.esapi</groupId>\n                <artifactId>esapi</artifactId>\n                <version>2.7.0.0</version>\n                <exclusions>\n                    <exclusion>\n                        <groupId>javax.servlet</groupId>\n                        <artifactId>servlet-api</artifactId>\n                    </exclusion>\n                    <exclusion>\n                        <artifactId>antisamy</artifactId>\n                        <groupId>org.owasp.antisamy</groupId>\n                    </exclusion>\n                </exclusions>\n            </dependency>\n            <dependency>\n                <groupId>org.springframework</groupId>\n                <artifactId>spring-test</artifactId>\n                <version>${spring.version}</version>\n                <scope>test</scope>\n            </dependency>\n            <dependency>\n                <groupId>org.springframework</groupId>\n                <artifactId>spring-webmvc</artifactId>\n                <version>${spring.version}</version>\n            </dependency>\n            <dependency>\n                <groupId>com.h2database</groupId>\n                <artifactId>h2</artifactId>\n                <version>2.4.240</version>\n                <scope>runtime</scope>\n            </dependency>\n            <dependency>\n                <groupId>org.hibernate</groupId>\n                <artifactId>hibernate-core</artifactId>\n                <version>${hibernate.version}</version>\n            </dependency>\n            <dependency>\n                <groupId>com.sun.faces</groupId>\n                <artifactId>jsf-api</artifactId>\n                <version>${jsf.version}</version>\n            </dependency>\n            <dependency>\n                <groupId>com.sun.faces</groupId>\n                <artifactId>jsf-impl</artifactId>\n                <version>${jsf.version}</version>\n            </dependency>\n            <dependency>\n                <groupId>ch.qos.logback</groupId>\n                <artifactId>logback-classic</artifactId>\n                <version>1.5.32</version>\n            </dependency>\n            <dependency>\n                <groupId>org.apache.commons</groupId>\n                <artifactId>commons-lang3</artifactId>\n                <version>3.20.0</version>\n            </dependency>\n            <dependency>\n                <groupId>org.junit.jupiter</groupId>\n                <artifactId>junit-jupiter-engine</artifactId>\n                <version>${junit.jupiter.version}</version>\n                <scope>test</scope>\n            </dependency>\n            <dependency>\n                <groupId>org.hamcrest</groupId>\n                <artifactId>hamcrest-library</artifactId>\n                <version>${hamcrest.version}</version>\n                <scope>test</scope>\n            </dependency>\n        </dependencies>\n    </dependencyManagement>\n\n    <build>\n        <plugins>\n            <plugin>\n                <groupId>com.github.spotbugs</groupId>\n                <artifactId>spotbugs-maven-plugin</artifactId>\n                <version>4.9.8.3</version>\n                <configuration>\n                    <effort>Max</effort>\n                    <threshold>Low</threshold>\n                    <plugins>\n                        <plugin>\n                            <groupId>com.h3xstream.findsecbugs</groupId>\n                            <artifactId>findsecbugs-plugin</artifactId>\n                            <version>1.14.0</version>\n                        </plugin>\n                    </plugins>\n                </configuration>\n            </plugin>\n        </plugins>\n\n        <pluginManagement>\n            <plugins>\n                <plugin>\n                    <groupId>org.apache.maven.plugins</groupId>\n                    <artifactId>maven-compiler-plugin</artifactId>\n                    <version>3.15.0</version>\n                    <configuration>\n                        <source>${java.version}</source>\n                        <target>${java.version}</target>\n                    </configuration>\n                </plugin>\n                <plugin>\n                    <groupId>org.apache.tomcat.maven</groupId>\n                    <artifactId>tomcat7-maven-plugin</artifactId>\n                    <version>2.2</version>\n                </plugin>\n                <plugin>\n                    <groupId>org.apache.maven.plugins</groupId>\n                    <artifactId>maven-war-plugin</artifactId>\n                    <version>3.5.1</version>\n                </plugin>\n                <plugin>\n                    <groupId>org.apache.maven.plugins</groupId>\n                    <artifactId>maven-site-plugin</artifactId>\n                    <version>3.21.0</version>\n                </plugin>\n                <plugin>\n                    <groupId>org.apache.maven.plugins</groupId>\n                    <artifactId>maven-project-info-reports-plugin</artifactId>\n                    <version>3.9.0</version>\n                </plugin>\n            </plugins>\n        </pluginManagement>\n    </build>\n\n    <reporting>\n        <plugins>\n            <plugin>\n                <groupId>org.owasp</groupId>\n                <artifactId>dependency-check-maven</artifactId>\n                <version>12.2.1</version>\n                <configuration>\n                    <skipProvidedScope>true</skipProvidedScope>\n                    <skipRuntimeScope>true</skipRuntimeScope>\n                </configuration>\n                <reportSets>\n                    <reportSet>\n                        <reports>\n                            <report>aggregate</report>\n                        </reports>\n                    </reportSet>\n                </reportSets>\n            </plugin>\n        </plugins>\n    </reporting>\n\n    <modules>\n        <module>Ch04_OutputEscaping</module>\n        <module>Ch04_OutputEscapingJSF</module>\n        <module>Ch04_OutputEscapingJSP</module>\n        <module>Ch05_AccessReferenceMaps</module>\n        <module>Ch05_HSTS</module>\n        <module>Ch05_SessionFixation</module>\n        <module>Ch05_SessionHandling</module>\n        <module>Ch06_SQLInjection</module>\n        <module>Ch06_XPathInjection</module>\n        <module>Ch07_CSP</module>\n        <module>Ch07_XSS</module>\n        <module>Ch07_XSSFilter</module>\n        <module>Ch07_XSSJSF</module>\n        <module>Ch08_CSRF</module>\n    </modules>\n</project>"
  }
]