spring-projects / spring-projects/spring-security
org.springframework.security.web.savedrequest.DefaultSavedRequest ignores HTTP method when matching current request to saved request
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 9.6k
- Forks
- 6.3k
- Avg merge
- 2d 11h
- Merged PRs (30d)
- 52
Description
Describe the bug
Context: Spring Boot application with two or more REST endpoints that mapped to the same path but different HTTP methods, permissions for endpoints are different. It is possible that endpoint's response may be wrong ("access denied") if previously another endpoint was called (same path, another HTTP method).
To Reproduce
Example application: https://github.com/astr2k/spring-security-issue-demo
May be reproduced using JUnit tests and Spring's MockMvc, Postman, etc.
Application has two REST endpoints, one mapped to GET method, another to PUT, paths are the same.
Permissions configuration: PUT endpoint may be executed only by user having "ADMIN" role, GET endpoint is permitted for all.
After application starts, call all endpoints as anonymous user, do not login.
First call GET endpoint - returns OK (expected).
Call PUT endpoint - returns Unauthorized (expected).
Call again GET endpoint - now returns Unauthorized, same response as in previous call.
Expected behavior
Calling GET endpoint should not return Unauthorized status as it is permitted for all.
Possible root cause
Traced the execution flow in debugger and, as of my understanding, the root cause is flawed logic in DefaultSavedRequest class when matching current request to saved (cached) request:
https://github.com/spring-projects/spring-security/blob/1631cac1506d7fdda1f3864357075af4965a78cd/web/src/main/java/org/springframework/security/web/savedrequest/DefaultSavedRequest.java#L235
if (!"GET".equals(request.getMethod()) && "GET".equals(this.method)) {
// A save GET should not match an incoming non-GET method
return false;
}
Means that in most cases requests with different HTTP methods will be considered the same.
Environment
Java 17, Spring Boot 3.0.6, Spring Security 6.0.3.
Reproducible with earlier versions too, also Spring Boot 2.x.x
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in web/src/main/java/org/springframework/security/web/savedrequest/DefaultSavedRequest.java around line 235 and trace how the saved request is matched. Reproduce the GET/PUT sequence with the linked example or Spring MockMvc, then add regression coverage showing that different HTTP methods do not match and that the permitted GET remains successful.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java, spring
- Domain
- backend, security
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100