Skip to content
This repository has been archived by the owner on Apr 4, 2021. It is now read-only.

Commit

Permalink
Merge branch 'master' of https://github.com/apache/falcon
Browse files Browse the repository at this point in the history
  • Loading branch information
sandeepSamudrala committed Aug 14, 2016
2 parents 1bb8d3c + 2bea7f4 commit d6dc8bf
Show file tree
Hide file tree
Showing 16 changed files with 569 additions and 11 deletions.
10 changes: 10 additions & 0 deletions common/src/main/java/org/apache/falcon/security/SecurityUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,16 @@ public static boolean isAuthorizationEnabled() {
"falcon.security.authorization.enabled", "false"));
}

/**
* Checks if CSRF filter is enabled in the configuration.
*
* @return true if falcon.security.csrf.enabled is enabled, false otherwise
*/
public static boolean isCSRFFilterEnabled() {
return Boolean.valueOf(StartupProperties.get().getProperty(
"falcon.security.csrf.enabled", "false"));
}

public static AuthorizationProvider getAuthorizationProvider() throws FalconException {
String providerClassName = StartupProperties.get().getProperty(
"falcon.security.authorization.provider",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@ public static DistCpOptions getDistCpOptions(CommandLine cmd,
distcpOptions.setMapBandwidth(Integer.parseInt(cmd.getOptionValue("mapBandwidth")));

String tdeEncryptionEnabled = cmd.getOptionValue(TDE_ENCRYPTION_ENABLED);
if (StringUtils.isNotBlank(tdeEncryptionEnabled) && tdeEncryptionEnabled.equalsIgnoreCase(Boolean.TRUE.toString())) {
if (StringUtils.isNotBlank(tdeEncryptionEnabled)
&& tdeEncryptionEnabled.equalsIgnoreCase(Boolean.TRUE.toString())) {
distcpOptions.setSyncFolder(true);
distcpOptions.setSkipCRC(true);
} else {
Expand Down
9 changes: 9 additions & 0 deletions common/src/main/resources/startup.properties
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,15 @@ it.workflow.execution.listeners=org.apache.falcon.catalog.CatalogPartitionHandle
# Authorization Enabled flag: false (default)|true
*.falcon.security.authorization.enabled=false

# CSRF filter enabled flag: false (default) | true
*.falcon.security.csrf.enabled=false

# Custom header for CSRF filter
*.falcon.security.csrf.header=FALCON-CSRF-FILTER

# Browser user agents to be filtered
*.falcon.security.csrf.browser=^Mozilla.*,^Opera.*

# The name of the group of super-users
*.falcon.security.authorization.superusergroup=falcon

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,22 @@ public void testGetAuthorizationProviderByDefault() throws Exception {
DefaultAuthorizationProvider.class);
}

@Test
public void testIsCSRFFilterEnabledByDefault() throws Exception {
Assert.assertFalse(SecurityUtil.isCSRFFilterEnabled());
}

@Test
public void testIsCSRFFilterEnabled() throws Exception {
try {
StartupProperties.get().setProperty("falcon.security.csrf.enabled", "true");
Assert.assertTrue(SecurityUtil.isCSRFFilterEnabled());
} finally {
// reset
StartupProperties.get().setProperty("falcon.security.csrf.enabled", "false");
}
}

@Test
public void testTryProxy() throws IOException, FalconException {
Process process = Mockito.mock(Process.class);
Expand Down
26 changes: 21 additions & 5 deletions docs/src/site/twiki/Security.twiki
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@
---++ Overview

Apache Falcon provides the following security features:
* Support credential provider alias for passwords used in Falcon server.
* Support authentication to identify proper users.
* Support authorization to specify resource access permission for users or groups.
* Support SSL to provide transport level security for data confidentiality and integrity.

* Credential provider alias for passwords used in Falcon server.
* Authentication to identify proper users.
* Authorization to specify resource access permission for users or groups.
* Cross-Site Request Forgery (CSRF) prevention.
* SSL to provide transport level security for data confidentiality and integrity.

---++ Credential Provider Alias for Passwords
Server-side configuration properties (i.e. startup.properties) contain passwords and other sensitive information.
Expand Down Expand Up @@ -310,6 +310,22 @@ Administrative groups are determined by the configuration:
*.falcon.security.authorization.admin.groups=falcon,testgroup,staff
</verbatim>

---++ Cross-Site Request Forgery (CSRF) Prevention

Cross-Site Request Forgery (CSRF) is an attack that forces an end user to execute unwanted actions on a web application in which they're currently authenticated.
Falcon provides an option to prevent CSRF with Hadoop CSRF filter for REST APIs. By default, Falcon CSRF filter is disabled.
To enable the support for CSRF prevention, set falcon.security.csrf.enabled to true in the startup configuration.
We also provide options to configure custom header and browser user agents.

<verbatim>
# CSRF filter enabled flag: false (default) | true
*.falcon.security.csrf.enabled=true
# Custom header for CSRF filter
*.falcon.security.csrf.header=FALCON-CSRF-FILTER
# Browser user agents to be filtered
*.falcon.security.csrf.browser=^Mozilla.*,^Opera.*
</verbatim>


---++ SSL

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
import org.apache.falcon.entity.v0.cluster.Cluster;
import org.apache.falcon.extensions.AbstractExtension;

import java.net.URI;
import java.net.URISyntaxException;
import java.util.Properties;

/**
Expand Down Expand Up @@ -82,17 +84,43 @@ public Properties getAdditionalProperties(final Properties extensionProperties)
if (StringUtils.isNotBlank(srcPaths)) {
String[] paths = srcPaths.split(COMMA_SEPARATOR);

URI pathUri;
for (String path : paths) {
StringBuilder srcpath = new StringBuilder(srcClusterEndPoint);
try {
pathUri = new URI(path.trim());
} catch (URISyntaxException e) {
throw new FalconException(e);
}
String authority = pathUri.getAuthority();
StringBuilder srcpath = new StringBuilder();
if (authority == null) {
srcpath.append(srcClusterEndPoint);
}

srcpath.append(path.trim());
srcpath.append(COMMA_SEPARATOR);
absoluteSrcPaths.append(srcpath);
}
}

additionalProperties.put(HdfsMirroringExtensionProperties.SOURCE_DIR.getName(),
StringUtils.removeEnd(absoluteSrcPaths.toString(), COMMA_SEPARATOR));

// Target dir shouldn't have the namenode
String targetDir = extensionProperties.getProperty(HdfsMirroringExtensionProperties
.TARGET_DIR.getName());

URI targetPathUri;
try {
targetPathUri = new URI(targetDir.trim());
} catch (URISyntaxException e) {
throw new FalconException(e);
}

if (targetPathUri.getScheme() != null) {
additionalProperties.put(HdfsMirroringExtensionProperties.TARGET_DIR.getName(),
targetPathUri.getPath());
}

// add sourceClusterFS and targetClusterFS
additionalProperties.put(HdfsMirroringExtensionProperties.SOURCE_CLUSTER_FS_WRITE_ENDPOINT.getName(),
ClusterHelper.getStorageUrl(srcCluster));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ public String getExtensionLibPath(final String extensionName) throws StoreAccess

for (FileStatus fileStatus : files) {
if (fileStatus.getPath().getName().equalsIgnoreCase(LIBS_DIR)) {
libsPath = Path.getPathWithoutSchemeAndAuthority(fileStatus.getPath());
libsPath = Path.getPathWithoutSchemeAndAuthority(fileStatus.getPath());
break;
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/**
* 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.falcon.security;

import org.apache.falcon.util.StartupProperties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import java.io.IOException;
import java.util.Properties;

/**
* CSRF filter before processing the request.
*/
public class FalconCSRFFilter extends RestCsrfPreventionFilter {
private static final Logger LOG = LoggerFactory.getLogger(FalconCSRFFilter.class);

public static final String CSRF_PROP_KEY_PREFIX = "falcon.security.csrf.";
public static final String CSRF_PROP_KEY_CUSTOMER_HEADER = "header";
public static final String CSRF_PROP_KEY_BROWSER_USER_AGENT = "browser";

private boolean isCSRFFilterEnabled;

@Override
public void init(FilterConfig filterConfig) throws ServletException {
isCSRFFilterEnabled = SecurityUtil.isCSRFFilterEnabled();
if (isCSRFFilterEnabled) {
super.init(filterConfig);

// add additional property: custom header
Properties configProperties = StartupProperties.get();
String customHeader = configProperties.getProperty(CSRF_PROP_KEY_PREFIX + CSRF_PROP_KEY_CUSTOMER_HEADER);
if (customHeader != null) {
super.headerName = customHeader;
}

// add additional property: browser user agent
String browerAgents = configProperties.getProperty(CSRF_PROP_KEY_PREFIX + CSRF_PROP_KEY_BROWSER_USER_AGENT);
if (browerAgents != null) {
super.parseBrowserUserAgents(browerAgents);
}

LOG.info("Adding cross-site request forgery (CSRF) protection, headerName = {},"
+ "methodsToIgnore = {}, " + "browserUserAgents = {}",
new Object[]{super.headerName, super.methodsToIgnore, super.browserUserAgents});
} else {
LOG.info("CSRF filter is not enabled.");
}
}

@Override
public void doFilter(ServletRequest request, ServletResponse response,
final FilterChain filterChain) throws IOException, ServletException {
if (isCSRFFilterEnabled) {
super.doFilter(request, response, filterChain);
} else {
filterChain.doFilter(request, response);
}
}
}
Loading

0 comments on commit d6dc8bf

Please sign in to comment.