React SignalR - Do not send bearer token in URL

Viewed 2018

I am writing an application which has just failed pen testing for the following:

Authorisation Token is being sent in the URL:

 https://domain/Hub?access_token=eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Imh1Tjk1SXZQZmVocTM0R3pCRFoxR1hHaXJuTSIsImtpZCI6Imh1Tjk1SXZQZmVocTM0R3pCRFoxR1hHaXJuTSJ9.....

This is happening automatically when sending to the Hub which uses Azure AD authorisation.

    constructor (hub: string) {
    this.hubName = hub;
    this.hub = new HubConnectionBuilder()
        .configureLogging(LogLevel.Critical)
        .withUrl(`${this.hubURL}${hub}` , {
            skipNegotiation: true,
            transport: HttpTransportType.WebSockets,
            accessTokenFactory: () => {
                return `${getToken()}`
            }
        })
        .build();
}

I've scoured for documentation, however I was wondering if there was a way to connect and send requests without exposing the bearer token within the URL?

1 Answers

From the documentation

When using WebSockets or Server-Sent Events, the browser client sends the access token in the query string. Receiving the access token via query string is generally secure as using the standard Authorization header. Always use HTTPS to ensure a secure end-to-end connection between the client and the server. Many web servers log the URL for each request, including the query string. Logging the URLs may log the access token. ASP.NET Core logs the URL for each request by default, which will include the query string. For example:

And from this documentation

In standard web APIs, bearer tokens are sent in an HTTP header. However, SignalR is unable to set these headers in browsers when using some transports. When using WebSockets and Server-Sent Events, the token is transmitted as a query string parameter.

Seems to me you could disable WebSockets and Server-Sent events. See this question on how to remove WebSockets or Server-Sent events. But then you fallback to long polling or forever frame, and you may not want that.

Since your URL in your question is https I wouldn't bother that much if you have disabled the request logging.

Changing the log level for Microsoft.AspNetCore.Hosting could be done in your appsettings.json

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore.Hosting": "Warning"
    }
  }
}
Related