basic HTTP authentication on subsequent requests - http

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

Related

How does client send an authentication token back to the user in OpenID connect?

I'm learning about OpenID connect and OAuth2.0 and i think there is something missing, what the client will do after receiving the ID token from the authorization server?
Ok it now has a JWT that contains information about the user, but when the user wants to send a request to the client to do whatever he wants to do, he should attach a token with his request, right? so, when the client will generate this token? as far as i know, if a server uses HTTP as its protocol, it can't send data to the user if the user didn't issue a request, so it shouldn't be able to send that token without a request from the user.
Did i miss something?
I tried to search about this stuff, and I didn't find anything useful.
Ok it now has a JWT that contains information about the user, but when
the user wants to send a request to the client to do whatever he wants
to do, he should attach a token with his request, right?
Should say "but when the client wants to send a request to the server ..."
if a server uses HTTP as its protocol, it can't send data to the user
if the user didn't issue a request, so it shouldn't be able to send
that token without a request from the user.
The token will have been provided to the client during sign-on process.
To summarise the process:
Client enters credentials (e.g. username and password) and sends those to a login endpoint.
The login server will generate a JWT and return to client.
Client receives a JWT and caches it locally at the client end ready to be sent to the server on subsequent requests.
On all subsequent requests to the server the client will attach the cached JWT in the authorization headers of the http request.
The server will validate the token to ensure client is authenticated.

Anti-forgery token on each request from angular app

I have a website which supposed to be very secure as most of the activities are financial transactions. This site has a lot of security mechanism and I doubt one of that is not sufficient.
This web application is based on AngularJS 1.4 and ASP.NET MVC 4. After logging into the system using angular, I am calling a controller action to set Anti-forgery token. The all subsequent request has the same token and server validates the same on each request.
Now the problem.
Since we are not changing the token on each request, a logged in user can use the token from the request by merely looking in Fiddler or Chrome Network tab and try to request resources modifying the request.
Is it required to reset the token on each request? Will it help to prevent this kind of attacks?
The token is not meant to prevent the authorized user from crafting requests manually. The token ensures that someone else other than they user, cannot use a csrf request to forge a request from the user.
You can reuse the same token because if implemented properly, a potential CSRF attacker should not be able to read the value. This relies on the same origin policy of the browser to ensure the third party site cannot read or submit the same value.
If you had any kind of hole though, such as a json GET that returned a token(best practice is JSON returning data should still be submitted with a post) then the token could be compromised.
https://learn.microsoft.com/en-us/aspnet/web-api/overview/security/preventing-cross-site-request-forgery-csrf-attacks
Authorization
In regards to potentially fraudulent requests from the authenticated user
You need server side checks that ensure that he is only posting edits to accounts for which he has the authority to edit. For example, if I own account A, and I want to send money to account B, then the server side check will ensure that I own account A, and thus have authority to send its funds elsewhere. If I hand crafted a request to send funds from B to A, the server side check should see that I am not the owner of B by looking at the database relations of the account and owner. This is known as authorization. Authorization ensures that a user has the authority to perform an action. This is usually dictated by business rules that defines the relationships between tables that say who has access to what.
Authentication
The only other issue is ensuring that I am who I say I am, since if I just posted a user ID in the request, I could easily change that in the browser.
When the user proves he is who he says he is, usually by providing userid/password, then we generate an authentication token. In ASP.NET this token is cryptographically secure such that only the server has the necessary key information to generate and validate the token. Usually this token is persisted as a cookie.
The combination of authentication and authorization ensures we know who the user is, and on each request use our business rules defining authorization to check that the action is valid. It doesn't matter that he can hand craft invalid requests, as the requests will fail server side authorization.
Imagine this simplified server side code:
public void TransferFunds(TransferFundsRequest request)
{
var account = Database.GetAccount(request.SourceAccountId);
if(account.OwnerUserId != session.UserId)
{
throw UnauthorizedException("This user is not the owner of the source account in the transfer funds request.");
}
// continue with logic to transfer funds
}
CSRF
Cross site request forgery is an entirely different issue. This is when somehow another site loaded in the authorized user's browser tries to send a request from the user's browser. A malicious third party site that I visit uses javascript or other methods to cause my browser to make a TransferFunds request, from account A to account C. Now if I am owner of account A, from the perspective of the server that is a valid request. CSRF tokens ensure that we can detect that the user did not send the request from a form that our server generated, but instead some third party site's form or URL.
For example, if all the parameters of the request can be coded in a query string, I could craft a URL for the TransferFunds request and email it to the Account A owner and try to trick them into clicking the link. If the user happens to be logged into the site, then our server believes the user sent the request. However, if we include the anti-CSRF token when generating HTML input forms, then the absence of the token proves to us that the request came from a form or URL crafted by a third party.

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.

Auth cookie different domain issue

I am trying to implement SSO with a vendor, and they require I send a HTTP request. In this HTTP request, there is a custom header for username and password, which is where I pass in the u/p info. If the user is authenticated, then they send back an 'auth cookie'. I'm trying to understand a few things:
What exactly is this auth cookie? Is this a standard thing? or all it means is that its a cookie that has authentication information?
The HTTP request is sent to a domain which is different than mine. i.e., the script that sends the request is on a.com and the URL where I need to send the HTTP request is b.com. The vendor is saying that I am supposed to just 'send' the cookie they return in the response back to the user. This is not working, but I need to understand why - what will the domain of the cookie be? Will it be a.com or b.com? If its b.com, will that work, because the script that is actually making the call will be in a.com, and most browsers don't allow third-party domain cookie. Or is it failing because I am trying to write a cookie with a.com, where the cookie already has data for b.com?
Figured this out. The HTTP returned is just another custom header value, and not a cookie. So, we have to write our own cookie. However, obviously, the other domain doesn't recognise the cookie. So we actually build a reverse proxy in IIS, so that the domain a.com accesses the site through the proxy, called x.a.com, and never see b.com. So the cookie written is recognized by that domain.

Challenge for realm in HttpUnit

The HttpUnit API for webclient says that "Will only send the authorization header when challenged for the specified realm." What does challenged mean in this case? How does HttpUnit recognize a challenge?
This refers to the way HTTP Authentication works:
When accessing a protected URL (for the first time, with no credentials included in the request), the server will send back a response that has a status code of 401 Unauthorized and a WWW-Authenticate header set to something like Basic realm="My Realm". This indicates that Basic authentication is needed for the given URL and the realm is named 'My Realm'. This is the challenge - the user agent is being informed by the server that the URL it tried to access requires authentication and it should send back the user credentials. The user agent will typically prompt the user for credentials and then retry the request, this time with a Authorization header set to something like Basic rXflcjMwYXxz where the second part is the Base64 encoded username and password pair.
In case of the HttpUnit method you've linked to, you'll see that it requires a realm, username and password. I imagine that when the a URL is accessed, if it gets back a 401 (the challenge) from the server, it'll compare the realm you passed it with the realm in the response; if it matches, it'll attempt to authenticate with the username and password supplied.
References:
RFC entry for 401
Headers for authentication
Basic access authentication
When the server responds with a 401 error, the HttpUnit throws an AuthorizationRequiredException. We can use getParameter("realm") of the exception to get the realm and send a request again with this realm name.

Resources