Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible in ASP.NET to derive the browser MajorVersion from the HTTP request's user agent string alone?

We have an application which uses Request.Browser.MajorVersion as part of a cache key. We have a challenge to determine which cache key was used for a set of historic requests. To do this we're analysing IIS logs so need to determine what the value would have been for ASP.NET's Request.Browser.MajorVersion for each request. Is it possible to derive this from the user agent string alone?

UPDATE

I originally assumed the value of Request.Browser.MajorVersion would be the version taken direct from the user agent string. However, in a debug session to confirm this theory I see this:

Debug session screenshot

I would have expected Request.Browser.MajorVersion to be 61, not 44. Can anyone provide any insight into why these values differ, and how I might be able to confidently tell what the value of Request.Browser.MajorVersion would be for a given user agent string?

UPDATE 2

I have discovered that ASP.NET uses a set of templates to build the HttpBrowserCapabilities object set as Request.Browser. These are available here:

%SystemRoot%\Microsoft.NET\Framework[version]\Config\Browsers

Looking at the templates, they all use regex to parse the user agent string (I've pasted the contents of chrome.browser below), which suggests that Request.Browser.MajorVersion should correspond with the value in the user agent string. So still no idea why my local application is returning 44 as that value.

<browsers>
    <!-- Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US) AppleWebKit/530.1 (KHTML, like Gecko) Chrome/2.0.168.0 Safari/530.1 -->
    <browser id="Chrome" parentID="WebKit">
        <identification>
            <userAgent match="Chrome/(?'version'(?'major'\d+)(\.(?'minor'\d+)?)\w*)" />
        </identification>

        <capabilities>
          <capability name="browser"                         value="Chrome" />
          <capability name="majorversion"                    value="${major}" />
          <capability name="minorversion"                    value="${minor}" />
          <capability name="type"                            value="Chrome${major}" />
          <capability name="version"                         value="${version}" />
          <capability name="ecmascriptversion"               value="3.0" />
          <capability name="javascript"                      value="true" />
          <capability name="javascriptversion"               value="1.7" />
          <capability name="w3cdomversion"                   value="1.0" />
          <capability name="supportsAccesskeyAttribute"      value="true" />
          <capability name="tagwriter"                       value="System.Web.UI.HtmlTextWriter" />
          <capability name="cookies"                         value="true" />
          <capability name="frames"                          value="true" />
          <capability name="javaapplets"                     value="true" />
          <capability name="supportsCallback"                value="true" />
          <capability name="supportsDivNoWrap"               value="false" />
          <capability name="supportsFileUpload"              value="true" />
          <capability name="supportsMaintainScrollPositionOnPostback" value="true" />
          <capability name="supportsMultilineTextBoxDisplay" value="true" />
          <capability name="supportsXmlHttp"                 value="true" />
          <capability name="tables"                          value="true" />
        </capabilities>
    </browser>
</browsers>

UPDATE 3

I have finally got to the bottom of this. It turns out that the application I was debugging was using a third-party service called 51 Degrees which intercepts the request and applies its own parsing of the request header, in this case using a database installed locally on the application server. This database had become out of date and was therefore producing strange results for nmore recent browser versions. My details in Update 2 above are valid for vanilla ASP.NET applications, but this does explain why my results were diverging from a vanilla test environment. Thanks to everyone who spared the time to help me investigate this.

like image 681
Tom Troughton Avatar asked Oct 12 '17 11:10

Tom Troughton


People also ask

What is the browser user agent string?

A browser's User-Agent string (UA) helps identify which browser is being used, what version, and on which operating system. When feature detection APIs are not available, use the UA to customize behavior or content to specific browser versions.

Can user agent be spoofed?

The process is called user-agent spoofing. Yes, when a browser or any client sends a different user-agent HTTP header from what they are and fake it that is called spoofing.

Which field in an HTTP client header provides information about the user's OS and browser?

The HTTP headers User-Agent is a request header that allows a characteristic string that allows network protocol peers to identify the Operating System and Browser of the web-server. Your browser sends the user agent to every website you connect to.


1 Answers

Very challenging.

This page will tell you your agent string:

http://www.useragentstring.com/

This page will show you agent string for most browsers http://www.useragentstring.com/pages/useragentstring.php

Some browsers have a major/minor version in the agent string. Some do not. The format various between browser and even between browser version, so even if you know the major version exists in the agent string, parsing it out can still be specific to each browser/version.

If you really need to do this, you're better off finding a library that is kept up to date and well maintained.

like image 120
Jeremy Avatar answered Sep 19 '22 03:09

Jeremy