You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@knox.apache.org by lm...@apache.org on 2013/11/27 15:48:24 UTC

git commit: #KNOX-198 CSRF Header Support - added WebAppSec provider for web application security vulnerability prevention and a CSRF prevention filter.

Updated Branches:
  refs/heads/master 184ee06e1 -> 9901058dc


#KNOX-198 CSRF Header Support - added WebAppSec provider for web application security vulnerability prevention and a CSRF prevention filter.


Project: http://git-wip-us.apache.org/repos/asf/incubator-knox/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-knox/commit/9901058d
Tree: http://git-wip-us.apache.org/repos/asf/incubator-knox/tree/9901058d
Diff: http://git-wip-us.apache.org/repos/asf/incubator-knox/diff/9901058d

Branch: refs/heads/master
Commit: 9901058dc9dbf95b1e98311273f94eb623ecc8fe
Parents: 184ee06
Author: Larry McCay <lm...@hortonworks.com>
Authored: Wed Nov 27 09:46:09 2013 -0500
Committer: Larry McCay <lm...@hortonworks.com>
Committed: Wed Nov 27 09:47:46 2013 -0500

----------------------------------------------------------------------
 gateway-provider-security-webappsec/pom.xml     | 85 ++++++++++++++++++
 .../gateway/webappsec/WebAppSecMessages.java    | 26 ++++++
 .../webappsec/deploy/WebAppSecContributor.java  | 66 ++++++++++++++
 .../webappsec/filter/CSRFPreventionFilter.java  | 71 +++++++++++++++
 ...gateway.deploy.ProviderDeploymentContributor | 19 ++++
 .../gateway/provider/federation/CSRFTest.java   | 30 +++++++
 gateway-release/pom.xml                         |  4 +
 .../hadoop/gateway/GatewayBasicFuncTest.java    | 92 +++++++++++++++++++-
 .../hadoop/gateway/GatewayFuncTestDriver.java   | 16 ++++
 pom.xml                                         |  6 ++
 10 files changed, 414 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-knox/blob/9901058d/gateway-provider-security-webappsec/pom.xml
----------------------------------------------------------------------
diff --git a/gateway-provider-security-webappsec/pom.xml b/gateway-provider-security-webappsec/pom.xml
new file mode 100644
index 0000000..02411d1
--- /dev/null
+++ b/gateway-provider-security-webappsec/pom.xml
@@ -0,0 +1,85 @@
+<!--
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+<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">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.apache.hadoop</groupId>
+        <artifactId>gateway</artifactId>
+        <version>0.4.0-SNAPSHOT</version>
+    </parent>
+    <artifactId>gateway-provider-security-webappsec</artifactId>
+
+    <name>gateway-provider-security-webappsec</name>
+    <description>An extension of the gateway introducing web application security protections.</description>
+
+    <licenses>
+        <license>
+            <name>The Apache Software License, Version 2.0</name>
+            <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
+            <distribution>repo</distribution>
+        </license>
+    </licenses>
+
+    <dependencies>
+        <dependency>
+            <groupId>${gateway-group}</groupId>
+            <artifactId>gateway-spi</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>${gateway-group}</groupId>
+            <artifactId>gateway-util-common</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>commons-io</groupId>
+            <artifactId>commons-io</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>commons-codec</groupId>
+            <artifactId>commons-codec</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.hadoop</groupId>
+            <artifactId>hadoop-cmf</artifactId>
+            <version>3.0.0-SNAPSHOT</version>
+        </dependency>
+
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.easymock</groupId>
+            <artifactId>easymock</artifactId>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.hadoop</groupId>
+            <artifactId>gateway-test-utils</artifactId>
+            <scope>test</scope>
+        </dependency>
+
+    </dependencies>
+
+</project>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-knox/blob/9901058d/gateway-provider-security-webappsec/src/main/java/org/apache/hadoop/gateway/webappsec/WebAppSecMessages.java
----------------------------------------------------------------------
diff --git a/gateway-provider-security-webappsec/src/main/java/org/apache/hadoop/gateway/webappsec/WebAppSecMessages.java b/gateway-provider-security-webappsec/src/main/java/org/apache/hadoop/gateway/webappsec/WebAppSecMessages.java
new file mode 100644
index 0000000..7cf68f4
--- /dev/null
+++ b/gateway-provider-security-webappsec/src/main/java/org/apache/hadoop/gateway/webappsec/WebAppSecMessages.java
@@ -0,0 +1,26 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.hadoop.gateway.webappsec;
+
+import org.apache.hadoop.gateway.i18n.messages.Message;
+import org.apache.hadoop.gateway.i18n.messages.MessageLevel;
+import org.apache.hadoop.gateway.i18n.messages.Messages;
+
+@Messages(logger="org.apache.hadoop.gateway.provider.global.csrf")
+public interface WebAppSecMessages {
+}

