spring-projects / spring-projects/spring-security

org.springframework.security.web.savedrequest.DefaultSavedRequest ignores HTTP method when matching current request to saved request

Open
#13,140 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

in: web status: waiting-for-triage
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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.