Skip to content
17 changes: 6 additions & 11 deletions src/owasp-suppression.xml
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,11 @@
-->
<suppressions xmlns="https://jeremylong.github.io/DependencyCheck/dependency-suppression.1.1.xsd">

<suppress>
<notes><![CDATA[ file name: tomcat-embed-core-8.5.5.jar ]]></notes>
<sha1>d55e12a418ff99ecd723a118c2a28bb91079972d</sha1>
<cpe>cpe:/a:apache:tomcat:8.5.5</cpe>
</suppress>

<suppress>
<notes><![CDATA[ file name: tomcat-embed-websocket-8.5.5.jar ]]></notes>
<sha1>fd99cd1cd4c824abdf03466f0509f067747f0d1a</sha1>
<cpe>cpe:/a:apache:tomcat:8.5.5</cpe>
</suppress>
<!-- EXAMPLE-->
<!-- <suppress>-->
<!-- <notes><![CDATA[ file name: tomcat-embed-core-8.5.5.jar ]]></notes>-->
<!-- <sha1>d55e12a418ff99ecd723a118c2a28bb91079972d</sha1>-->
<!-- <cpe>cpe:/a:apache:tomcat:8.5.5</cpe>-->
<!-- </suppress>-->

</suppressions>

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,12 @@
*/
package org.apache.shiro.ee.filters;

import static org.apache.shiro.SecurityUtils.getSecurityManager;
import static org.apache.shiro.ee.cdi.ShiroScopeContext.isWebContainerSessions;
import static org.apache.shiro.ee.filters.FormResubmitSupport.getNativeSessionManager;
import java.net.CookieManager;
import java.net.HttpCookie;
import java.net.URI;
import java.time.Duration;
import java.util.List;
import java.util.Map;
Expand All @@ -24,12 +27,15 @@
import jakarta.servlet.ServletContext;
import jakarta.servlet.ServletRequest;
import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.ee.listeners.EnvironmentLoaderListener;
import static org.apache.shiro.web.mgt.CookieRememberMeManager.DEFAULT_REMEMBER_ME_COOKIE_NAME;
import static org.apache.shiro.web.servlet.ShiroHttpSession.DEFAULT_SESSION_ID_NAME;