http://git-wip-us.apache.org/repos/asf/incubator-knox/blob/9901058d/gateway-provider-security-webappsec/src/main/java/org/apache/hadoop/gateway/webappsec/deploy/WebAppSecContributor.java
----------------------------------------------------------------------
diff --git a/gateway-provider-security-webappsec/src/main/java/org/apache/hadoop/gateway/webappsec/deploy/WebAppSecContributor.java b/gateway-provider-security-webappsec/src/main/java/org/apache/hadoop/gateway/webappsec/deploy/WebAppSecContributor.java
new file mode 100644
index 0000000..6a54b9e
--- /dev/null
+++ b/gateway-provider-security-webappsec/src/main/java/org/apache/hadoop/gateway/webappsec/deploy/WebAppSecContributor.java
@@ -0,0 +1,66 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.hadoop.gateway.webappsec.deploy;
+
+import java.util.List;
+import java.util.Map;
+
+import org.apache.hadoop.gateway.deploy.DeploymentContext;
+import org.apache.hadoop.gateway.deploy.ProviderDeploymentContributorBase;
+import org.apache.hadoop.gateway.descriptor.FilterParamDescriptor;
+import org.apache.hadoop.gateway.descriptor.ResourceDescriptor;
+import org.apache.hadoop.gateway.topology.Provider;
+import org.apache.hadoop.gateway.topology.Service;
+
+public class WebAppSecContributor extends
+    ProviderDeploymentContributorBase {
+  private static final String ROLE = "webappsec";
+  private static final String NAME = "WebAppSec";
+  private static final String CSRF_SUFFIX = "_CSRF";
+  private static final String CSRF_FILTER_CLASSNAME = "org.apache.hadoop.gateway.webappsec.filter.CSRFPreventionFilter";
+  private static final String CSRF_ENABLED = "csrf.enabled";
+
+  @Override
+  public String getRole() {
+    return ROLE;
+  }
+
+  @Override
+  public String getName() {
+    return NAME;
+  }
+
+  @Override
+  public void initializeContribution(DeploymentContext context) {
+    super.initializeContribution(context);
+  }
+
+  @Override
+  public void contributeFilter(DeploymentContext context, Provider provider, Service service, 
+      ResourceDescriptor resource, List<FilterParamDescriptor> params) {
+    
+    Provider webappsec = context.getTopology().getProvider(ROLE, NAME);
+    if (webappsec != null && webappsec.isEnabled()) {
+      Map<String,String> map = provider.getParams();
+      String csrfEnabled = map.get(CSRF_ENABLED);
+      if ( csrfEnabled != null && csrfEnabled.equals("true")) {
+        resource.addFilter().name( getName() + CSRF_SUFFIX ).role( getRole() ).impl( CSRF_FILTER_CLASSNAME ).params( params );
+      }
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-knox/blob/9901058d/gateway-provider-security-webappsec/src/main/java/org/apache/hadoop/gateway/webappsec/filter/CSRFPreventionFilter.java
----------------------------------------------------------------------
diff --git a/gateway-provider-security-webappsec/src/main/java/org/apache/hadoop/gateway/webappsec/filter/CSRFPreventionFilter.java b/gateway-provider-security-webappsec/src/main/java/org/apache/hadoop/gateway/webappsec/filter/CSRFPreventionFilter.java
new file mode 100644
index 0000000..eb98b8c
--- /dev/null
+++ b/gateway-provider-security-webappsec/src/main/java/org/apache/hadoop/gateway/webappsec/filter/CSRFPreventionFilter.java
@@ -0,0 +1,71 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.hadoop.gateway.webappsec.filter;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+public class CSRFPreventionFilter implements Filter {
+  private static final String CUSTOM_HEADER_PARAM = "csrf.customHeader";
+  private static final String CUSTOM_METHODS_TO_IGNORE_PARAM = "csrf.methodsToIgnore";
+  private String  headerName = "X-XSRF-Header";
+  private String  mti = "GET,OPTIONS,HEAD";
+  private Set<String> methodsToIgnore = null;
+  
+  @Override
+  public void init( FilterConfig filterConfig ) throws ServletException {
+    String customHeader = filterConfig.getInitParameter(CUSTOM_HEADER_PARAM);
+    if (customHeader != null) {
+      headerName = customHeader;
+    }
+    String customMTI = filterConfig.getInitParameter(CUSTOM_METHODS_TO_IGNORE_PARAM);
+    if (customMTI != null) {
+      mti = customMTI;
+    }
+    methodsToIgnore = new HashSet<String>(Arrays.asList(mti));
+  }
+  
+  @Override
+  public void doFilter(ServletRequest request, ServletResponse response,
+      FilterChain chain) throws IOException, ServletException {
+    if (!methodsToIgnore.contains(((HttpServletRequest) request).getMethod()) && !(((HttpServletRequest) request).getHeader(headerName) != null)) {
+      ((HttpServletResponse)response).sendError(HttpServletResponse.SC_BAD_REQUEST, "Missing Required Header for Vulnerability Protection");
+    }
+    chain.doFilter(request, response);
+  }
+
+  /* (non-Javadoc)
+   * @see javax.servlet.Filter#destroy()
+   */
+  @Override
+  public void destroy() {
+    // TODO Auto-generated method stub
+    
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-knox/blob/9901058d/gateway-provider-security-webappsec/src/main/resources/META-INF/services/org.apache.hadoop.gateway.deploy.ProviderDeploymentContributor
----------------------------------------------------------------------
diff --git a/gateway-provider-security-webappsec/src/main/resources/META-INF/services/org.apache.hadoop.gateway.deploy.ProviderDeploymentContributor b/gateway-provider-security-webappsec/src/main/resources/META-INF/services/org.apache.hadoop.gateway.deploy.ProviderDeploymentContributor
new file mode 100644
index 0000000..9a060d3
--- /dev/null
+++ b/gateway-provider-security-webappsec/src/main/resources/META-INF/services/org.apache.hadoop.gateway.deploy.ProviderDeploymentContributor
@@ -0,0 +1,19 @@
+##########################################################################
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+##########################################################################
+
+org.apache.hadoop.gateway.webappsec.deploy.WebAppSecContributor

http://git-wip-us.apache.org/repos/asf/incubator-knox/blob/9901058d/gateway-provider-security-webappsec/src/test/java/org/apache/hadoop/gateway/provider/federation/CSRFTest.java
----------------------------------------------------------------------
diff --git a/gateway-provider-security-webappsec/src/test/java/org/apache/hadoop/gateway/provider/federation/CSRFTest.java b/gateway-provider-security-webappsec/src/test/java/org/apache/hadoop/gateway/provider/federation/CSRFTest.java
new file mode 100644
index 0000000..28ec021
--- /dev/null
+++ b/gateway-provider-security-webappsec/src/test/java/org/apache/hadoop/gateway/provider/federation/CSRFTest.java
@@ -0,0 +1,30 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.hadoop.gateway.provider.federation;
+
+import junit.framework.TestCase;
+
+import org.apache.hadoop.gateway.services.security.token.impl.JWTToken;
+import org.junit.Test;
+
+public class CSRFTest extends TestCase {
+  @Test
+  public void testCsrf() throws Exception {
+    assertTrue(true);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-knox/blob/9901058d/gateway-release/pom.xml
----------------------------------------------------------------------
diff --git a/gateway-release/pom.xml b/gateway-release/pom.xml
index 2b8c1d2..982be2b 100644
--- a/gateway-release/pom.xml
+++ b/gateway-release/pom.xml
@@ -163,6 +163,10 @@
         </dependency>
         <dependency>
             <groupId>${gateway-group}</groupId>
+            <artifactId>gateway-provider-security-webappsec</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>${gateway-group}</groupId>
             <artifactId>gateway-provider-security-authz-acls</artifactId>
         </dependency>
         <dependency>

http://git-wip-us.apache.org/repos/asf/incubator-knox/blob/9901058d/gateway-test/src/test/java/org/apache/hadoop/gateway/GatewayBasicFuncTest.java
----------------------------------------------------------------------
diff --git a/gateway-test/src/test/java/org/apache/hadoop/gateway/GatewayBasicFuncTest.java b/gateway-test/src/test/java/org/apache/hadoop/gateway/GatewayBasicFuncTest.java
index 11eeb0c..973e8ff 100644
--- a/gateway-test/src/test/java/org/apache/hadoop/gateway/GatewayBasicFuncTest.java
+++ b/gateway-test/src/test/java/org/apache/hadoop/gateway/GatewayBasicFuncTest.java
@@ -150,6 +150,13 @@ public class GatewayBasicFuncTest {
         .addRoot( "topology" )
           .addTag( "gateway" )
             .addTag( "provider" )
+              .addTag( "role" ).addText( "webappsec" )
+              .addTag( "name" ).addText( "WebAppSec" )
+              .addTag( "enabled" ).addText( "true" )
+              .addTag( "param" )
+                .addTag( "name" ).addText( "csrf.enabled" )
+                .addTag( "value" ).addText( "true" ).gotoParent().gotoParent()
+            .addTag( "provider" )
               .addTag( "role" ).addText( "authentication" )
               .addTag( "enabled" ).addText( "true" )
               .addTag( "param" )
@@ -204,7 +211,7 @@ public class GatewayBasicFuncTest {
             .addTag( "role" ).addText( "WEBHBASE" )
             .addTag( "url" ).addText( driver.getRealUrl( "WEBHBASE" ) )
         .gotoRoot();
-    // System.out.println( "GATEWAY=" + xml.toString() );
+//     System.out.println( "GATEWAY=" + xml.toString() );
     return xml;
   }
 
@@ -236,6 +243,7 @@ public class GatewayBasicFuncTest {
     given()
         //.log().all()
         .auth().preemptive().basic( username, password )
+        .header("X-XSRF-Header", "jksdhfkhdsf")
         .queryParam( "op", "MKDIRS" )
         .expect()
             //.log().all();
@@ -266,6 +274,7 @@ public class GatewayBasicFuncTest {
     Response response = given()
         //.log().all()
         .auth().preemptive().basic( username, password )
+        .header("X-XSRF-Header", "jksdhfkhdsf")
         .queryParam( "op", "CREATE" )
         .expect()
             //.log().ifError()
@@ -303,6 +312,7 @@ public class GatewayBasicFuncTest {
         .status( HttpStatus.SC_OK );
     given()
         .auth().preemptive().basic( username, password )
+        .header("X-XSRF-Header", "jksdhfkhdsf")
         .queryParam( "op", "DELETE" )
         .queryParam( "recursive", "true" )
         .expect()
@@ -324,6 +334,7 @@ public class GatewayBasicFuncTest {
     given()
         //.log().all()
         .auth().preemptive().basic( username, password )
+        .header("X-XSRF-Header", "jksdhfkhdsf")
         .queryParam( "op", "MKDIRS" )
         .expect()
             //.log().all();
@@ -356,6 +367,7 @@ public class GatewayBasicFuncTest {
         .status( HttpStatus.SC_OK );
     given()
         .auth().preemptive().basic( username, password )
+        .header("X-XSRF-Header", "jksdhfkhdsf")
         .queryParam( "op", "DELETE" )
         .queryParam( "recursive", "true" )
         .expect()
@@ -387,6 +399,7 @@ public class GatewayBasicFuncTest {
     given()
         //.log().all()
         .auth().preemptive().basic( username, password )
+        .header("X-XSRF-Header", "jksdhfkhdsf")
         .queryParam( "op", "MKDIRS" )
         .expect()
         //.log().all();
@@ -409,6 +422,7 @@ public class GatewayBasicFuncTest {
     given()
         //.log().all()
         .auth().preemptive().basic( username, password )
+        .header("X-XSRF-Header", "jksdhfkhdsf")
         .queryParam( "op", "LISTSTATUS" )
         .expect()
         //.log().ifError()
@@ -421,6 +435,7 @@ public class GatewayBasicFuncTest {
     given()
         //.log().all()
         .auth().preemptive().basic( username, "invalid-password" )
+        .header("X-XSRF-Header", "jksdhfkhdsf")
         .queryParam( "op", "LISTSTATUS" )
         .expect()
         //.log().ifError()
@@ -432,6 +447,7 @@ public class GatewayBasicFuncTest {
     given()
         //.log().all()
         .auth().preemptive().basic( "hdfs-user", "hdfs-password" )
+        .header("X-XSRF-Header", "jksdhfkhdsf")
         .queryParam( "op", "LISTSTATUS" )
         .expect()
         //.log().ifError()
@@ -443,6 +459,7 @@ public class GatewayBasicFuncTest {
     given()
       //.log().all()
       .auth().preemptive().basic( "mapred-user", "mapred-password" )
+      .header("X-XSRF-Header", "jksdhfkhdsf")
       .queryParam( "op", "LISTSTATUS" )
       .expect()
       //.log().ifError()
@@ -491,6 +508,7 @@ public class GatewayBasicFuncTest {
     Response response = given()
         //.log().all()
         .auth().preemptive().basic( username, password )
+        .header("X-XSRF-Header", "jksdhfkhdsf")
         .queryParam( "op", "CREATE" )
         .expect()
         //.log().ifError()
@@ -508,6 +526,7 @@ public class GatewayBasicFuncTest {
     response = given()
         //.log().all()
         .auth().preemptive().basic( username, password )
+        .header("X-XSRF-Header", "jksdhfkhdsf")
         .content( driver.getResourceBytes( "test.txt" ) )
         .contentType( "text/plain" )
         .expect()
@@ -559,6 +578,7 @@ public class GatewayBasicFuncTest {
     given()
         //.log().all()
         .auth().preemptive().basic( username, password )
+        .header("X-XSRF-Header", "jksdhfkhdsf")
         .queryParam( "op", "OPEN" )
         .expect()
         //.log().ifError()
@@ -590,6 +610,7 @@ public class GatewayBasicFuncTest {
         .status( HttpStatus.SC_OK );
     given()
         .auth().preemptive().basic( username, password )
+        .header("X-XSRF-Header", "jksdhfkhdsf")
         .queryParam( "op", "DELETE" )
         .queryParam( "recursive", "true" )
         .expect()
@@ -685,6 +706,7 @@ public class GatewayBasicFuncTest {
       Response response = given()
           //.log().all()
           .auth().preemptive().basic( userA, "invalid-password" )
+          .header("X-XSRF-Header", "jksdhfkhdsf")
           .queryParam( "op", "OPEN" )
           .expect()
           //.log().all()
@@ -929,6 +951,7 @@ public class GatewayBasicFuncTest {
         .contentType( "application/x-thrift" );
     Response response = given()
         .auth().preemptive().basic( username, password )
+        .header("X-XSRF-Header", "jksdhfkhdsf")
         .content( driver.getResourceBytes( "hive/open-session-request.bin" ) )
         .contentType( "application/x-thrift" )
         .expect()
@@ -953,6 +976,7 @@ public class GatewayBasicFuncTest {
         .contentType( "application/x-thrift" );
     response = given()
         .auth().preemptive().basic( username, password )
+        .header("X-XSRF-Header", "jksdhfkhdsf")
         .content( driver.getResourceBytes( "hive/execute-set-fetch-output-serde-request.bin" ) )
         .contentType( "application/x-thrift" )
         .expect()
@@ -976,6 +1000,7 @@ public class GatewayBasicFuncTest {
         .contentType( "application/x-thrift" );
     response = given()
         .auth().preemptive().basic( username, password )
+        .header("X-XSRF-Header", "jksdhfkhdsf")
         .content( driver.getResourceBytes( "hive/close-operation-1-request.bin" ) )
         .contentType( "application/x-thrift" )
         .expect()
@@ -999,6 +1024,7 @@ public class GatewayBasicFuncTest {
         .contentType( "application/x-thrift" );
     response = given()
         .auth().preemptive().basic( username, password )
+        .header("X-XSRF-Header", "jksdhfkhdsf")
         .content( driver.getResourceBytes( "hive/execute-set-server2-http-path-request.bin" ) )
         .contentType( "application/x-thrift" )
         .expect()
@@ -1022,6 +1048,7 @@ public class GatewayBasicFuncTest {
         .contentType( "application/x-thrift" );
     response = given()
         .auth().preemptive().basic( username, password )
+        .header("X-XSRF-Header", "jksdhfkhdsf")
         .content( driver.getResourceBytes( "hive/close-operation-2-request.bin" ) )
         .contentType( "application/x-thrift" )
         .expect()
@@ -1045,6 +1072,7 @@ public class GatewayBasicFuncTest {
         .contentType( "application/x-thrift" );
     response = given()
         .auth().preemptive().basic( username, password )
+        .header("X-XSRF-Header", "jksdhfkhdsf")
         .content( driver.getResourceBytes( "hive/execute-set-server2-servermode-request.bin" ) )
         .contentType( "application/x-thrift" )
         .expect()
@@ -1068,6 +1096,7 @@ public class GatewayBasicFuncTest {
         .contentType( "application/x-thrift" );
     response = given()
         .auth().preemptive().basic( username, password )
+        .header("X-XSRF-Header", "jksdhfkhdsf")
         .content( driver.getResourceBytes( "hive/close-operation-3-request.bin" ) )
         .contentType( "application/x-thrift" )
         .expect()
@@ -1091,6 +1120,7 @@ public class GatewayBasicFuncTest {
         .contentType( "application/x-thrift" );
     response = given()
         .auth().preemptive().basic( username, password )
+        .header("X-XSRF-Header", "jksdhfkhdsf")
         .content( driver.getResourceBytes( "hive/execute-set-security-authorization-enabled-request.bin" ) )
         .contentType( "application/x-thrift" )
         .expect()
@@ -1114,6 +1144,7 @@ public class GatewayBasicFuncTest {
         .contentType( "application/x-thrift" );
     response = given()
         .auth().preemptive().basic( username, password )
+        .header("X-XSRF-Header", "jksdhfkhdsf")
         .content( driver.getResourceBytes( "hive/close-operation-4-request.bin" ) )
         .contentType( "application/x-thrift" )
         .expect()
@@ -1137,6 +1168,7 @@ public class GatewayBasicFuncTest {
         .contentType( "application/x-thrift" );
     response = given()
         .auth().preemptive().basic( username, password )
+        .header("X-XSRF-Header", "jksdhfkhdsf")
         .content( driver.getResourceBytes( "hive/execute-create-table-request.bin" ) )
         .contentType( "application/x-thrift" )
         .expect()
@@ -1160,6 +1192,7 @@ public class GatewayBasicFuncTest {
         .contentType( "application/x-thrift" );
     response = given()
         .auth().preemptive().basic( username, password )
+        .header("X-XSRF-Header", "jksdhfkhdsf")
         .content( driver.getResourceBytes( "hive/close-operation-5-request.bin" ) )
         .contentType( "application/x-thrift" )
         .expect()
@@ -1183,6 +1216,7 @@ public class GatewayBasicFuncTest {
         .contentType( "application/x-thrift" );
     response = given()
         .auth().preemptive().basic( username, password )
+        .header("X-XSRF-Header", "jksdhfkhdsf")
         .content( driver.getResourceBytes( "hive/execute-select-from-table-request.bin" ) )
         .contentType( "application/x-thrift" )
         .expect()
@@ -1206,6 +1240,7 @@ public class GatewayBasicFuncTest {
         .contentType( "application/x-thrift" );
     response = given()
         .auth().preemptive().basic( username, password )
+        .header("X-XSRF-Header", "jksdhfkhdsf")
         .content( driver.getResourceBytes( "hive/get-result-set-metadata-request.bin" ) )
         .contentType( "application/x-thrift" )
         .expect()
@@ -1229,6 +1264,7 @@ public class GatewayBasicFuncTest {
         .contentType( "application/x-thrift" );
     response = given()
         .auth().preemptive().basic( username, password )
+        .header("X-XSRF-Header", "jksdhfkhdsf")
         .content( driver.getResourceBytes( "hive/fetch-results-request.bin" ) )
         .contentType( "application/x-thrift" )
         .expect()
@@ -1252,6 +1288,7 @@ public class GatewayBasicFuncTest {
         .contentType( "application/x-thrift" );
     response = given()
         .auth().preemptive().basic( username, password )
+        .header("X-XSRF-Header", "jksdhfkhdsf")
         .content( driver.getResourceBytes( "hive/close-operation-6-request.bin" ) )
         .contentType( "application/x-thrift" )
         .expect()
@@ -1275,6 +1312,7 @@ public class GatewayBasicFuncTest {
         .contentType( "application/x-thrift" );
     response = given()
         .auth().preemptive().basic( username, password )
+        .header("X-XSRF-Header", "jksdhfkhdsf")
         .content( driver.getResourceBytes( "hive/close-session-request.bin" ) )
         .contentType( "application/x-thrift" )
         .expect()
@@ -1304,6 +1342,7 @@ public class GatewayBasicFuncTest {
     
     Response response = given()
     .auth().preemptive().basic( username, password )
+    .header("X-XSRF-Header", "jksdhfkhdsf")
     .header( "Accept", ContentType.XML.toString() )
     .expect()
     .statusCode( HttpStatus.SC_OK )
@@ -1328,6 +1367,7 @@ public class GatewayBasicFuncTest {
     
     response = given()
     .auth().preemptive().basic( username, password )
+    .header("X-XSRF-Header", "jksdhfkhdsf")
     .header( "Accept", ContentType.JSON.toString() )
     .expect()
     .statusCode( HttpStatus.SC_OK )
@@ -1350,6 +1390,7 @@ public class GatewayBasicFuncTest {
     
     given()
     .auth().preemptive().basic( username, password )
+    .header("X-XSRF-Header", "jksdhfkhdsf")
     .header( "Accept", "application/x-protobuf" )
     .expect()
     .statusCode( HttpStatus.SC_OK )
@@ -1378,6 +1419,7 @@ public class GatewayBasicFuncTest {
 
     given()
     .auth().preemptive().basic( username, password )
+    .header("X-XSRF-Header", "jksdhfkhdsf")
     .expect()
     .statusCode( HttpStatus.SC_CREATED )
     .contentType( ContentType.XML )
@@ -1397,6 +1439,7 @@ public class GatewayBasicFuncTest {
     
     given()
     .auth().preemptive().basic( username, password )
+    .header("X-XSRF-Header", "jksdhfkhdsf")
     .expect()
     .statusCode( HttpStatus.SC_CREATED )
     .contentType( ContentType.JSON )
@@ -1416,6 +1459,7 @@ public class GatewayBasicFuncTest {
 
     given()
     .auth().preemptive().basic( username, password )
+    .header("X-XSRF-Header", "jksdhfkhdsf")
     .expect()
     .statusCode( HttpStatus.SC_CREATED )
     .contentType( "application/x-protobuf" )
@@ -1444,6 +1488,7 @@ public class GatewayBasicFuncTest {
 
     Response response = given()
     .auth().preemptive().basic( username, password )
+    .header("X-XSRF-Header", "jksdhfkhdsf")
     .header( "Accept", ContentType.XML.toString() )
     .expect()
     .statusCode( HttpStatus.SC_OK )
@@ -1468,6 +1513,7 @@ public class GatewayBasicFuncTest {
 
     response = given()
     .auth().preemptive().basic( username, password )
+    .header("X-XSRF-Header", "jksdhfkhdsf")
     .header( "Accept", ContentType.JSON.toString() )
     .expect()
     .statusCode( HttpStatus.SC_OK )
@@ -1490,6 +1536,7 @@ public class GatewayBasicFuncTest {
 
     response = given()
     .auth().preemptive().basic( username, password )
+    .header("X-XSRF-Header", "jksdhfkhdsf")
     .header( "Accept", "application/x-protobuf" )
     .expect()
     .statusCode( HttpStatus.SC_OK )
@@ -1524,6 +1571,7 @@ public class GatewayBasicFuncTest {
 
     given()
     .auth().preemptive().basic( username, password )
+    .header("X-XSRF-Header", "jksdhfkhdsf")
     //.header( "Content-Type", ContentType.XML.toString() )
     .content( driver.getResourceBytes( resourceName + ".xml" ) )
     .contentType( ContentType.XML.toString() )
@@ -1543,6 +1591,7 @@ public class GatewayBasicFuncTest {
 
     given()
     .auth().preemptive().basic( username, password )
+    .header("X-XSRF-Header", "jksdhfkhdsf")
     //.header( "Content-Type", ContentType.JSON.toString() )
     .content( driver.getResourceBytes( resourceName + ".json" ) )
     .contentType( ContentType.JSON.toString() )
@@ -1563,6 +1612,7 @@ public class GatewayBasicFuncTest {
 
     given()
     .auth().preemptive().basic( username, password )
+    .header("X-XSRF-Header", "jksdhfkhdsf")
     //.header( "Content-Type", "application/x-protobuf" )
     .content( driver.getResourceBytes( resourceName + ".protobuf" ) )
     .contentType( "application/x-protobuf" )
@@ -1585,6 +1635,7 @@ public class GatewayBasicFuncTest {
 
     given()
       .auth().preemptive().basic( username, password )
+      .header("X-XSRF-Header", "jksdhfkhdsf")
       //.header( "Content-Type", ContentType.XML.toString() )
       .content( driver.getResourceBytes( resourceName + ".xml" ) )
       .contentType( ContentType.XML.toString() )
@@ -1604,6 +1655,7 @@ public class GatewayBasicFuncTest {
 
     given()
     .auth().preemptive().basic( username, password )
+    .header("X-XSRF-Header", "jksdhfkhdsf")
     //.header( "Content-Type", ContentType.JSON.toString() )
     .content( driver.getResourceBytes( resourceName + ".json" ) )
     .contentType( ContentType.JSON.toString() )
@@ -1624,6 +1676,7 @@ public class GatewayBasicFuncTest {
 
     given()
     .auth().preemptive().basic( username, password )
+    .header("X-XSRF-Header", "jksdhfkhdsf")
     //.header( "Content-Type", "application/x-protobuf" )
     .content( driver.getResourceBytes( resourceName + ".protobuf" ) )
     .contentType( "application/x-protobuf" )
@@ -1652,6 +1705,7 @@ public class GatewayBasicFuncTest {
 
     given()
     .auth().preemptive().basic( username, password )
+    .header("X-XSRF-Header", "jksdhfkhdsf")
     .expect()
     .statusCode( HttpStatus.SC_OK )
     .when().delete( driver.getUrl( "WEBHBASE" ) + "/" + tableId + "/" + rowId );
@@ -1666,6 +1720,7 @@ public class GatewayBasicFuncTest {
 
     given()
     .auth().preemptive().basic( username, password )
+    .header("X-XSRF-Header", "jksdhfkhdsf")
     .expect()
     .statusCode( HttpStatus.SC_OK )
     .when().delete( driver.getUrl( "WEBHBASE" ) + "/" + tableId + "/" + rowId + "/" + familyId );
@@ -1680,6 +1735,7 @@ public class GatewayBasicFuncTest {
 
     given()
     .auth().preemptive().basic( username, password )
+    .header("X-XSRF-Header", "jksdhfkhdsf")
     .expect()
     .statusCode( HttpStatus.SC_OK )
     .when().delete( driver.getUrl( "WEBHBASE" ) + "/" + tableId + "/" + rowId + "/" + familyId + ":" + columnId );
@@ -1711,6 +1767,7 @@ public class GatewayBasicFuncTest {
 
     Response response = given()
     .auth().preemptive().basic( username, password )
+    .header("X-XSRF-Header", "jksdhfkhdsf")
     .header( "Accept", ContentType.XML.toString() )
     .expect()
     .statusCode( HttpStatus.SC_OK )
@@ -1735,6 +1792,7 @@ public class GatewayBasicFuncTest {
 
     response = given()
     .auth().preemptive().basic( username, password )
+    .header("X-XSRF-Header", "jksdhfkhdsf")
     .header( "Accept", ContentType.XML.toString() )
     .expect()
     .statusCode( HttpStatus.SC_OK )
@@ -1759,6 +1817,7 @@ public class GatewayBasicFuncTest {
 
     response = given()
     .auth().preemptive().basic( username, password )
+    .header("X-XSRF-Header", "jksdhfkhdsf")
     .header( "Accept", ContentType.JSON.toString() )
     .expect()
     .statusCode( HttpStatus.SC_OK )
@@ -1781,6 +1840,7 @@ public class GatewayBasicFuncTest {
 
     response = given()
     .auth().preemptive().basic( username, password )
+    .header("X-XSRF-Header", "jksdhfkhdsf")
     .header( "Accept", ContentType.JSON.toString() )
     .expect()
     .statusCode( HttpStatus.SC_OK )
@@ -1813,6 +1873,7 @@ public class GatewayBasicFuncTest {
 
     given()
     .auth().preemptive().basic( username, password )
+    .header("X-XSRF-Header", "jksdhfkhdsf")
     .header( "Content-Type", ContentType.XML.toString() )
     .content( driver.getResourceBytes( scannerDefinitionResourceName + ".xml" ) )
     .expect()
@@ -1835,6 +1896,7 @@ public class GatewayBasicFuncTest {
 
     Response response = given()
     .auth().preemptive().basic( username, password )
+    .header("X-XSRF-Header", "jksdhfkhdsf")
     .header( "Accept", ContentType.XML.toString() )
     .expect()
     .statusCode( HttpStatus.SC_OK )
@@ -1857,10 +1919,38 @@ public class GatewayBasicFuncTest {
 
     given()
     .auth().preemptive().basic( username, password )
+    .header("X-XSRF-Header", "jksdhfkhdsf")
     .expect()
     .statusCode( HttpStatus.SC_OK )
     .when().delete( driver.getUrl( "WEBHBASE" ) + scannerPath + "/" + scannerId );
     driver.assertComplete();
   }
 
+  @Ignore
+  public void testCrossSiteRequestForgeryPrevention() throws IOException {
+    String root = "/tmp/GatewayWebHdfsFuncTest/testCrossSiteRequestForgeryPrevention";
+    String username = "hdfs";
+    String password = "hdfs-password";
+
+//    driver.getMock( "WEBHDFS" )
+//        .expect()
+//        .method( "PUT" )
+//        .pathInfo( "/v1" + root + "/dir" )
+//        .queryParam( "op", "MKDIRS" )
+//        .queryParam( "user.name", username )
+//        .respond()
+//        .status( HttpStatus.SC_BAD_REQUEST );
+    given()
+        .log().all()
+        .auth().preemptive().basic( username, password )
+//        .header("X-XSRF-Header", "jksdhfkhdsf")
+        .queryParam( "op", "MKDIRS" )
+        .expect()
+            .log().all()
+        .statusCode( HttpStatus.SC_BAD_REQUEST )
+        .when().put( driver.getUrl( "WEBHDFS" ) + "/v1" + root + "/dir" );
+//    driver.reset();
+//    driver.assertComplete();
+  }
+
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-knox/blob/9901058d/gateway-test/src/test/java/org/apache/hadoop/gateway/GatewayFuncTestDriver.java
----------------------------------------------------------------------
diff --git a/gateway-test/src/test/java/org/apache/hadoop/gateway/GatewayFuncTestDriver.java b/gateway-test/src/test/java/org/apache/hadoop/gateway/GatewayFuncTestDriver.java
index 0fb91e1..5e6006f 100644
--- a/gateway-test/src/test/java/org/apache/hadoop/gateway/GatewayFuncTestDriver.java
+++ b/gateway-test/src/test/java/org/apache/hadoop/gateway/GatewayFuncTestDriver.java
@@ -300,6 +300,7 @@ public class GatewayFuncTestDriver {
         //.log().headers()
         //.log().parameters()
         .auth().preemptive().basic( user, password )
+        .header("X-XSRF-Header", "jksdhfkhdsf")
         .queryParam( "op", "CREATE" )
         .queryParam( "permission", permsOctal )
         .expect()
@@ -339,6 +340,7 @@ public class GatewayFuncTestDriver {
     Response response = given()
         //.log().all()
         .auth().preemptive().basic( user, password )
+        .header("X-XSRF-Header", "jksdhfkhdsf")
         .contentType( contentType )
         .content( getResourceBytes( resource ) )
         .expect()
@@ -399,6 +401,7 @@ public class GatewayFuncTestDriver {
     Response response = given()
         //.log().all()
         .auth().preemptive().basic( user, password )
+        .header("X-XSRF-Header", "jksdhfkhdsf")
         .queryParam( "op", "OPEN" )
         .expect()
         //.log().all()
@@ -426,6 +429,7 @@ public class GatewayFuncTestDriver {
     given()
         //.log().all()
         .auth().preemptive().basic( user, password )
+        .header("X-XSRF-Header", "jksdhfkhdsf")
         .queryParam( "op", "SETOWNER" )
         .queryParam( "owner", owner )
         .queryParam( "group", group )
@@ -449,6 +453,7 @@ public class GatewayFuncTestDriver {
     given()
         //.log().all()
         .auth().preemptive().basic( user, password )
+        .header("X-XSRF-Header", "jksdhfkhdsf")
         .queryParam( "op", "SETPERMISSION" )
         .queryParam( "permission", permsOctal )
         .expect()
@@ -493,6 +498,7 @@ public class GatewayFuncTestDriver {
     Response response = given()
         //.log().all()
         .auth().preemptive().basic( user, password )
+        .header("X-XSRF-Header", "jksdhfkhdsf")
         .queryParam( "op", "CREATE" )
         .queryParam( "overwrite", "true" )
         .content( getResourceBytes( resource ) )
@@ -533,6 +539,7 @@ public class GatewayFuncTestDriver {
     Response response = given()
         //.log().all()
         .auth().preemptive().basic( user, password )
+        .header("X-XSRF-Header", "jksdhfkhdsf")
         .queryParam( "op", "CREATE" )
         .queryParam( "overwrite", "true" )
         .contentType( contentType )
@@ -555,6 +562,7 @@ public class GatewayFuncTestDriver {
     given()
         //.log().all()
         .auth().preemptive().basic( user, password )
+        .header("X-XSRF-Header", "jksdhfkhdsf")
         .queryParam( "op", "DELETE" )
         .queryParam( "recursive", recursive )
         .expect()
@@ -580,6 +588,7 @@ public class GatewayFuncTestDriver {
     Response response = given()
         //.log().all()
         .auth().preemptive().basic( user, password )
+        .header("X-XSRF-Header", "jksdhfkhdsf")
         .queryParam( "op", "MKDIRS" )
         .queryParam( "permission", permsOctal )
         .expect()
@@ -630,6 +639,7 @@ public class GatewayFuncTestDriver {
     String json = given()
         //.log().all()
         .auth().preemptive().basic( user, password )
+        .header("X-XSRF-Header", "jksdhfkhdsf")
         .formParam( "user.name", user )
         .formParam( "jar", jar )    //"/user/hdfs/test/hadoop-examples.jar" )
         .formParam( "class", main ) //"org.apache.org.apache.hadoop.examples.WordCount" )
@@ -657,6 +667,7 @@ public class GatewayFuncTestDriver {
     String json = given()
         //.log().all()
         .auth().preemptive().basic( user, password )
+        .header("X-XSRF-Header", "jksdhfkhdsf")
 //BUG: The identity asserter needs to check for this too.
         .formParam( "user.name", user )
         .formParam( "group", group )
@@ -690,6 +701,7 @@ public class GatewayFuncTestDriver {
     String json = given()
         //.log().all()
         .auth().preemptive().basic( user, password )
+        .header("X-XSRF-Header", "jksdhfkhdsf")
         .formParam( "user.name", user )
         .formParam( "group", group )
         .formParam( "group", group )
@@ -722,6 +734,7 @@ public class GatewayFuncTestDriver {
     String status = given()
         //.log().all()
         .auth().preemptive().basic( user, password )
+        .header("X-XSRF-Header", "jksdhfkhdsf")
         .pathParam( "job", job )
         .expect()
         //.log().all()
@@ -743,6 +756,7 @@ public class GatewayFuncTestDriver {
   public void oozieGetVersions( String user, String password ) throws IOException {
     given()
         .auth().preemptive().basic( user, password )
+        .header("X-XSRF-Header", "jksdhfkhdsf")
         .expect()
         .statusCode( 200 )
         .body( "", hasItems( 0, 1 ) )
@@ -844,6 +858,7 @@ TODO
 //    post.getParams().setParameter( "action", "start" );
     StringEntity entity = new StringEntity( request, ContentType.create( "application/xml", "UTF-8" ) );
     post.setEntity( entity );
+    post.setHeader("X-XSRF-Header", "ksdjfhdsjkfhds");
     HttpResponse response = client.execute( targetHost, post, localContext );
     assertThat( response.getStatusLine().getStatusCode(), is( status ) );
     String json = EntityUtils.toString( response.getEntity() );
@@ -930,6 +945,7 @@ TODO
     localContext.setAttribute( ClientContext.AUTH_CACHE, authCache );
 
     HttpGet request = new HttpGet( url.toURI() );
+    request.setHeader("X-XSRF-Header", "ksdhfjkhdsjkf");
     HttpResponse response = client.execute( targetHost, request, localContext );
     assertThat( response.getStatusLine().getStatusCode(), is( status ) );
     String json = EntityUtils.toString( response.getEntity() );

http://git-wip-us.apache.org/repos/asf/incubator-knox/blob/9901058d/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index c945dcb..255451a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -44,6 +44,7 @@
         <module>gateway-provider-rewrite-func-service-registry</module>
         <module>gateway-provider-rewrite-step-secure-query</module>
         <module>gateway-provider-security-jwt</module>
+        <module>gateway-provider-security-webappsec</module>
         <module>gateway-provider-security-shiro</module>
         <module>gateway-provider-security-authz-acls</module>
         <module>gateway-provider-identity-assertion-pseudo</module>
@@ -349,6 +350,11 @@
             </dependency>
             <dependency>
                 <groupId>${gateway-group}</groupId>
+                <artifactId>gateway-provider-security-webappsec</artifactId>
+                <version>${gateway-version}</version>
+            </dependency>
+            <dependency>
+                <groupId>${gateway-group}</groupId>
                 <artifactId>gateway-provider-security-shiro</artifactId>
                 <version>${gateway-version}</version>
             </dependency>