Small security improvements (#1412)

Typos fixed

Disables empty string gateway token for sure. Test if the gateway token is not empty string ecplicitly.
Empty string is the default value and if accepted could be a security vulnerability (e.g. enabling gateway token
authentication and using empty string as token). According to https://datatracker.ietf.org/doc/html/rfc7230#section-3.2.4
the header value shall not have trailing spaces and the http server shall already have trimmed them. So if execution passes
start with "GatewayToken " then token shall not be empty. But but let's check anyway

In UI first set key then enable the gateway token authentication. Otherwise the key might be left empty (default). This however
shall not be really problem since (because of token trimming) the empty token will be rejected anyway.

Signed-off-by: Marinov Avgustin <Avgustin.Marinov@bosch.com>
This commit is contained in:
Avgustin Marinov
2023-08-16 14:25:17 +03:00
committed by GitHub
parent a5dba29e74
commit acff82f60f
10 changed files with 71 additions and 69 deletions

View File

@@ -43,8 +43,8 @@ public abstract class AbstractControllerAuthenticationFilter implements PreAuthe
protected abstract String getTenantConfigurationKey();
@Override
public boolean isEnable(final DmfTenantSecurityToken secruityToken) {
return tenantAware.runAsTenant(secruityToken.getTenant(), configurationKeyTenantRunner);
public boolean isEnable(final DmfTenantSecurityToken securityToken) {
return tenantAware.runAsTenant(securityToken.getTenant(), configurationKeyTenantRunner);
}
private final class SecurityConfigurationKeyTenantRunner implements TenantAware.TenantRunner<Boolean> {

View File

@@ -61,9 +61,9 @@ public class ControllerPreAuthenticateSecurityTokenFilter extends AbstractContro
}
@Override
public HeaderAuthentication getPreAuthenticatedPrincipal(final DmfTenantSecurityToken secruityToken) {
final String controllerId = resolveControllerId(secruityToken);
final String authHeader = secruityToken.getHeader(DmfTenantSecurityToken.AUTHORIZATION_HEADER);
public HeaderAuthentication getPreAuthenticatedPrincipal(final DmfTenantSecurityToken securityToken) {
final String controllerId = resolveControllerId(securityToken);
final String authHeader = securityToken.getHeader(DmfTenantSecurityToken.AUTHORIZATION_HEADER);
if ((authHeader != null) && authHeader.startsWith(TARGET_SECURITY_TOKEN_AUTH_SCHEME)) {
LOGGER.debug("found authorization header with scheme {} using target security token for authentication",
TARGET_SECURITY_TOKEN_AUTH_SCHEME);
@@ -71,7 +71,7 @@ public class ControllerPreAuthenticateSecurityTokenFilter extends AbstractContro
}
LOGGER.debug(
"security token filter is enabled but requst does not contain either the necessary path variables {} or the authorization header with scheme {}",
secruityToken, TARGET_SECURITY_TOKEN_AUTH_SCHEME);
securityToken, TARGET_SECURITY_TOKEN_AUTH_SCHEME);
return null;
}

View File

@@ -41,13 +41,13 @@ public class ControllerPreAuthenticatedAnonymousDownload extends AbstractControl
}
@Override
public HeaderAuthentication getPreAuthenticatedPrincipal(final DmfTenantSecurityToken secruityToken) {
return new HeaderAuthentication(secruityToken.getControllerId(), secruityToken.getControllerId());
public HeaderAuthentication getPreAuthenticatedPrincipal(final DmfTenantSecurityToken securityToken) {
return new HeaderAuthentication(securityToken.getControllerId(), securityToken.getControllerId());
}
@Override
public HeaderAuthentication getPreAuthenticatedCredentials(final DmfTenantSecurityToken secruityToken) {
return new HeaderAuthentication(secruityToken.getControllerId(), secruityToken.getControllerId());
public HeaderAuthentication getPreAuthenticatedCredentials(final DmfTenantSecurityToken securityToken) {
return new HeaderAuthentication(securityToken.getControllerId(), securityToken.getControllerId());
}
@Override

View File

@@ -28,17 +28,17 @@ public class ControllerPreAuthenticatedAnonymousFilter implements PreAuthenticat
}
@Override
public HeaderAuthentication getPreAuthenticatedPrincipal(final DmfTenantSecurityToken secruityToken) {
return new HeaderAuthentication(secruityToken.getControllerId(), secruityToken.getControllerId());
public HeaderAuthentication getPreAuthenticatedPrincipal(final DmfTenantSecurityToken securityToken) {
return new HeaderAuthentication(securityToken.getControllerId(), securityToken.getControllerId());
}
@Override
public HeaderAuthentication getPreAuthenticatedCredentials(final DmfTenantSecurityToken secruityToken) {
return new HeaderAuthentication(secruityToken.getControllerId(), secruityToken.getControllerId());
public HeaderAuthentication getPreAuthenticatedCredentials(final DmfTenantSecurityToken securityToken) {
return new HeaderAuthentication(securityToken.getControllerId(), securityToken.getControllerId());
}
@Override
public boolean isEnable(final DmfTenantSecurityToken secruityToken) {
public boolean isEnable(final DmfTenantSecurityToken securityToken) {
return ddiSecurityConfiguration.getAuthentication().getAnonymous().isEnabled();
}

View File

@@ -19,7 +19,7 @@ import org.slf4j.LoggerFactory;
* configuration) the possibility to authenticate a target based through a
* gateway security token. This is commonly used for targets connected
* indirectly via a gateway. This gateway controls multiple targets under the
* gateway security token which can be set via the {@code TenantSecruityToken}
* gateway security token which can be set via the {@code TenantsecurityToken}
* header. {@code Example Header: Authorization: GatewayToken
* 5d8fSD54fdsFG98DDsa.}
*
@@ -55,25 +55,27 @@ public class ControllerPreAuthenticatedGatewaySecurityTokenFilter extends Abstra
}
@Override
public HeaderAuthentication getPreAuthenticatedPrincipal(final DmfTenantSecurityToken secruityToken) {
final String authHeader = secruityToken.getHeader(DmfTenantSecurityToken.AUTHORIZATION_HEADER);
if ((authHeader != null) && authHeader.startsWith(GATEWAY_SECURITY_TOKEN_AUTH_SCHEME)) {
public HeaderAuthentication getPreAuthenticatedPrincipal(final DmfTenantSecurityToken securityToken) {
final String authHeader = securityToken.getHeader(DmfTenantSecurityToken.AUTHORIZATION_HEADER);
if (authHeader != null &&
authHeader.startsWith(GATEWAY_SECURITY_TOKEN_AUTH_SCHEME) &&
authHeader.length() > OFFSET_GATEWAY_TOKEN) { // disables empty string token
LOGGER.debug("found authorization header with scheme {} using target security token for authentication",
GATEWAY_SECURITY_TOKEN_AUTH_SCHEME);
return new HeaderAuthentication(secruityToken.getControllerId(),
return new HeaderAuthentication(securityToken.getControllerId(),
authHeader.substring(OFFSET_GATEWAY_TOKEN));
}
LOGGER.debug(
"security token filter is enabled but request does not contain either the necessary secruity token {} or the authorization header with scheme {}",
secruityToken, GATEWAY_SECURITY_TOKEN_AUTH_SCHEME);
"security token filter is enabled but request does not contain either the necessary security token {} or the authorization header with scheme {}",
securityToken, GATEWAY_SECURITY_TOKEN_AUTH_SCHEME);
return null;
}
@Override
public HeaderAuthentication getPreAuthenticatedCredentials(final DmfTenantSecurityToken secruityToken) {
final String gatewayToken = tenantAware.runAsTenant(secruityToken.getTenant(),
public HeaderAuthentication getPreAuthenticatedCredentials(final DmfTenantSecurityToken securityToken) {
final String gatewayToken = tenantAware.runAsTenant(securityToken.getTenant(),
gatewaySecurityTokenKeyConfigRunner);
return new HeaderAuthentication(secruityToken.getControllerId(), gatewayToken);
return new HeaderAuthentication(securityToken.getControllerId(), gatewayToken);
}
@Override

View File

@@ -22,26 +22,26 @@ public interface PreAuthenticationFilter {
/**
* Check if the filter is enabled.
*
* @param secruityToken the secruity info
* @param securityToken the secruity info
* @return <code>true</code> is enabled <code>false</code> diabled
*/
boolean isEnable(DmfTenantSecurityToken secruityToken);
boolean isEnable(DmfTenantSecurityToken securityToken);
/**
* Extract the principal information from the current secruityToken.
* Extract the principal information from the current securityToken.
*
* @param secruityToken the secruityToken
* @param securityToken the securityToken
* @return the extracted tenant and controller id
*/
HeaderAuthentication getPreAuthenticatedPrincipal(DmfTenantSecurityToken secruityToken);
HeaderAuthentication getPreAuthenticatedPrincipal(DmfTenantSecurityToken securityToken);
/**
* Extract the principal credentials from the current secruityToken.
* Extract the principal credentials from the current securityToken.
*
* @param secruityToken the secruityToken
* @param securityToken the securityToken
* @return the extracted tenant and controller id
*/
Object getPreAuthenticatedCredentials(DmfTenantSecurityToken secruityToken);
Object getPreAuthenticatedCredentials(DmfTenantSecurityToken securityToken);
/**
* Allows to add additional authorities to the successful authenticated token.