/**
Expand Down Expand Up @@ -96,4 +102,30 @@ static Map<String, String> transformCookieHeader(@NonNull List<String> cookies)
static Stream<HttpCookie> cookieStreamFromHeader(@NonNull List<String> cookies) {
return cookies.stream().map(HttpCookie::parse).map(list -> list.get(0));
}

static void initializeCookies(URI savedRequest, ServletContext servletContext,
CookieManager cookieManager, HttpServletRequest originalRequest) {
var session = SecurityUtils.getSubject().getSession();
var sessionCookieName = getSessionCookieName(servletContext, getSecurityManager());
var sessionCookie = new HttpCookie(sessionCookieName, session.getId().toString());
sessionCookie.setPath(servletContext.getContextPath());
sessionCookie.setVersion(0);
cookieManager.getCookieStore().add(savedRequest, sessionCookie);
log.debug("Setting Cookie {}", sessionCookieName);
for (Cookie origCookie : originalRequest.getCookies()) {
if (!origCookie.getName().startsWith(sessionCookieName)
&& !origCookie.getName().equals(DEFAULT_REMEMBER_ME_COOKIE_NAME)) {
try {
log.debug("Setting Cookie {}", origCookie.getName());
HttpCookie cookie = new HttpCookie(origCookie.getName(), origCookie.getValue());
cookie.setPath(servletContext.getContextPath());
cookie.setVersion(0);
cookieManager.getCookieStore().add(savedRequest, cookie);
} catch (IllegalArgumentException e) {
log.warn("Form Resubmit: Ignoring invalid cookie [{} - {}]",
origCookie.getName(), origCookie.getValue(), e);
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,35 +23,39 @@
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.mgt.DefaultSecurityManager;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Optional;
import java.util.UUID;
import java.util.stream.Collectors;
import static org.apache.shiro.SecurityUtils.getSecurityManager;
import static org.apache.shiro.ee.filters.FormResubmitSupport.FORM_DATA_CACHE;
import static org.apache.shiro.ee.filters.FormResubmitSupport.decrypt;
import static org.apache.shiro.ee.filters.FormResubmitSupport.getRememberMeManager;
import static org.apache.shiro.web.filter.authc.NoAccessFilter.FORM_RESUBMIT_CHECK_SERVLET_PATH;

@Slf4j
@WebServlet(name = "ShiroFormResubmitValidator", urlPatterns = FORM_RESUBMIT_CHECK_SERVLET_PATH)
public class FormResubmitValidator extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) {
var session = SecurityUtils.getSubject().getSession(false);
if (session == null) {
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
return;
}

protected void doPost(HttpServletRequest request, HttpServletResponse response) {
var rememberMeManager = getRememberMeManager();
if (rememberMeManager == null || rememberMeManager.getCipherService() == null) {
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
} else {
try {
String encryptedSessionId = rememberMeManager.getCipherService()
.encrypt(session.getId().toString().getBytes(StandardCharsets.UTF_8),
String formDataKey = decrypt(request.getReader().lines().collect(Collectors.joining()), rememberMeManager);
var cache = getSecurityManager(DefaultSecurityManager.class)
.getCacheManager().getCache(FORM_DATA_CACHE);
Optional.ofNullable(cache.get(UUID.fromString(formDataKey))).orElseThrow(IllegalCallerException::new);
String encryptedFormDataKey = rememberMeManager.getCipherService()
.encrypt(formDataKey.getBytes(StandardCharsets.UTF_8),
rememberMeManager.getEncryptionCipherKey()).toBase64();
response.getWriter().write(encryptedSessionId);
response.getWriter().write(encryptedFormDataKey);
response.setStatus(HttpServletResponse.SC_OK);
} catch (IOException e) {
log.warn("Form resubmit verification: failed to write encrypted principals to response", e);
} catch (IOException | IllegalCallerException e) {
log.warn("Form resubmit verification: invalid input or failed to write encrypted session id to response", e);
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ public void setSecurityManager(WebSecurityManager sm) {
}

@Override
@SneakyThrows
@SneakyThrows(InterruptedException.class)
protected void executeChain(ServletRequest request, ServletResponse response,
FilterChain origChain) throws IOException, ServletException {
if (isShiroEEDisabled(getServletContext())) {
Expand All @@ -245,7 +245,7 @@ protected void executeChain(ServletRequest request, ServletResponse response,
log.debug("Resubmitting Post Data: {}", postData);
var httpRequest = WebUtils.toHttp(request);
boolean rememberedAjaxResubmit = "partial/ajax".equals(httpRequest.getHeader("Faces-Request"));
Optional.ofNullable(resubmitSavedForm(postData,
Optional.ofNullable(resubmitSavedForm(postData, null,
Servlets.getRequestURLWithQueryString(httpRequest),
WebUtils.toHttp(request), WebUtils.toHttp(response),
request.getServletContext(), rememberedAjaxResubmit, false))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ protected AuthenticationToken createToken(ServletRequest request, ServletRespons
protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
if (request instanceof HttpServletRequest) {
HttpServletRequest httpRequest = WebUtils.toHttp(request);
return httpRequest.getMethod().equals("GET")
return httpRequest.getMethod().equals("POST")
&& httpRequest.getServletPath().equals(FORM_RESUBMIT_CHECK_SERVLET_PATH);
}
return false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import static org.apache.shiro.web.filter.authz.PortFilter.DEFAULT_HTTP_PORT;
import static org.apache.shiro.web.filter.authz.PortFilter.HTTP_SCHEME;
import static org.apache.shiro.web.filter.authz.SslFilter.DEFAULT_HTTPS_PORT;
import static org.apache.shiro.web.filter.authz.SslFilter.HTTPS_SCHEME;

/**
* HttpServletResponse implementation to support URL Encoding of Shiro Session IDs.
Expand Down Expand Up @@ -183,18 +187,18 @@ private boolean doIsEncodeable(HttpServletRequest hreq, HttpSession session, Str
}
int serverPort = hreq.getServerPort();
if (serverPort == -1) {
if ("https".equals(hreq.getScheme())) {
serverPort = 443;
if (HTTPS_SCHEME.equals(hreq.getScheme())) {
serverPort = DEFAULT_HTTPS_PORT;
} else {
serverPort = 80;
serverPort = DEFAULT_HTTP_PORT;
}
}
int urlPort = url.getPort();
if (urlPort == -1) {
if ("https".equals(url.getProtocol())) {
urlPort = 443;
if (HTTPS_SCHEME.equals(url.getProtocol())) {
urlPort = DEFAULT_HTTPS_PORT;
} else {
urlPort = 80;
urlPort = DEFAULT_HTTP_PORT;
}
}
if (serverPort != urlPort) {
Expand All @@ -208,9 +212,7 @@ private boolean doIsEncodeable(HttpServletRequest hreq, HttpSession session, Str
return (false);
}
String tok = ";" + DEFAULT_SESSION_ID_PARAMETER_NAME + "=" + session.getId();
if (file.indexOf(tok, contextPath.length()) >= 0) {
return (false);
}
return file.indexOf(tok, contextPath.length()) < 0;
}

// This URL belongs to our web application, so it is encodeable
Expand Down Expand Up @@ -248,8 +250,8 @@ private String toAbsolute(String location) {

try {
buf.append(scheme).append("://").append(name);
if ((scheme.equals("http") && port != 80)
|| (scheme.equals("https") && port != 443)) {
if ((scheme.equals(HTTP_SCHEME) && port != DEFAULT_HTTP_PORT)
|| (scheme.equals(HTTPS_SCHEME) && port != DEFAULT_HTTPS_PORT)) {
buf.append(':').append(port);
}
if (!leadingSlash) {
Expand All @@ -262,9 +264,7 @@ private String toAbsolute(String location) {
}
buf.append(location);
} catch (IOException e) {
IllegalArgumentException iae = new IllegalArgumentException(location);
iae.initCause(e);
throw iae;
throw new IllegalArgumentException(location, e);
}

return buf.toString();
Expand Down Expand Up @@ -333,7 +333,7 @@ protected String toEncoded(String url, String sessionId) {
}
StringBuilder sb = new StringBuilder(path);
// session id param can't be first.
if (sb.length() > 0) {
if (!sb.isEmpty()) {
sb.append(";");
sb.append(DEFAULT_SESSION_ID_PARAMETER_NAME);
sb.append("=");
Expand Down
Loading