Skip to content
This repository was archived by the owner on May 31, 2022. It is now read-only.

Possible CSRF detected - state parameter was present but no state could be found #322

Closed
cloud-devops-expert opened this issue Nov 26, 2014 · 11 comments

Comments

@cloud-devops-expert
Copy link

Hi,

When i try to create a Spring OAuth server, like this, in Spring blog, i get an error:

curl -X GET http://localhost:8080 -v -L -u user:password
* Rebuilt URL to: http://localhost:8080/
* Hostname was NOT found in DNS cache
*   Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 8080 (#0)
* Server auth using Basic with user 'user'
> GET / HTTP/1.1
> Authorization: Basic dXNlcjpwYXNzd29yZA==
> User-Agent: curl/7.35.0
> Host: localhost:8080
> Accept: */*
> 
< HTTP/1.1 302 Found
* Server Apache-Coyote/1.1 is not blacklisted
< Server: Apache-Coyote/1.1
< X-Content-Type-Options: nosniff
< X-XSS-Protection: 1; mode=block
< Cache-Control: no-cache, no-store, max-age=0, must-revalidate
< Pragma: no-cache
< Expires: 0
< X-Frame-Options: DENY
< Set-Cookie: JSESSIONID=16E880F53147AF4FA4C598615CFE97D4; Path=/; HttpOnly
< Location: http://localhost:8080/login
< Content-Length: 0
< Date: Wed, 26 Nov 2014 19:38:18 GMT
< 
* Connection #0 to host localhost left intact
* Issue another request to this URL: 'http://localhost:8080/login'
* Found bundle for host localhost: 0x15cf8b0
* Re-using existing connection! (#0) with host localhost
* Connected to localhost (127.0.0.1) port 8080 (#0)
* Server auth using Basic with user 'user'
> GET /login HTTP/1.1
> Authorization: Basic dXNlcjpwYXNzd29yZA==
> User-Agent: curl/7.35.0
> Host: localhost:8080
> Accept: */*
> 
< HTTP/1.1 302 Found
* Server Apache-Coyote/1.1 is not blacklisted
< Server: Apache-Coyote/1.1
< X-Content-Type-Options: nosniff
< X-XSS-Protection: 1; mode=block
< Cache-Control: no-cache, no-store, max-age=0, must-revalidate
< Pragma: no-cache
< Expires: 0
< X-Frame-Options: DENY
< Set-Cookie: JSESSIONID=8BCDD1F49074CA6239BC1E93903180F3; Path=/; HttpOnly
< Location: http://localhost:9998/oauth/authorize?client_id=my-trusted-client&redirect_uri=http%3A%2F%2Flocalhost%3A8080%2Flogin&response_type=code&state=Bvp1wZ
< Content-Length: 0
< Date: Wed, 26 Nov 2014 19:38:18 GMT
< 
* Connection #0 to host localhost left intact
* Issue another request to this URL: 'http://localhost:9998/oauth/authorize?client_id=my-trusted-client&redirect_uri=http%3A%2F%2Flocalhost%3A8080%2Flogin&response_type=code&state=Bvp1wZ'
* Found bundle for host localhost: 0x15cf8b0
* Hostname was NOT found in DNS cache
*   Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 9998 (#1)
* Server auth using Basic with user 'user'
> GET /oauth/authorize?client_id=my-trusted-client&redirect_uri=http%3A%2F%2Flocalhost%3A8080%2Flogin&response_type=code&state=Bvp1wZ HTTP/1.1
> Authorization: Basic dXNlcjpwYXNzd29yZA==
> User-Agent: curl/7.35.0
> Host: localhost:9998
> Accept: */*
> 
< HTTP/1.1 302 Found
* Server Apache-Coyote/1.1 is not blacklisted
< Server: Apache-Coyote/1.1
< Strict-Transport-Security: max-age=31536000 ; includeSubDomains
< Pragma: no-cache
< Expires: Thu, 01 Jan 1970 00:00:00 GMT
< Cache-Control: no-cache
< Cache-Control: no-store
< Location: http://localhost:8080/login?code=2eJuuj&state=Bvp1wZ
< Content-Language: pt-PT
< Content-Length: 0
< Date: Wed, 26 Nov 2014 19:38:18 GMT
< 
* Connection #1 to host localhost left intact
* Issue another request to this URL: 'http://localhost:8080/login?code=2eJuuj&state=Bvp1wZ'
* Found bundle for host localhost: 0x15cf8b0
* Re-using existing connection! (#0) with host localhost
* Connected to localhost (127.0.0.1) port 8080 (#0)
* Server auth using Basic with user 'user'
> GET /login?code=2eJuuj&state=Bvp1wZ HTTP/1.1
> Authorization: Basic dXNlcjpwYXNzd29yZA==
> User-Agent: curl/7.35.0
> Host: localhost:8080
> Accept: */*
> 
< HTTP/1.1 500 Internal Server Error
* Server Apache-Coyote/1.1 is not blacklisted
< Server: Apache-Coyote/1.1
< X-Content-Type-Options: nosniff
< X-XSS-Protection: 1; mode=block
< Cache-Control: no-cache, no-store, max-age=0, must-revalidate
< Pragma: no-cache
< Expires: 0
< X-Frame-Options: DENY
< Set-Cookie: JSESSIONID=BB959926086631B7120D7B9ED51C385D; Path=/; HttpOnly
< Content-Type: application/json;charset=UTF-8
< Transfer-Encoding: chunked
< Date: Wed, 26 Nov 2014 19:38:18 GMT
< Connection: close
< 
* Closing connection 0
{"timestamp":1417030698602,"status":500,"error":"Internal Server Error","exception":"org.springframework.security.oauth2.common.exceptions.InvalidRequestException","message":"Possible CSRF detected - state parameter was present but no state could be found","path":"/login"}

Apparently, state param is not maintained between different requests, by OAuthRestTemplate.

@dsyer
Copy link
Contributor

dsyer commented Nov 29, 2014

That depends on how you set up the OAuth2RestTemplate. Since there isn't one in the sample you linked to (and there is no /login either), you must be doing something different. If you use @EnableOAuth2Client as described in the docs and in the samples you will get a session-scoped context that saves the state.

@cloud-devops-expert
Copy link
Author

In client side, i'm using:

@Configuration
@EnableAutoConfiguration
@EnableOAuth2Sso
@ComponentScan
public class OauthConfig {
}

This configuration @EnableOAuth2Sso, activates @EnableOAuth2Client.

@dsyer
Copy link
Contributor

dsyer commented Nov 29, 2014

The problem is the session then. You have 2 servers running on localhost, on different ports, but cookies don't record the host, only the path, and both are on the root path "/" so they are sharing a cookie. Put one of them in a sub context (e.g. using server.contextPath=/auth for the auth server) and it should work I think.

@cloud-devops-expert
Copy link
Author

I tried that.
I putted client in /c and server in /s.
But problem continues:

curl -X GET http://localhost:8080/c -v -L -u user:password
* Hostname was NOT found in DNS cache
*   Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 8080 (#0)
* Server auth using Basic with user 'user'
> GET /c HTTP/1.1
> Authorization: Basic dXNlcjpwYXNzd29yZA==
> User-Agent: curl/7.35.0
> Host: localhost:8080
> Accept: */*
> 
< HTTP/1.1 302 Found
* Server Apache-Coyote/1.1 is not blacklisted
< Server: Apache-Coyote/1.1
< Location: http://localhost:8080/c/
< Transfer-Encoding: chunked
< Date: Sat, 29 Nov 2014 13:45:49 GMT
< 
* Ignoring the response-body
* Connection #0 to host localhost left intact
* Issue another request to this URL: 'http://localhost:8080/c/'
* Found bundle for host localhost: 0x8d2890
* Re-using existing connection! (#0) with host localhost
* Connected to localhost (127.0.0.1) port 8080 (#0)
* Server auth using Basic with user 'user'
> GET /c/ HTTP/1.1
> Authorization: Basic dXNlcjpwYXNzd29yZA==
> User-Agent: curl/7.35.0
> Host: localhost:8080
> Accept: */*
> 
< HTTP/1.1 302 Found
* Server Apache-Coyote/1.1 is not blacklisted
< Server: Apache-Coyote/1.1
< X-Content-Type-Options: nosniff
< X-XSS-Protection: 1; mode=block
< Cache-Control: no-cache, no-store, max-age=0, must-revalidate
< Pragma: no-cache
< Expires: 0
< X-Frame-Options: DENY
< Set-Cookie: JSESSIONID=F68F960F8A3CE93557A9A84FBC5C7F74; Path=/c/; HttpOnly
< Location: http://localhost:8080/c/login
< Content-Length: 0
< Date: Sat, 29 Nov 2014 13:45:49 GMT
< 
* Connection #0 to host localhost left intact
* Issue another request to this URL: 'http://localhost:8080/c/login'
* Found bundle for host localhost: 0x8d2890
* Re-using existing connection! (#0) with host localhost
* Connected to localhost (127.0.0.1) port 8080 (#0)
* Server auth using Basic with user 'user'
> GET /c/login HTTP/1.1
> Authorization: Basic dXNlcjpwYXNzd29yZA==
> User-Agent: curl/7.35.0
> Host: localhost:8080
> Accept: */*
> 
< HTTP/1.1 302 Found
* Server Apache-Coyote/1.1 is not blacklisted
< Server: Apache-Coyote/1.1
< X-Content-Type-Options: nosniff
< X-XSS-Protection: 1; mode=block
< Cache-Control: no-cache, no-store, max-age=0, must-revalidate
< Pragma: no-cache
< Expires: 0
< X-Frame-Options: DENY
< Set-Cookie: JSESSIONID=C6ED81BB2D78C7D88CE5D5F29290A0FD; Path=/c/; HttpOnly
< Location: http://localhost:9998/s/oauth/authorize?client_id=acme&redirect_uri=http%3A%2F%2Flocalhost%3A8080%2Fc%2Flogin&response_type=code&state=2K3YjJ
< Content-Length: 0
< Date: Sat, 29 Nov 2014 13:45:52 GMT
< 
* Connection #0 to host localhost left intact
* Issue another request to this URL: 'http://localhost:9998/s/oauth/authorize?client_id=acme&redirect_uri=http%3A%2F%2Flocalhost%3A8080%2Fc%2Flogin&response_type=code&state=2K3YjJ'
* Found bundle for host localhost: 0x8d2890
* Hostname was NOT found in DNS cache
*   Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 9998 (#1)
* Server auth using Basic with user 'user'
> GET /s/oauth/authorize?client_id=acme&redirect_uri=http%3A%2F%2Flocalhost%3A8080%2Fc%2Flogin&response_type=code&state=2K3YjJ HTTP/1.1
> Authorization: Basic dXNlcjpwYXNzd29yZA==
> User-Agent: curl/7.35.0
> Host: localhost:9998
> Accept: */*
> 
< HTTP/1.1 302 Found
* Server Apache-Coyote/1.1 is not blacklisted
< Server: Apache-Coyote/1.1
< Strict-Transport-Security: max-age=31536000 ; includeSubDomains
< Pragma: no-cache
< Expires: Thu, 01 Jan 1970 00:00:00 GMT
< Cache-Control: no-cache
< Cache-Control: no-store
< Location: http://localhost:8080/c/login?code=aWzQ6N&state=2K3YjJ
< Content-Language: pt-PT
< Content-Length: 0
< Date: Sat, 29 Nov 2014 13:45:52 GMT
< 
* Connection #1 to host localhost left intact
* Issue another request to this URL: 'http://localhost:8080/c/login?code=aWzQ6N&state=2K3YjJ'
* Found bundle for host localhost: 0x8d2890
* Re-using existing connection! (#0) with host localhost
* Connected to localhost (127.0.0.1) port 8080 (#0)
* Server auth using Basic with user 'user'
> GET /c/login?code=aWzQ6N&state=2K3YjJ HTTP/1.1
> Authorization: Basic dXNlcjpwYXNzd29yZA==
> User-Agent: curl/7.35.0
> Host: localhost:8080
> Accept: */*
> 
< HTTP/1.1 500 Internal Server Error
* Server Apache-Coyote/1.1 is not blacklisted
< Server: Apache-Coyote/1.1
< X-Content-Type-Options: nosniff
< X-XSS-Protection: 1; mode=block
< Cache-Control: no-cache, no-store, max-age=0, must-revalidate
< Pragma: no-cache
< Expires: 0
< X-Frame-Options: DENY
< Set-Cookie: JSESSIONID=4AAECB750626D63EFE9FC6C35729C39B; Path=/c/; HttpOnly
< Content-Type: application/json;charset=UTF-8
< Transfer-Encoding: chunked
< Date: Sat, 29 Nov 2014 13:45:54 GMT
< Connection: close
< 
* Closing connection 0
{"timestamp":1417268754019,"status":500,"error":"Internal Server Error","exception":"org.springframework.security.oauth2.common.exceptions.InvalidRequestException","message":"Possible CSRF detected - state parameter was present but no state could be found","path":"/c/login"}

@dsyer
Copy link
Contributor

dsyer commented Nov 29, 2014

I can see that your client is not sending cookies. I think you can do it with curl, but it might take some effort. Does it work in a browser?

@cloud-devops-expert
Copy link
Author

I activated the cookies in curl, and now i have a different error: Error requesting token:

curl -X GET http://localhost:8080/c -v -L -u user:password -c cookies.txt
* Hostname was NOT found in DNS cache
*   Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 8080 (#0)
* Server auth using Basic with user 'user'
> GET /c HTTP/1.1
> Authorization: Basic dXNlcjpwYXNzd29yZA==
> User-Agent: curl/7.35.0
> Host: localhost:8080
> Accept: */*
> 
< HTTP/1.1 302 Found
* Server Apache-Coyote/1.1 is not blacklisted
< Server: Apache-Coyote/1.1
< Location: http://localhost:8080/c/
< Transfer-Encoding: chunked
< Date: Sat, 29 Nov 2014 15:03:35 GMT
< 
* Ignoring the response-body
* Connection #0 to host localhost left intact
* Issue another request to this URL: 'http://localhost:8080/c/'
* Found bundle for host localhost: 0x2159920
* Re-using existing connection! (#0) with host localhost
* Connected to localhost (127.0.0.1) port 8080 (#0)
* Server auth using Basic with user 'user'
> GET /c/ HTTP/1.1
> Authorization: Basic dXNlcjpwYXNzd29yZA==
> User-Agent: curl/7.35.0
> Host: localhost:8080
> Accept: */*
> 
< HTTP/1.1 302 Found
* Server Apache-Coyote/1.1 is not blacklisted
< Server: Apache-Coyote/1.1
< X-Content-Type-Options: nosniff
< X-XSS-Protection: 1; mode=block
< Cache-Control: no-cache, no-store, max-age=0, must-revalidate
< Pragma: no-cache
< Expires: 0
< X-Frame-Options: DENY
* Added cookie JSESSIONID="F0B9A1709103E2D21713A983A4C7AE5F" for domain localhost, path /c/, expire 0
< Set-Cookie: JSESSIONID=F0B9A1709103E2D21713A983A4C7AE5F; Path=/c/; HttpOnly
< Location: http://localhost:8080/c/login
< Content-Length: 0
< Date: Sat, 29 Nov 2014 15:03:35 GMT
< 
* Connection #0 to host localhost left intact
* Issue another request to this URL: 'http://localhost:8080/c/login'
* Found bundle for host localhost: 0x2159920
* Re-using existing connection! (#0) with host localhost
* Connected to localhost (127.0.0.1) port 8080 (#0)
* Server auth using Basic with user 'user'
> GET /c/login HTTP/1.1
> Authorization: Basic dXNlcjpwYXNzd29yZA==
> User-Agent: curl/7.35.0
> Host: localhost:8080
> Accept: */*
> Cookie: JSESSIONID=F0B9A1709103E2D21713A983A4C7AE5F
> 
< HTTP/1.1 302 Found
* Server Apache-Coyote/1.1 is not blacklisted
< Server: Apache-Coyote/1.1
< X-Content-Type-Options: nosniff
< X-XSS-Protection: 1; mode=block
< Cache-Control: no-cache, no-store, max-age=0, must-revalidate
< Pragma: no-cache
< Expires: 0
< X-Frame-Options: DENY
< Location: http://localhost:9998/s/oauth/authorize?client_id=libertas&redirect_uri=http%3A%2F%2Flocalhost%3A8080%2Fc%2Flogin&response_type=code&state=RdqgBV
< Content-Length: 0
< Date: Sat, 29 Nov 2014 15:03:35 GMT
< 
* Connection #0 to host localhost left intact
* Issue another request to this URL: 'http://localhost:9998/s/oauth/authorize?client_id=libertas&redirect_uri=http%3A%2F%2Flocalhost%3A8080%2Fc%2Flogin&response_type=code&state=RdqgBV'
* Found bundle for host localhost: 0x2159920
* Hostname was NOT found in DNS cache
*   Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 9998 (#1)
* Server auth using Basic with user 'user'
> GET /s/oauth/authorize?client_id=libertas&redirect_uri=http%3A%2F%2Flocalhost%3A8080%2Fc%2Flogin&response_type=code&state=RdqgBV HTTP/1.1
> Authorization: Basic dXNlcjpwYXNzd29yZA==
> User-Agent: curl/7.35.0
> Host: localhost:9998
> Accept: */*
> 
< HTTP/1.1 302 Found
* Server Apache-Coyote/1.1 is not blacklisted
< Server: Apache-Coyote/1.1
< Strict-Transport-Security: max-age=31536000 ; includeSubDomains
< Pragma: no-cache
< Expires: Thu, 01 Jan 1970 00:00:00 GMT
< Cache-Control: no-cache
< Cache-Control: no-store
< Location: http://localhost:8080/c/login?code=C7t83H&state=RdqgBV
< Content-Language: pt-PT
< Content-Length: 0
< Date: Sat, 29 Nov 2014 15:03:35 GMT
< 
* Connection #1 to host localhost left intact
* Issue another request to this URL: 'http://localhost:8080/c/login?code=C7t83H&state=RdqgBV'
* Found bundle for host localhost: 0x2159920
* Re-using existing connection! (#0) with host localhost
* Connected to localhost (127.0.0.1) port 8080 (#0)
* Server auth using Basic with user 'user'
> GET /c/login?code=C7t83H&state=RdqgBV HTTP/1.1
> Authorization: Basic dXNlcjpwYXNzd29yZA==
> User-Agent: curl/7.35.0
> Host: localhost:8080
> Accept: */*
> Cookie: JSESSIONID=F0B9A1709103E2D21713A983A4C7AE5F
> 
< HTTP/1.1 500 Internal Server Error
* Server Apache-Coyote/1.1 is not blacklisted
< Server: Apache-Coyote/1.1
< X-Content-Type-Options: nosniff
< X-XSS-Protection: 1; mode=block
< Cache-Control: no-cache, no-store, max-age=0, must-revalidate
< Pragma: no-cache
< Expires: 0
< X-Frame-Options: DENY
< Content-Type: application/json;charset=UTF-8
< Transfer-Encoding: chunked
< Date: Sat, 29 Nov 2014 15:03:35 GMT
< Connection: close
< 
* Closing connection 0
{"timestamp":1417273415416,"status":500,"error":"Internal Server Error","exception":"org.springframework.security.oauth2.client.resource.OAuth2AccessDeniedException","message":"Error requesting access token.","path":"/c/login"}

@dsyer
Copy link
Contributor

dsyer commented Nov 29, 2014

Looks like an access denied when the client tries to get the user details. Perfectly normal probably. This isn't really a Spring OAuth feature, but maybe you can share a bit more? How is the client trying to get the user details? Did you forget to set the access rule for the token info endpoint on the server?

@dsyer
Copy link
Contributor

dsyer commented Dec 1, 2014

Duplicates spring-attic/spring-cloud-security#13

@dsyer dsyer closed this as completed Dec 1, 2014
@prashantbhate
Copy link

Just seen a similar issue while trying out https://spring.io/guides/tutorials/spring-boot-oauth2/
and observed that this issue is with chrome browser that wasn't passing the JSESSIONID after facebook redirect . Same worked when I Used Safari , (just adding it here so that it saves someone's two hours !)

you can see that set-cookie is called twice as second login/facebook call is not passing previously set sessionid

call sequence

@ex0b1t
Copy link

ex0b1t commented Aug 24, 2017

An alternative to @dsyer suggestion to change the context path is to change the cookie name one of your services use eg.

server:
  port: 8081
  session:
    cookie:
      name: OAUTH2SESSION # This is to prevent cookie clash with other service as they run on the same host and context path

@ChangdongLi
Copy link

Note since Spring Boot 2, to change the cookie name, the parameter is server.servlet.session.cookie.name

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Development

No branches or pull requests

5 participants