Web API - Authentication credentials in the HTTP header vs body with SSL? - http

I'm sending username and password in the HTTP Body for authentication to each controller action in a Web API. I do the authentication in each controller using the username/password. It's using SSL.
Are there any security reasons why it's better to send the authentication credentials in the HTTP Header than in the HTTP body?
If I was using Basic Authentication I can see how having the credentials in the header are necessary as in this question but I'm not so I don't see the purpose. It seems just as secure in either as long as it's using SSL.

From an SSL perspective the security of the credentials in header (HTTP Basic auth) or body (e.g. form based logon) of an HTTP request is equal.
However if the client is a regular web browser you should consider the following:
Browsers cache the credentials used with HTTP basic authentication the users usually face the problem that for performing a log-out they would have to close their browser.
On the other side a form-based logon usually created a session cookie that is time restricted and can be deleted any time.

Related

Chrome ignores HTTP WWW-Authenticate realm

Our web application has user/password authentication. It runs on a web server which is secured itself with HTTP Basic Auth. This is just a temporary solution / workaround. The web application's authentication will be sufficient in future, but at the moment the web server Basic Auth prevents accessing the web application at all.
The web application returns status code 401 when not authenticated on application level. The WWW-Authenticate header defines a different realm, so the browser won't get confused between web server and web application authentication: If we didn't define a different realm the browser would throw away the web server credentials as soon as the application's 401 arrives.
So far so good. However our application has its own authentication dialog. For XHR requests we want to handle the 401 status on our own and need to prevent the browser's internal basic auth window. There is a simple trick for this: Just adjust authentication header (WWW-Authenticate) to use a custom auth method:
WWW-Authenticate: CustomBasic realm="myapp"
Whereby the web server returns:
WWW-Authenticate: Basic realm="webserver"
This works with Firefox but not with Chrome. Chrome ignores the realm when using CustomBasic and discards the credentials (user / password) for realm "webserver" as if we didn't define the realm "myapp" at all.
Do you know why? Do you know a solution with following requirements:
Keep 401 status for both realms
Do not show browser's basic auth window on application level (especially for XHR requests)
Yes I know we can simply workaround this by using different HTTP status codes on application level and handle them respecitvely. But if possible I want to keep the correct status codes 401. This could also be a valid use case, e.g. if you have two web applications accessible with two different URL paths on the same host.

Is the cookie dependent on the browser?

I'm a little confused about the cookie and I want to know can we use cookies somewhere other than the browser, like a mobile app or desktop app. Is the cookie dependent on the browser?
No, cookie is not dependent on browser.
Cookie is dependent on HTTP "User-Agent" -- the software/library client that is acting on behalf of a user, following HTTP protocol. Browser is just one type of it. Other types of "User-Agent" includes:
CLI software that can send HTTP request, such as curl or wget.
Library that can be imported in project and send HTTP request. Take Node.js project for example, they can be request or axios. All major programming language have its own HTTP client libraries.
Self-implemented HTTP client logic code.
more...
In a mobile app or desktop app, if HTTP is used for application, it is highly likely that cookie is used.
Any HTTP client can use cookies. A cookie is just a HTTP header sent by the server, with a value that is sent back to the server by the client in subsequent requests. Consult the documentation of your HTTP client to see if there is built-in support for remembering cookies.
Session Based Authentication
In the session based authentication, the server will create a session for the user after the user logs in. The session id is then stored on a cookie on the user’s browser. While the user stays logged in, the cookie would be sent along with every subsequent request. The server can then compare the session id stored on the cookie against the session information stored in the memory to verify user’s identity and sends response with the corresponding state!
Token Based Authentication
Many web applications use JSON Web Token (JWT) instead of sessions for authentication. In the token based application, the server creates JWT with a secret and sends the JWT to the client. The client stores the JWT (usually in local storage) and includes JWT in the header with every request. The server would then validate the JWT with every request from the client and sends response.
The biggest difference here is that the user’s state is not stored on the server, as the state is stored inside the token on the client side instead. Most of the modern web applications use JWT for authentication for reasons including scalability and mobile device authentication.
Scalability
Session based authentication: Because the sessions are stored in the server’s memory, scaling becomes an issue when there is a huge number of users using the system at once.
Token based authentication: There is no issue with scaling because token is stored on the client side.
Multiple Device
Session based authentication: Cookies normally work on a single domain or subdomains and they are normally disabled by browser if they work cross-domain (3rd party cookies). It poses issues when APIs are served from a different domain to mobile and web devices.
Token based authentication: There is no issue with cookies as the JWT is included in the request header.
Token Based Authentication: using JWT is the more recommended method in modern web apps. One drawback with JWT is that the size of JWT is much bigger comparing with the session id stored in cookie because JWT contains more user information. Care must be taken to ensure only the necessary information is included in JWT and sensitive information should be omitted to prevent XSS security attacks.

