How to obtain csrf token to be sent in the request header while calling lagom service endpoint? - security

I have a Lagom application in which I have enabled play security headers by adding play filters dependency in the project. Now, when I am hitting the service endpoint, it is giving the error:
p.filters.CSRF - [CSRF] Check failed because no token found in headers
I have in the play documentation that Play will require a CSRF check when all of the following are true:
The request method is not GET, HEAD or OPTIONS.
The request has one or more Cookie or Authorization headers.
The CORS filter is not configured to trust the request’s origin.
And all three are true in my case. Disabling csrf check is not an option for me.
I just can figure out how can I obtain this token to be sent in the header. Do I need to add anything in the configuration file?
Any help would be appreciated.

Disabling csrf check is not an option for me.
Why? Lagom is a framework for sessionless microservices. It's very strange, that you need CSRF token for calling Lagom endpoint. If you want to protect Lagom endpoint, you need to think about implement authenticating/authorize.

Related

Is an HTTPS header or a post body more secure?

When sending an HTTPS request, is there any difference from a security standpoint between a header and the post body? Is one more vulnerable to leaking or interception? If so, why?
I have read comparisons of GET vs. POST and of various authentication and encryption schemes against each other, but nothing about Header vs. application/x-www-form-urlencoded Post bodies. I admit I only spent ~20 minutes googling and SO searching, so apologies if this has been covered before.
While I believe this to be generic to all HTTPS traffic, I'm asking in the context of OpenId Connect. I am using the Authorization Code grant type and the Spring Security OAuth client libraries.
OIDC stipulates Clients and Authorization Servers have a choice of method for sending credentials when exchanging a one-time code for a durable id token. Quoting openid.net openid-connect-core section 9. Client Authentication:
This section defines a set of Client Authentication methods that are
used by Clients to authenticate to the Authorization Server when using
the Token Endpoint. During Client Registration, the RP (Client) MAY
register a Client Authentication method. If no method is registered,
the default method is client_secret_basic.
These Client Authentication methods are:
client_secret_basic
Clients that have received a client_secret value
from the Authorization Server authenticate with the Authorization
Server in accordance with Section 2.3.1 of OAuth 2.0 [RFC6749] using
the HTTP Basic authentication scheme.
Note, this is the Authorization: Basic <value> header. The provider I'm integrating with supports this via OpenId client_id and client_secret concatenated with a colon and Base64 encoded.
client_secret_post
Clients that
have received a client_secret value from the Authorization Server,
authenticate with the Authorization Server in accordance with Section
2.3.1 of OAuth 2.0 [RFC6749] by including the Client Credentials in the request body.
I have not been able to find anything specific to OpenId Connect that expresses a preference between either method.
I am integrating with a OIDC provider that allows either method, but you must choose and all dependent resource servers must conform to the single choice. Both the header and post body are sent in plain text. (Note this provider does not support either the client_secret_jwt method which is HMAC SHA encoded version of the sensitive secret or the private_key_jwt method which is a public-private signature, both of which are clearly more secure than essentially plaintext values, but it's unclear if this adds any practical security improvement on a TLS/SSL encrypted communication.)
OAuth 2.0 prefers HTTP Basic auth and states the following about this:
Including the client credentials in the request-body using the two parameters is NOT RECOMMENDED and SHOULD be limited to clients unable to directly utilize the HTTP Basic authentication scheme (or other password-based HTTP authentication schemes).
You can safely assume that this translates to OIDC as well.
While Pieter pointed on the specification, I also have a thought on the best practice.
Given a post body can contain any information, there is no way browsers, proxy implementations or an API to respect secrets embedded in body. In comparison, Authorisation header is defined and maintained by RFC7235, which is a standard.
4.2. Authorization
The "Authorization" header field allows a user agent to authenticate
itself with an origin server -- usually, but not necessarily, after
receiving a 401 (Unauthorized) response. Its value consists of
credentials containing the authentication information of the user
agent for the realm of the resource being requested.
More on proxy,
A proxy forwarding a request MUST NOT modify any Authorization fields
in that request. See Section 3.2 of [RFC7234] for details of and
requirements pertaining to handling of the Authorization field by
HTTP caches.
So being a well understood header by many parties should make it the safest way to transmit credentials. Hope this thought will help others to make their design decisions.

Client Credentials authorization with Azure Active directory and Swagger

Need to get the authorization token to access my app running on localhost. I query the AAD token endpoint for the token from the Swagger OAuth2 client in UseSwaggerUi3. I get the CORS error that endpoint is not allowing the cross origin requests from my localhost. How can I fix this?
[Edit]
I'm able to get the token if I send a POST request to the same endpoint using Fiddler.
You can't use client credentials flow from the front-end. Firstly because your secret is visible to anyone who sees the page.
Secondly because Azure AD blocks cross origin requests to its token endpoint. (as you saw)
You need to use authorization code or implicit flow with user context. Or build another API which gets the token in the back-end and calls the other API with it.
CORS are the cross origin resource, it will allow two different web apps working on 2 different origin to communicate with each other.
There are two ways to enable cors
1) go-to azure - web apps - setting column search - cors.
2) add new cors header as "*", which means it will allow all the urls which are requesting the web app, you also provide specific one url.
3) save it.
4) second approach is allow cors header from your code in web config headers.

