-
Notifications
You must be signed in to change notification settings - Fork 12
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
implementation of the csrf signed double submit pattern #3409
Merged
Merged
Changes from 2 commits
Commits
Show all changes
15 commits
Select commit
Hold shift + click to select a range
9648ebd
naive implementation of the csrf double submit pattern
thoniTUB 849028c
Merge branch 'develop' into feature/crsf-filter
thoniTUB cdcb67b
fixes admin ui templates
thoniTUB 43750c9
updates gh actions
thoniTUB ff3c67f
change fetch to rest call everywhere
thoniTUB ee7ae75
more github action updates
thoniTUB 7d506c6
adds signing of csrf cookie
thoniTUB 867554e
adds readme, timers, and csrf check property for the request
thoniTUB 56cad0b
Merge branch 'develop' into feature/crsf-filter
thoniTUB 5b4c18b
Update backend/src/main/java/com/bakdata/conquery/models/auth/web/csr…
thoniTUB da7d3ca
review changes
thoniTUB 717b922
rename DefaultAuthFilter -> Authfilter
thoniTUB c0c91ab
Merge branch 'develop' into feature/crsf-filter
thoniTUB 0a48af0
update readme
thoniTUB 3c9cc9e
Merge branch 'develop' into feature/crsf-filter
thoniTUB File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
48 changes: 48 additions & 0 deletions
48
backend/src/main/java/com/bakdata/conquery/models/auth/web/csrf/CsrfTokenCheckFilter.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
package com.bakdata.conquery.models.auth.web.csrf; | ||
|
||
import java.io.IOException; | ||
import java.util.Optional; | ||
|
||
import com.bakdata.conquery.models.auth.web.AuthCookieFilter; | ||
import jakarta.annotation.Priority; | ||
import jakarta.ws.rs.ForbiddenException; | ||
import jakarta.ws.rs.container.ContainerRequestContext; | ||
import jakarta.ws.rs.container.ContainerRequestFilter; | ||
import jakarta.ws.rs.core.Cookie; | ||
import lombok.extern.slf4j.Slf4j; | ||
import org.apache.commons.lang3.StringUtils; | ||
|
||
/** | ||
* Implementation of the Double-Submit-Cookie Pattern. | ||
* Checks if tokens in cookie and header match if a cookie is present. | ||
* Otherwise the request is refused. | ||
*/ | ||
@Priority(AuthCookieFilter.PRIORITY - 100) | ||
@Slf4j | ||
public class CsrfTokenCheckFilter implements ContainerRequestFilter { | ||
public static final String CSRF_TOKEN_HEADER = "X-Csrf-Token"; | ||
|
||
@Override | ||
public void filter(ContainerRequestContext requestContext) throws IOException { | ||
final String cookieToken = Optional.ofNullable(requestContext.getCookies().get(CsrfTokenSetFilter.CSRF_COOKIE_NAME)).map(Cookie::getValue).orElse(null); | ||
final String headerToken = requestContext.getHeaders().getFirst(CSRF_TOKEN_HEADER); | ||
|
||
if (cookieToken == null) { | ||
log.trace("Request had no csrf token set. Accepting request"); | ||
return; | ||
} | ||
|
||
if (StringUtils.isBlank(headerToken)) { | ||
log.warn("Request contained csrf cookie but the header token was empty"); | ||
throw new ForbiddenException("CSRF Attempt"); | ||
} | ||
|
||
if (!cookieToken.equals(headerToken)) { | ||
log.warn("Request csrf cookie and header did not match"); | ||
throw new ForbiddenException("CSRF Attempt"); | ||
} | ||
|
||
log.trace("Csrf check successful"); | ||
|
||
} | ||
} |
52 changes: 52 additions & 0 deletions
52
backend/src/main/java/com/bakdata/conquery/models/auth/web/csrf/CsrfTokenSetFilter.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
package com.bakdata.conquery.models.auth.web.csrf; | ||
|
||
import java.io.IOException; | ||
import java.security.SecureRandom; | ||
import java.util.Random; | ||
|
||
import jakarta.ws.rs.container.ContainerRequestContext; | ||
import jakarta.ws.rs.container.ContainerRequestFilter; | ||
import jakarta.ws.rs.container.ContainerResponseContext; | ||
import jakarta.ws.rs.container.ContainerResponseFilter; | ||
import jakarta.ws.rs.core.HttpHeaders; | ||
import jakarta.ws.rs.core.NewCookie; | ||
import org.apache.commons.lang3.RandomStringUtils; | ||
|
||
/** | ||
* Implementation of the Double-Submit-Cookie Pattern. | ||
* This filter generates a random token which is injected in to the response. | ||
* <ul> | ||
* <li>In a Set-Cookie header, so that browser requests send the token via cookie back to us</li> | ||
* <li>In the response payload. This filter sets a request property, which is eventually provided to freemarker. | ||
* Freemarker then writes the token into payload (see base.html.ftl)</li> | ||
* </ul> | ||
*/ | ||
public class CsrfTokenSetFilter implements ContainerRequestFilter, ContainerResponseFilter { | ||
|
||
public static final String CSRF_COOKIE_NAME = "csrf_token"; | ||
public static final String CSRF_TOKEN_PROPERTY = "csrf_token"; | ||
public static final int TOKEN_LENGTH = 30; | ||
|
||
Random random = new SecureRandom(); | ||
|
||
@Override | ||
public void filter(ContainerRequestContext requestContext) throws IOException { | ||
final String token = RandomStringUtils.random(TOKEN_LENGTH, 0, 0, true, true, | ||
null, random | ||
); | ||
requestContext.setProperty(CSRF_TOKEN_PROPERTY, token); | ||
} | ||
|
||
@Override | ||
public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) throws IOException { | ||
final String csrfToken = getCsrfTokenProperty(requestContext); | ||
|
||
responseContext.getHeaders() | ||
.add(HttpHeaders.SET_COOKIE, new NewCookie(CSRF_COOKIE_NAME, csrfToken, "/", null, 0, null, 3600, null, requestContext.getSecurityContext() | ||
.isSecure(), false)); | ||
} | ||
|
||
public static String getCsrfTokenProperty(ContainerRequestContext requestContext) { | ||
return (String) requestContext.getProperty(CSRF_TOKEN_PROPERTY); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
private final?