Specify OAuth token in GET URL - rest

My REST service uses OAuth 2.0 authentication. I want to test some GET URLs using the browser (without using a client). Can I pass the bearer token in the URL ?
URL : www.example.com/employee/employeeId

You can pass it in the access_token query parameter, see https://www.rfc-editor.org/rfc/rfc6750#section-2.3, but as noted in the other answer, it is not the preferred way of passing a token. It may end up in logs, browser cache etc. On this method the spec says:
Because of the security weaknesses associated with the URI method
(see Section 5), including the high likelihood that the URL
containing the access token will be logged, it SHOULD NOT be used
unless it is impossible to transport the access token in the
"Authorization" request header field or the HTTP request entity-body.
Resource servers MAY support this method.
This method is included to document current use; its use is not
recommended, due to its security deficiencies (see Section 5) and
also because it uses a reserved query parameter name, which is
counter to URI namespace best practices, per "Architecture of the
World Wide Web, Volume One" [W3C.REC-webarch-20041215].
So you should also be aware that the Resource Server (or API) may not even support this method of token passing. The only method that is mandatory to implement is the Authorization header method.

You most certainly can.
Ses facebook graph API. But be aware that it is not recommended since users may sent these urls as email or messages. Oauth 2.0 spec writes about it.

Related

Can a HTTP GET request on REST web service be safe?

I'm currently working on a new REST Web Service, developed in Django REST Framework, and while defining URLs I had a doubt about it's security. Following the standards that defined GET method for list data from a database, I doesn't understand if this can be a safe method to bring data.
Imagine this situation:
I access an URL /patients defined to return a list of patients. This list is not public and can only be requested by authorized users. Since not all users can see all patients, I create an hash code that works as key, allowing to list patients for that specific user. If no hash code provide, the method returns an 403 forbiden.
It work something like this: /patients/HASHCODE
Since my hash code is request in the URL and not inside of the body of HTTP message, like it would be if done by POST method, this looks unsafe me. I know that SSL can hide some information of requests, but not about a GET request. And of course this hash should not be visible for no one.
Can I say this is a safe method to access my API? If not, how should I implement this?
First of all, you must use HTTPS, as it ensures that both body and headers will be encrypted. Pick a certificate issued by a certification authority and stay away from self-signed certificates.
If what you call hash means an access token, then it belongs to the Authorization header with the Bearer authentication scheme (refer to this answer for details). Alternatively, you may want to use a cookie with both HttpOnly and Secure flags set.
I also advise you to look into some sort of authorization mechanism for your application: according to the user roles or authorities, retrieve the data they can access or refuse the request. It's very likely your web framework already provides you some sort for authorization mechanism. Let me also highlight that you should't write your own security-related stuff (unless you really know what your are doing).
Any sort of sensitive information (such as credentials, access tokens, you name it) must never ever be sent in the URL: The requested URL may be logged by servers and proxies; If the URL is requested by a browser, the URL goes to the browser history. You surely want to avoid that.
GET is meant for data retrieval while POST is kinda a catch all verb, that is, the representation sent in the payload will be processed according to the resource's own specific semantics). If you need to send sensitive information to the server, I would advise you to use POST, sending any sensitive data in payload which will be encrypted over HTTPS.

How to prevent CSRF in API-Centric Web Application

I am looking to build a web application using API-Centric architecture.
The frontend of the application would make requests to the REST API using AJAX.
The API is also used by other clients for various purposes. I'm of the opinion that the use of CSRF tokens may not be applicable to their implementation.
Other approaches include verifying the origin in the headers, but of course, headers can easily be spoofed.
How could I implement a robust CSRF prevention strategy for this application?
Some proposition: First You can use api-url like GET api/gime-csrf which return CSRF token as response and also set it in http-only cookie (so JS has no access to it - but remember to block TRACE request in server to prevent XST attack). Then when you make some "save state" request like POST/PUT/PATCH - you just put CSRF in some request header - and in server you compare header token value with cookie token value.

What is the state parameter used for in Facebook's manual login flow?

