Skip to content

Commit

Permalink
W
Browse files Browse the repository at this point in the history
  • Loading branch information
carlosjepard committed Jul 30, 2024
1 parent 78d156d commit 99d4ab4
Show file tree
Hide file tree
Showing 6 changed files with 94 additions and 5 deletions.
5 changes: 3 additions & 2 deletions docker/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,9 @@ COPY ./docker-files/docker-entrypoint.sh /
COPY ./docker-files/docker-entrypoint.d/* /docker-entrypoint.d/

RUN set -ex; \
groupadd -r --gid "$RODA_GID" "$RODA_GROUP"; \
useradd -r --uid "$RODA_UID" --gid "$RODA_GID" "$RODA_USER"; \
usermod -l roda ubuntu; \
usermod -d /home/roda -m roda; \
groupmod -n roda ubuntu; \
mkdir -p -m0770 "$RODA_HOME/data"; \
mkdir -p -m0770 "$RODA_HOME/config"; \
chown -R "$RODA_USER:0" "$RODA_HOME"
Expand Down
27 changes: 27 additions & 0 deletions roda-ui/roda-wui/src/main/java/org/roda/wui/RODA.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,18 @@
*/
package org.roda.wui;

import jakarta.servlet.ServletContext;
import jakarta.servlet.ServletException;
import org.apereo.cas.client.session.SingleSignOutHttpSessionListener;
import org.roda.wui.filter.OnOffFilter;
import org.roda.wui.filter.SecurityHeadersFilter;
import org.roda.wui.servlets.ContextListener;
import org.roda.wui.servlets.RodaWuiServlet;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletContextInitializer;
import org.springframework.boot.web.servlet.ServletListenerRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
Expand Down Expand Up @@ -57,6 +62,8 @@ public FilterRegistrationBean<OnOffFilter> internalWebAuthFilter() {
return registrationBean;
}



@Bean
public FilterRegistrationBean<OnOffFilter> internalApiAuthFilter() {
FilterRegistrationBean<OnOffFilter> registrationBean = new FilterRegistrationBean<>();
Expand Down Expand Up @@ -192,6 +199,14 @@ public ServletRegistrationBean<HttpServlet> clientLogger() {
return bean;
}

@Bean
public FilterRegistrationBean<SecurityHeadersFilter> securityHeadersFilter() {
FilterRegistrationBean<SecurityHeadersFilter> registrationBean = new FilterRegistrationBean<>();
registrationBean.setFilter(new SecurityHeadersFilter());
registrationBean.addUrlPatterns("/*"); // Apply the filter to all requests
return registrationBean;
}

@Bean
public ServletRegistrationBean<HttpServlet> userManagementService() {
ServletRegistrationBean<HttpServlet> bean;
Expand All @@ -216,6 +231,18 @@ public ServletRegistrationBean<HttpServlet> browserService() {
return bean;
}

@Bean
public ServletContextInitializer servletContextInitializer() {
return new ServletContextInitializer() {

@Override
public void onStartup(ServletContext servletContext) throws ServletException {
servletContext.getSessionCookieConfig().setSecure(true);
servletContext.getSessionCookieConfig().setHttpOnly(true);
}
};
}

@Configuration
public static class DefaultView implements WebMvcConfigurer {

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package org.roda.wui.filter;

import jakarta.servlet.*;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;

public class SecurityHeadersFilter implements Filter {

@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletResponse httpServletResponse = (HttpServletResponse) response;

httpServletResponse.setHeader("Strict-Transport-Security", "max-age=31536000; includeSubDomains");
httpServletResponse.setHeader("Content-Security-Policy", "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://www.google.com https://www.google-analytics.com; style-src 'self' 'unsafe-inline'; img-src 'self'; font-src 'self';");
httpServletResponse.setHeader("X-Frame-Options", "SAMEORIGIN");
httpServletResponse.setHeader("X-Content-Type-Options", "nosniff");
httpServletResponse.setHeader("Referrer-Policy", "no-referrer");
httpServletResponse.setHeader("Permissions-Policy", "geolocation=(self)");

chain.doFilter(request, response);
}

@Override
public void init(FilterConfig filterConfig) {
}

@Override
public void destroy() {
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -93,16 +93,19 @@
return null;
},

setCookie: function (name, value, expiryDays, domain, path) {
setCookie: function (name, value, expiryDays, domain, path, sameSite) {
expiryDays = expiryDays || 365;

sameSite = sameSite || 'Strict'; // Default SameSite value

var exdate = new Date();
exdate.setDate(exdate.getDate() + expiryDays);

var cookie = [
name + '=' + value,
'expires=' + exdate.toUTCString(),
'path=' + path || '/'
'path=' + path || '/',
'SameSite=' + sameSite // Correctly include SameSite attribute
];

if (domain) {
Expand Down Expand Up @@ -337,7 +340,7 @@
},

setDismissedCookie: function () {
Util.setCookie(DISMISSED_COOKIE, 'yes', this.options.expiryDays, this.options.domain, this.options.path);
Util.setCookie(DISMISSED_COOKIE, 'yes', this.options.expiryDays, this.options.domain, this.options.path, this.options.sameSite);
}
};

Expand Down
8 changes: 8 additions & 0 deletions roda-ui/roda-wui/src/main/webapp/META-INF/context.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<Context>

<!-- Add SameSite to the cookies -->
<CookieProcessor
sameSiteCookies="strict" />

</Context>
19 changes: 19 additions & 0 deletions roda-ui/roda-wui/src/main/webapp/WEB-INF/web.xml
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,15 @@
<url-pattern>/logout</url-pattern>
</filter-mapping>

<filter>
<filter-name>SecurityHeadersFilter</filter-name>
<filter-class>org.roda.wui.filter.SecurityHeadersFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>SecurityHeadersFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

<!-- ************************************ -->
<!-- REST related servlets/servlet-mappings -->
<!-- ************************************ -->
Expand Down Expand Up @@ -338,4 +347,14 @@
</web-resource-collection>
<auth-constraint/>
</security-constraint>

<session-config>
<cookie-config>
<http-only>true</http-only>
<secure>true</secure>
</cookie-config>
</session-config>



</web-app>

0 comments on commit 99d4ab4

Please sign in to comment.