Don't require csrf for search endpoint

Reasoning:

- It doesn't change state and is not a sensitive endpoint
- It really should be changed to GET but that is a bit more intrusive
  change that can be done at another time
- The search csrf token is stored on the top.jsp page for a long time.
  If the user keeps this tab open for a while it is possible the csrf
  token will change on their session with other requests going on such
  that the search csrf token becomes wrong/stale.

Signed-off-by: Andrew DeMaria <lostonamountain@gmail.com>
master
Andrew DeMaria 7 years ago
parent ded28c4669
commit c7789533a0
No known key found for this signature in database
GPG Key ID: 0A3F5E91F8364EDF
  1. 29
      airsonic-main/src/main/java/org/airsonic/player/security/CsrfSecurityRequestMatcher.java
  2. 1
      airsonic-main/src/main/webapp/WEB-INF/jsp/top.jsp

@ -6,6 +6,8 @@ import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Collection;
import java.util.regex.Pattern; import java.util.regex.Pattern;
/** /**
@ -19,24 +21,23 @@ import java.util.regex.Pattern;
@Component @Component
public class CsrfSecurityRequestMatcher implements RequestMatcher { public class CsrfSecurityRequestMatcher implements RequestMatcher {
private Pattern allowedMethods = Pattern.compile("^(GET|HEAD|TRACE|OPTIONS)$"); private Pattern allowedMethods = Pattern.compile("^(GET|HEAD|TRACE|OPTIONS)$");
private RegexRequestMatcher dwrRequestMatcher = new RegexRequestMatcher("/dwr/.*\\.dwr", "POST"); private Collection<RegexRequestMatcher> whiteListedMatchers;
private RegexRequestMatcher restRequestMatcher = new RegexRequestMatcher("/rest/.*\\.view(\\?.*)?", "POST");
public CsrfSecurityRequestMatcher() {
Collection<RegexRequestMatcher> whiteListedMatchers = new ArrayList<>();
whiteListedMatchers.add(new RegexRequestMatcher("/dwr/.*\\.dwr", "POST"));
whiteListedMatchers.add(new RegexRequestMatcher("/rest/.*\\.view(\\?.*)?", "POST"));
whiteListedMatchers.add(new RegexRequestMatcher("/search(?:\\.view)?", "POST"));
this.whiteListedMatchers = whiteListedMatchers;
}
@Override @Override
public boolean matches(HttpServletRequest request) { public boolean matches(HttpServletRequest request) {
boolean requireCsrfToken = true; boolean skipCSRF =
allowedMethods.matcher(request.getMethod()).matches() ||
if(allowedMethods.matcher(request.getMethod()).matches()){ whiteListedMatchers.stream().anyMatch(matcher -> matcher.matches(request));
requireCsrfToken = false;
} else {
if (dwrRequestMatcher.matches(request)) {
requireCsrfToken = false;
} else if (restRequestMatcher.matches(request)) {
requireCsrfToken = false;
}
}
return requireCsrfToken; return !skipCSRF;
} }
} }

@ -125,7 +125,6 @@
<td style="padding-left:1em"> <td style="padding-left:1em">
<form method="post" action="search.view" target="main" name="searchForm"> <form method="post" action="search.view" target="main" name="searchForm">
<sec:csrfInput />
<td><input type="text" name="query" id="query" size="28" placeholder="${search}" onclick="select();" <td><input type="text" name="query" id="query" size="28" placeholder="${search}" onclick="select();"
onkeyup="triggerInstantSearch();"></td> onkeyup="triggerInstantSearch();"></td>
<td><a href="javascript:document.searchForm.submit()"><img src="<spring:theme code="searchImage"/>" alt="${search}" title="${search}"></a></td> <td><a href="javascript:document.searchForm.submit()"><img src="<spring:theme code="searchImage"/>" alt="${search}" title="${search}"></a></td>

Loading…
Cancel
Save