How to disable csrf for token based authentication and enable it for browser?

The gateway serves an angular application which attaches CSRF token to each request; it is ok. When I send a password grant type request from mobile (emulated by postman), there is an exception "invalid CSRF token", I think the request is token based and should not depend on CSRF.
I check the source code and found it possible to disable CSRF in SecurityConfiguration.java file, but it will affect angular app if disable it.
I searched online, and someone suggests set up another set of routes for the mobile app. But I think the jhipster microservices framework may support it out-of-box.
How to support CSRF for browser-based application and disable it for token-based authentication?

jwt: Why is my token shown in Chrome DevTools?

I have a API in Express.js that will create blog posts and add them to my database. When I make a request from my React app inside of DevTools it will show my JWT. I am worried that when my site goes live people can see my token and make a request from their site to add unwanted posts. Please tell me what is going on and how I can prevent the security error.
When you send a request with a token in the header it will look like this in the header pane in Developer Tools:
I assume that's what you are wondering whether is safe or not.
The connection between the React app and the API is unencrypted when you are using ordinary HTTP. That makes a replay attack possible – an ISP or another server between the front-end and the API can read the token and pretend to be you later on with the read token.
The most important solution to that is to use HTTPS, which is encrypted HTTP. Potential attackers are unable to sniff and steal the tokens when you are using HTTPS. When you are dealing with usernames, passwords, etc., you should always use HTTPS.
HTTPS is free to use and not very hard to set up. See here for more details. There is also an interesting discussion here that you might want to read.
it's possible to see the JWT on the Chrome Dev tools because you are sending it as authorization header when creating a new blog post on your API, and you are making this request directly from the React application.
If the JWT is sensitive it should never be available on the front-end, you must have a server acting like a proxy, it should receive the request from the React application and then forward the request with JWT as the authorization header to your API.
Doing that you would avoid leaking the JWT, but it would still possible for someone to make requests to your proxy, which will be forwarded to your API.
If you want that only your react application be able to perform requests to your proxy, you could create a middleware which verifies the IP address of the incoming request (more details here), if it matches with your React app address then you accept the request, otherwise, you return a non-authorized error.
If you want only specific people to be able to create blog posts, then you should put authentication on the react application.

Is there any difference if I pass a user credentials as a payload, in the header, a parameter, or a query?

I am making an API for my app and I want to know if there is any difference security wise whether I pass a user's credentials as a payload, in the header, as a parameter, or as a query? Besides security, are there any differences at all such as performance, is one faster that the other?
This is for authenticating a user via username and password, from the client to the server in a GET request.
There is lot of difference when you send the credentials as payload or header or param or query. But it depends if you are using http or https. If its http then it is not at all recommended that you send the credentials at any cost over these mediums, as the request and the data can easily be traced. In case of https, you can do it but the most respected way of doing it would be to use Basic Authentication mechanism thats why its build or use OAUTH.
GET method is intended to be used to get some information from server, POST - to send data or request an action, so GET shouldn't be used for that.
You shouldn't pass authentication credentials as request parameters since they may easily leak at proxy servers, interim routers or insecure networks.
Passing them in a POST payload or request headers would minimize the probability of leaks, but anyway secure browser-to-server channel (https) must be used anyway.
While handling the authentication request on server make sure it has come from your own and not some other server. That can be implemented by using some server-generated key/token with limited lifetime and checking that token for validity when handling the POST request with credentials sent from browser.
If you issue some kind of authentication token or session id from server and keep it in a cookie, you should set HttpOnly flag to prevent access to them from JavaScript.
If you develop stateless single-page application, consider using JSON Web Token (JWT) to handle authentication/authorization claims, that would minimize the need to request permanent storage (database) on a backend and help with authentication procedures for multiple distributed resources.

Resources