In the fb developers docs for oauth authentication api - in the confirming identity section it has this note:
Note that you can also generate your own state parameter and use it with your login request to provide CSRF protection.
Can you help clarify what exactly is the meaning behind this? I mean how will I use a state parameter even if I generate one? Do I encode it as a part of the auth request url? What purpose will it serve even if I did that?
Do I encode it as a part of the auth request url?
Yes. It's also mentioned here in that document, as an optional URL-encoded parameter.
Whatever value you provide will be included in the URL of the redirect response that Facebook returns. It's a way, therefore, for you to pass some value through to your server.
What purpose will it serve even if I did that?
Since the value is simply passed between your app and the server, it's up to you to decide what, if anything, to do with it. The example mentioned is CSRF protection. By including a unique token as the state parameter you could ensure that the call to the server came from your app, rather than some malicious site.
(I don't think this is widely used, though, since the requirement to verify the authorization code or access token deals with most attack vectors.)
That's happens because the FBRLH_state session is not set.
<?php
session_start();
$_SESSION['FBRLH_state'] = $_GET['state'];
...

How to send a password in a GET request to access a REST resource

I have a REST service that is already secured with basic authentication using the Authorization header. This is used to access the service in general and is required for any request. i.e. "User1", "password1".
I have a "file" resource which can have an additional password associated with it (i.e a password protected Word document, PDF, etc), "docpassword". What is the best way to send sensitive information like this? I'm especially interested in how to send the password for a GET request, but I'd like to have a universal solution that will also work for POST requests.
Maybe a custom header?
The HTTP protocol defines the standard Authorization header for sending authentication data (credentials) to the server. This header is defined in the RFC 7235 (which makes the old RFC 2616 obsolete and updates the RFC 2617):
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.
Authorization = credentials
[...]
Please note that the name of this HTTP header is unfortunate because it carries authentication data instead of authorization. Anyways, this is the standard headers for sending credentials in the HTTP protocol.
Once you are already using the HTTP Basic Authentication Scheme to authenticate the users in your application, I believe you are already using the standard Authorization header.
I usually do not recommend custom headers, especially when the standard headers can be used instead, but your scenario seems not so common: You need to perform two authentications on the same request.
So, maybe a custom header such as X-Auth-Document or Document-Authentication with the document's password will be fine for GET requests. If you decide not using GET and decide using POST to access this resource, you can consider sending the document's password in the request paylod.
Anyways, don't forget using HTTPS: is highly advisable once you are sending sensitive data, such as credentials, over the wire. And HTTPS will protect you against the man-in-the-middle attack.
HTTP already has an authentication method, see for example this RFC: https://www.rfc-editor.org/rfc/rfc2617
Edit after clarification of question: There is nothing preventing the server to make additional challenges, even based on single resource basis. I must admit I did not implement such a thing yet, but each authorization can have its own realm. You could specify different realms, even down to document level if you really want to. The server then can potentially make multiple challenges in each realm (first login, then document). Remember, you can cache successful authentications, either on the client (for a realm, like a browser does), or giving out cookies with a cached token.
This would have the advantage of avoiding a custom header, and be completely HTTP/REST conform. There may be some performance disadvantage, but it could be mitigated with some targeted caching.
Of course you can go with custom header if you want to, but normally REST would imply that the client goes in with no prior knowledge other than mime-types and the HTTP protocol. A custom header implies out-of-band prior knowledge.

Tracking consumers for RESTful API (no auth)

Folks,
What is a simplest way to track consumer applications accessing RESTful API services inside department.
We do not restrict access - no authentication/authorization - open for invocation, trusted environment.
No tools like OAuth AuthZ servers or API management yet... but might be heading there at some point.
For now we thought to request consumers just to include some custom HTTP Header like X-Client-Id and log it on the server side for stats etc..
But knowing that in the future we might want to switch to more standard ways of doing things ... what would be best alternative to have to change less code in the future ?
Have the "clientId" in the Authorization: OAuth token (like access token)
Have JWT token in the Authorization header (looks too much - signing,base 64 etc for simple client id tracking ...)
Any ideas would be appreciated
We recently implemented this for one of our REST platforms and we used a combination of BOTH the points you mentioned, meaning Authorization header & JWT token. Although, JWT is ONLY for authentication and GETTING an access_token (oauth token) which is later used with calling actual resource apis. I will discuss how we handled this situation and you can decide on how you want to implement it.
1) Authentication
Client sends a JWT to your authentication service (/api/oauth2/auth). (If you want more reading on JWT, you can read here and here of how JWT is implemented by google and how you can use spring-security-jwt libary to handle all the signing and encrypting/decrypting). You get the "clientId" out of JWT after decrypting and verifying the signature and after server does all the authentication, you respond back with a 'refresh_token' and an 'access_token'. Server will save the access_token as well and map it to the clientId so that when client makes requests using access_token, you can know which client is making the request. The access_token expires in some time (ideally in an hour) and when it expires, the client uses the 'refresh_token' to get a new access token by posting refresh_token to some refresh token url (/api/oauth2/auth/token)
2) Authorization
Client takes the 'access_token' and uses the access token to make all the subsequent requests on all other apis (/api/*). Ideally, the access_token is sent as a part of the "Authorization" header. Server uses request filters (if you are using JAX-RS, you can use something like ContainerFilterRequest to add filters to specific url patterns and intercept them) to filter EACH request and parse out the Authorization header value. You will get the access_token from the header and from the access_token you can get the clientId that you mapped in step 1). You can do other authorization logic in the security filter and if everything goes through, you can use this information to LOG that clientId and the request that the client made.
This way you can kill 2 birds with one stone : Implement a security layer & log the information about customers (what calls they are making, how many time etc. etc.). In case you don't want to implement security filter just yet (as you mentioned it might be in the future), for now, the clients can just pass on the "clientId" (base64encoded or not, upto you) as a part of "Authorization" header. If all the calls are from a "trusted" network, it should be ok, although not as secure. This way, when you ACTUALLY implement a JWT and Oauth based security layer, all you have to do is change your ContainerFilterRequest logic to parse out access_token instead of client id (as mentioned in step # 2).
I hope this helps ! For more information on security filters you can have a look at this answer: Basic Authentication of a resource in Dropwizard. It says dropwizard, but it mostly talks about JAX-RS.
To implement full AuthN/AuthZ layer for consumer tracking would be an overkill for now.
We thought to use either to Authorzation header to pass custom client_id token:
Authorization: Custom <Client_Id>
or to use some limited version of JWT (no signatures as there no intent to validate them)
as access token
Authorization: JWT <JWT>
Where JWT could be:
{"alg":"none","typ":"JWT"}
{
"iss":"Client_ID",
"aud": REST Service URI,
"iat":1328550785
}
I do not see description of access_token format in the specification https://datatracker.ietf.org/doc/html/rfc6749#section-1.4
Are there any contraints to use JWT as access token?