Why connection token passed in the URL in Signal R? - asp.net

I got a website to handle all security issues raised by a software during Pen Testing. Please refer to the following screen shot:
jquery.signalR-2.4.1 is being used in the project (ASP.NET MVC). I need to give explanation to the security team about the use of above URL, why it is showing under a GET request. Is there any threat for the application? If yes how to remove the connection string from the query string inside the URL? If it's an inbuilt process or method what's the exact use?

It's a connection token, not a session/security token. This is documented in Microsoft's SignalR security section of the documents. I would refer your security team to this information as they are not aware of the difference here and how it is used. Especially the bolded portion below:
Here it is in case the link changes -
SignalR's connection token isn't an authentication token. It is used to confirm that the user making this request is the same one that created the connection. The connection token is necessary because ASP.NET SignalR allows connections to move between servers. The token associates the connection with a particular user but doesn't assert the identity of the user making the request. For a SignalR request to be properly authenticated, it must have some other token that asserts the identity of the user, such as a cookie or bearer token. However, the connection token itself makes no claim that the request was made by that user, only that the connection ID contained within the token is associated with that user.
Since the connection token provides no authentication claim of its own, it isn't considered a "session" or "authentication" token. Taking a given user's connection token and replaying it in a request authenticated as a different user (or an unauthenticated request) will fail, because the user identity of the request and the identity stored in the token won't match.

Related

AWS Cognito hosted UI returning id_token in URL

I am using AWS Cognito's hosted UI for user login. The id token is returned as part of the URL as described in https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pools-app-integration.html. Namely,
You can find the JSON web token (JWT) identity token after the #idtoken= parameter in the response. Here's a sample response from an implicit grant request. https://www.example.com/#id_token=123456789tokens123456789&expires_in=3600&token_type=Bearer
However, putting sensitive data in a query string is considered a bad practice (Is an HTTPS query string secure?). Does AWS Cognito support a more secure way of returning the id token?
Instead of token you can ask cognito to send you the Authorization code.
From Documentation:
The authorization code grant is the preferred method for authorizing end users. Instead of directly providing user pool tokens to an end user upon authentication, an authorization code is provided. This code is then sent to a custom application that can exchange it for the desired tokens. Because the tokens are never exposed directly to an end user, they are less likely to become compromised.
Source: https://aws.amazon.com/blogs/mobile/understanding-amazon-cognito-user-pool-oauth-2-0-grants/

OpenID connect - DO I need to verify the token at google at any request the user is making to my server?

I have requested a an accesstoken at google and would like to implement express middleware that verifies the token at any request the users are making to my server.
Should my server verify the token at google each time a user is making a request to my server? Or how should I go about verify the token?
Thanks
The token verification is standardized by the OAuth 2.0 Token Introspection RFC. It states:
The (introspection) response MAY be cached by the protected resource to improve performance and reduce load on the introspection endpoint, but at the cost of liveness of the information used by the protected resource to make authorization decisions. See Section 4 (of the RFC) for more information regarding the trade off when the response is cached.
So unless it's in Google's terms of use, you don't have to verify it on each request. In fact, the token could be revoked between the check and the end of your request. So if you use a cache with a sensible (rather short) lifetime, it could improve the performance with a little risk of accepting am already revoked token.
Google has a good article regarding authentication with a backend. I welcome you to go through it and understand its suggestions.
According to this document, there are client libraries provided by Google to validate the ID Token. Also there is the option to use tokeninfo endpoint.
Once validated, you can create a cache or persist validated data for future usage. But this depends on the exact requirement.
If you can maintain a context per validated token, then you can create a session to on top of token validation. This session musts have validity correlated to token validity. But if such session is not possible then you will require a token validation per request (indeed costly but required by context of usage).
In case you maintain a session, you can create endpoint to listen to Google security events, which allows you to remove persisted data based on security threats. This is highlighted in authentication with a backend article and can access through this link

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.

Authenticating with Web API

I am using ASP.NET WebAPI for a web service that I am building. He web service will use the Identity service to authenticate users.
I am a bit stuck as to how to authenticate users externally. Our current system is very basic- we send a username and password in the XML request as a separate field and it is all done in 1 request.
From what I can see from looking on Google, the best way is to request a token from the Ali and then pass this token in subsequent requests. Is there a way where I can do it all in 1 request (that is, send to the API my request for data as well as the username/password or perhaps an API key in a single request?)
From what I can see from looking on Google, the best way is to request
a token from the Ali and then pass this token in subsequent requests.
Is there a way where I can do it all in 1 request (that is, send to
the API my request for data as well as the username/password or
perhaps an API key in a single request?)
I'm not sure why your web service want to know user's username and password in Token based Authentication.
In Token based Authentication, your web service should not ask for user's username and password.
Instead, user first verifies the user name and password using a token issuer that your service trusts.
Upon successful verification, the token issuer provides the user with a token. Once the user has that token, it uses it to call your service.
For that, you do not have to reinvent the wheel. Here is JwtAuthForWebAPI nuget package for OAuth2 and OpenId Connect.
It is not secure at all to keep sending username/password with each request, you need to configure your api to issue access tokens for specified life time i.e. 24 hours. To do so you need create and end point (/token) which accepts the username/password validate the combination then issue an access token.
The client which receives this access token is responsible to store is securely and transmit it with each request to an any protected resource using the request "Authorization" header using bearer scheme.
As well you can not do this in one request, you need to obtain the access token at the beginning the you keep calling your protected resources using this access token until it is expired.
You can read more about this in my detailed blog post about Token Based Authentication in Web API

Create session oriented API's in asp.net Framework 4.0

I am working on a project where mobile apps connects to website through a set of API's. I considered creating API's using "Generic Handlers". This was seems to be working fine until restriction are defined for sensitive data. User has to be authenticated before he makes request for data.
I created a login API where user credentials are validated and a encrypted string which contains the same credentials which he provided at the time of login are returned back to the user after successful validation.
Each time a user makes request after successfull login, an encrypted string was supplied back to server in header. On server side, the encrypted data is decrypted and validated against with the credentials stored in DB. This step is unnecessary as user is recently authenticated. Is there anyway I can avoid authenticating user for each requests. I am planning to go with WCF services where Session can be effectively used to achieve the same (is this is something good idea?)
I did the same steps as you are doing for my API's. Here are some of the changes I made in the authentication part.
Client sends his credentials (username and password) to /api/login
Server validates the credentials and forms an encrypted string with identify of user and some necessary data like expiry date. Call this as token.
var tokenStr = "user_id=1234;expire_date=" + DateTime.Now.AddMinutes(20).ToString();
var encToken = AESCryptoService.Encrypt(salt, tokenStr);
Return this encrypted token to the client
Client sets this token in the HTTP header (X-App-Token) to make future API calls.
Server detects and decrypts this token. Here you can trust this token if decrypts with your salt. Get the user_id and set the current thread principal and proceed with the request.
If the token expires (read expire_date) then return 401 Authentication request, so that the client can request the token again.
You can also use SHA-1 or MD5 or some signing/encryption mechanism to make sure that the token string cannot be altered other than you.

Resources