basic HTTP authentication on subsequent requests

The image below depicts basic HTTP authentication. The client requests /family resource and it is asked to identify itself. It does and now it can access the /family. The client then also asks for /family/photos/kids resource which is in the family realm.
The client already identified itself for /family resource, but not also for /family/photos/kids. They are in the same realm, but the server doesn't know that the same client issued a request. Or does it? How does the server know that this particular client is also allowed to access /family/photos/kids on subsequent request? Is the password and username send on every request after the user has authenticated? Is the client asked for via pop-up for every request he/she makes? Are cookies set upon first authentication?
Basic authentication requires a header sent by client. No cookies or server session
When the client requests a resource, sends the Authorization header
GET /family
Authorization: Basic token
Where token is base64(username: password). Username followed by ':' and password encoded in base 64
If you are requesting a protected resourced from your browser for example a GET request, and you do not provide the header, the browser shows the autenticathion form and remember it for subsequent requests in the same domain

Why is the HTTP header for Authentication called Authorization?

Let me quote HTTP 1.1 RFC specification from www.w3.org.
10.4.2 401 Unauthorized
The request requires user authentication. The response MUST include a
WWW-Authenticate header field (section 14.47) containing a challenge
applicable to the requested resource. The client MAY repeat the
request with a suitable Authorization header field (section 14.8).
14.8 Authorization
A user agent that wishes to authenticate itself with a server usually, but not necessarily, after receiving a 401
response does so by including an Authorization request-header field
with the request. The Authorization field value consists of
credentials containing the authentication information of the user
agent for the realm of the resource being requested.
Why the credentials intended to prove user identity (Authentication) passed in Authorization header?
You can see it like this. The server says to the client "Please authenticate before accessing this resource" and sends information on how the client should do the authentication (WWW-Authenticate). The client is responsible for authenticating and then sends proof of that authentication to the server (Authorization).
The Basic authentication scheme messes things up because the authorization is a username and password, that is, you authorize by authenticating against the server itself (showing you know a user and password).
Nevertheless other schemes allow the client to authenticate with a third-party and only send a proof of the authentication to the server. The server can verify the authorization and may not know who the client is (although it typically does).
Note This is only a rationalization. I don't mean to say this was the motive behind the chosen names.
One possibility is that it is talking about the authorization from the user's perspective, not the server's.
There are actually two authorizations going on:
The user authorizing the client to act on their behalf.
The server authorizing the user to access its resources.
If we assume the header is named after 1) then we have:
The user authorized the client to act on their behalf. That authorization goes in the Authorization header. The server then used the user's authorization of the client to authenticate the user (confirm the client is acting on behalf of the user). Now it knows who the user is, it will then do its own separate checks for 2), to see if the user is authorized to perform the request.

How can an API application be vulnerable to CSRF?

I have a Web API application and have configured SSL for it.
Our authentication mechanism is via the header. Each request will have to contain a pair of keys that we will validate them against our database. We're not using Forms/Basic or Digect authentication.
I'm just wondering do we have to do anything with regard to the Cross-Site Request Forgery (CSRF) issue? is it applicable in this case?
I thought because we're not using the cookies so it should be safe.
Indeed, forcing another user to do a request only has an advantage for an attacker if that user's browser automatically pushes some credential that the attacker does not have. That can be:
auth cookie
HTTP Authentication (Basic/Digest/Windows Auth)
TLS session ID (in HTTPS)
implicit authorisation from IP address or network location (eg intranet site)
If you are not relying on any such credential, then there is no CSRF attack to defend against.

Resources