Quantcast
Channel: IEInternals
Viewing all 63 articles
Browse latest View live

Debugging in IE10 on Windows 8

$
0
0

Emulating the “non-Desktop Experience” in the Desktop Experience

The new full-screen “fast and fluid” experience of IE10 on Windows 8 offers many improvements over Internet Explorer 10 on the Desktop (ranging from UX to Security), but one thing it lacks is the F12 Developer Tools, used by web developers to debug web pages.

While you can use Visual Studio to debug pages, sometimes, debugging with the lightweight F12 Developer Tools on the Desktop can be simpler. However, what if your bug doesn’t repro in the Desktop experience?

In many cases, you can emulate the non-Desktop experience on the Desktop by making simple configuration changes:

  1. Enable Enhanced Protected Mode by clicking Tools > Internet Options > Advanced and ticking the Enhanced Protected Mode checkbox in the Security section near the bottom of the list.
  2. Enable ActiveX Filtering (Tools > ActiveX Filtering)
  3. Press F11 to put the IE Window in full-screen mode

With these configuration changes in place, you can continue to use the F12 Developer Tools while emulating the non-Desktop experience.

Note that one limit to the quality of the emulation is that the ActiveX Filtering feature will filter out Adobe Flash content from all sites. Such content is permitted in the non-Desktop experience only when your site is on the CV List or the DebugDomain registry key is set.

Debugging Local Content

Web Developers often test pages or sites on their local systems before it is deployed to production. In some cases, there are side-effects to debugging local content that developers should be aware of.

  1. When debugging against a dotless hostname (e.g. http://localhost) the content will typically be in the Local Intranet zone. By default, this means:
  • Security settings (e.g. File download, ActiveX behavior, cookie controls, popup blocker) will be different.
  • The site will run outside of Protected Mode or Enhanced Protected Mode, which means that extensions will run with fewer restrictions and cookies and other storage will be “partitioned” from Internet Zone storage.
  • If the hostname is merely dotless and isn’t localhost, the page will run in Compatibility View by default
  • When debugging against 127.0.0.1 or any other hostname which points to the local computer but is not mapped to the Intranet zone:
    • Requests from "Windows 8 Apps” and IE running in Enhanced Protected will be blocked due to AppContainer Network Isolation
  • When debugging content loaded from a file:// URL, other restrictions include:
    • The content will typically be subject to the Local Machine Lockdown
    • The IE8/IE9 XMLHTTPRequest object is not able to send requests (fixed in IE10)
    • The IE8+ XDomainRequest object is not able to send requests
    • Storage with domain-based security policy (e.g., HTML5 Storage, IndexedDB) is disabled
    • If the content runs inside Enhanced Protected Mode, subdownloads may fail if they lack a Mark-of-the-Web.

    For scenario #1, you can disable the Local Intranet Zone by clicking Tools > Internet Options > Security > Local Intranet > Sites and unchecking all of the boxes. Of course, this will also mean that your content runs inside Enhanced Protected Mode, which can cause the problems listed in scenario #2.

    To help address scenario #2, Fiddler4 includes a tool called the EnableLoopback Utility which can be used even when Fiddler isn’t running. It’s simply a graphical version of the CheckNetIsolation.exe command line tool which is used to exempt specific AppContainers from loopback restrictions.

    If you’re having issues in scenario #3, you can consider using IIS Express or Fiddler’s AutoResponder tab to serve your local pages from a local web server.

    I hope that this post is useful. If you encounter any other “gotchas” or have other tips for local debugging, please sound off in the comments below!

    -Eric


    Understanding Zone Elevation

    $
    0
    0

    The security setting “Websites in less privileged web content zone can navigate into this zone”:

     image

    ... is one that leads to more questions than almost any other. This setting, also known as Zone Elevation protection, was originally designed to prevent navigation from untrusted Internet content into the highly-trusted Local Machine Zone. Prior to Internet Explorer 6 on Windows XP SP2, if an attacker could accomplish such a navigation and inject script into the LMZ, they had found a Remote Code Execution vulnerability and could take over the machine. This was a key source of vulnerabilities in that era, and the threat led to the introduction of Zone Elevation protection.

    The Zone Elevation protection feature blocks navigation, either outright (when set to Disable) or via a Prompt:

    image

    Regardless of your specific security configuration, for the purposes of Zone Elevation checks, the privilege precedence of Zones is: Local Machine > (Local Intranet == Trusted Sites) > Internet > Restricted Sites. There's a special-case exemption in the logic that allows Trusted Sites to navigate to Intranet sites, even though normally Intranet > Trusted. (One reason for that is that the user may configure an Intranet Site to be a Trusted Site. Most people expect this to increase the site's level of privilege, despite the fact that the opposite is what happens by default, since the Intranet runs at the Medium-Low Security Template while the Trusted Zone defaults to the Medium Security Template. To help match users' expectations, the Trusted Zone is often afforded special exemptions like this one.) 

    You can explore the Zone Elevation prompt's behavior by adjusting the setting for the Intranet zone to Prompt, then visiting this test page: http://webdbg.com/test/zoneelevation.htm. This page attempts to load a frame at http://localhost, and offers various navigation-triggering methods as well.

    In XP SP2, Zone Elevation protection was bolstered by the Local Machine Zone lockdown, such that Zone Elevation into the LMZ would be akin to “Breaking into Jail.” When an attacker Zone Elevates into the Local Machine Lockdown Zone, he ends up with fewer privileges, not more.

    However, even after the Local Machine Zone lockdown was introduced, Zone Elevation protection still has some value in that it can prevent Internet Zone content from navigating into Trusted or Intranet Zone content. As such, when set to Prompt or Disable, it serves as a protection against XSS and CSRF attacks against content in those Zones. Without this protection, an attacker with knowledge of your Trusted/Intranet sites and their vulnerabilities could potentially execute a cross-zone attack against those pages from an Internet site. This attack is non-trivial to pull off (since it is, by its very nature, a targeted attack), and it isn’t nearly as scary as a pre-XPSP2 attack against LMZ.

    By default, all Zones have their Zone Elevation setting set to Allow except the Local Machine and Restricted Zones, where it is set to Disable. That setting is meaningless for the Restricted Zone because there is no less trusted Zone. It’s set that way because Disable is the default for the High Security template which may be used by other zones. If a Zone’s security level is set to the Low template, then the Zone Elevation URLAction is set to Prompt because this high level of privilege allows download of signed ActiveX controls and one-click access to scripting ActiveX controls that are not marked safe-for-scripting.

    Configuring Zone Elevation to prompt or disable access to your Local Intranet and Trusted Sites zones can help protect against CSRF and XSS.

    In IE10 Metro Mode, the Private Network Isolation feature more effectively enforces protection of the “Intranet,” as it prevents circumvention of cross-Zone restrictions using the site’s IP address or otherwise causing IE to Zone a “private network” site into the Internet zone.

    -Eric

    Braindump: ActiveX in Windows 8

    $
    0
    0

    Note: The “brain dump” series is akin to what the support.microsoft.com team calls “Fast Publish” articles—namely, things that are published quickly, without the usual level of polish, triple-checking, etc. I expect that these posts will contain errors, but I also expect them to be mostly correct. I’m writing these up this way now because they’ve been in my “Important things to write about” queue for ~5 years. Alas, these topics are so broad and intricate that a proper treatment would take far more time than I have available at the moment.

    There are a few notable changes in Win8/Internet Explorer 10’s behavior when it comes to ActiveX controls.

    1. The non-Desktop mode of the browser (let’s call it IEPKaM for lack of a better name) only permits instantiation of controls that are considered to be a part of the web platform. The list of permitted objects is hardcoded into Internet Explorer and consists of:

    MSXML DOMDocument {F6D90F11-9C73-11D3-B32E-00C04F990BB4}
    MSXML FreeThreadedDOMDocument {F6D90F12-9C73-11D3-B32E-00C04F990BB4}
    MSXML XMLSchemaCache {373984C9-B845-449B-91E7-45AC83036ADE}
    MSXML XSLTemplate {2933BF94-7B36-11D2-B20E-00C04F983E60}
    MSXML XMLHTTP {F6D90F16-9C73-11D3-B32E-00C04F990BB4}
    MSXML DOMDocument30 {F5078F32-C551-11D3-89B9-0000F81FE221}
    MSXML FreeThreadedDOMDocument30 {F5078F33-C551-11D3-89B9-0000F81FE221}
    MSXML XMLSchemaCache30 {F5078F34-C551-11D3-89B9-0000F81FE221}
    MSXML XSLTemplate30 {F5078F36-C551-11D3-89B9-0000F81FE221}
    MSXML XMLHTTP30 {F5078F35-C551-11D3-89B9-0000F81FE221}
    MSXML DOMDocument60 {88D96A05-F192-11D4-A65F-0040963251E5}
    MSXML FreeThreadedDOMDocument60 {88D96A06-f192-11D4-A65F-0040963251E5}
    MSXML XMLSchemaCache60 {88D96A07-f192-11D4-A65F-0040963251E5}
    MSXML XSLTemplate60 {88D96A08-f192-11D4-A65F-0040963251E5}
    MSXML XMLHTTP60 {88D96A0A-f192-11D4-A65F-0040963251E5}
    XMLHTTPRequest {ED8C108E-4349-11D2-91A4-00C04F7969E8}
    DOMDocument {2933BF90-7B36-11D2-B20E-00C04F983E60}
    Scripting.Dictionary {EE09B103-97E0-11CF-978F-00A02463E06F}
    HtmlComponent {3050f4f8-98b5-11cf-BB82-00AA00BDCE0B}
    Scriptlet {AE24FDAE-03C6-11D1-8B76-0080C744F389}
    IE XMLDocument Not registered – used when hosting XML
    IE SVGDocument Not registered – used when hosting SVG
    IE XHTMLDocument Not registered - – used when hosting XHTML
    Adobe Flash {D27CDB6E-AE6D-11cf-96B8-444553540000}

    IEPKaM blocks other forms of extensibility outright: toolbars, BHOs, Pluggable Protocols, MIME Filters, and Namespace handlers will not load in IEPKaM.

    2. IEPKaM only permits use of Adobe Flash on sites that are listed in the IE Compatibility List or DebugDomain registry key.

    3. When enabled, IE’s ActiveX Filter permits use the controls listed above, except Adobe Flash, which is still filtered. This enhancement makes ActiveX Filtering far more palatable, as it doesn’t block use of legacy objects like the ActiveX version of the XMLHTTPRequest control.

    4. Windows RT devices like the Microsoft Surface cannot download or install ActiveX controls.

    1. Windows RT’s ActiveX restrictions are additionally backed by the OS loader, which will refuse to run code that hasn’t been signed with a particular code-signing certificate.
    2. Installed controls that are a part of Windows RT are permitted to run in the Desktop experience.
    3. In the IEPKaM experience, the list above is still consulted before a control is permitted to load.

    5. When the Enhanced Protected Mode feature is enabled, controls will not load unless they have been compiled for 64bit (when run on 64bit Windows). When running on Windows 8, there is the additional requirement that the controls are listed in the CATID_AppContainerCompatible component category, indicating that they have been tested to work properly within AppContainers.

    For instance, the controls must not expect to perform a non-brokered read of the local disk or registry; instead, such operations must be conducted on the control’s behalf by a registered broker object running at Medium Integrity. In some cases (like writing to a file), the IE Protected Mode APIs will suffice, but IE10 does not include any new Read brokers, so if your control hopes to read an arbitrary file from disk, you’ll need to write your own broker.

    6. IE10 enables Enhanced Memory Protections like ForceASLR, which opts all loaded modules into address space randomization, regardless of whether the /DynamicBase flag was set. You should continue to set this flag directly, but be aware that your control cannot take dependencies on fixed module load addresses even if you fail to do so.

    -Eric

    Braindump: DNS

    $
    0
    0

    Note: The “brain dump” series is akin to what the support.microsoft.com team calls “Fast Publish” articles—namely, things that are published quickly, without the usual level of polish, triple-checking, etc. I expect that these posts will contain errors, but I also expect them to be mostly correct. I’m writing these up this way now because they’ve been in my “Important things to write about” queue for ~5 years. Alas, these topics are so broad and intricate that a proper treatment would take far more time than I have available at the moment.

    When you navigate to a web address like www.bing.com/help in your browser, in most cases, the browser (or more specifically, WinINET, the network stack below IE) will immediately convert the hostname component of that URL (in this case, www.bing.com) into a numeric IP address like 165.254.26.34. It performs this magic by sending a query to a Domain Name System (DNS) server that then returns one or more address records for the target hostname. The browser then establishes a TCP/IP connection to the target IP and then uses HTTP (and/or SSL/TLS) to transfer web traffic over that connection.

    Address Lists

    Many people assume that a hostname will only return one target address, but in practice, it will often return several. For instance, on my PC, a DNS query for www.bing.com returns the following:

    2600:1409:1::6010:6119
    2600:1409:1::6010:6123
    165.254.26.34
    165.254.26.43

    The first two addresses are IPv6 addresses, while the latter two are IPv4 addresses. Prior to Windows 2000, Windows would randomly select one of the addresses and attempt to use it; after Windows 2000, the first returned address is always returned first. The change was made to support the idea that the DNS resolver will attempt to order the address list by placing “preferred” addresses first. For instance, the list might be sorted based on the resolver’s knowledge of locality or connection throughput to a given server.

    Windows Vista and later always sort the IPv6 addresses to the front of the list.

    DNS Failover

    While WinINET will attempt to connect to the first address, if that connection fails, that entry in the address list will be marked as “bad” and a connection will be attempted to the next returned address. This process repeats until a connection is made, the address list runs out of candidate addresses, or the retry count limit is reached (INTERNET_OPTION_CONNECT_RETRIES defaults to 5). If a connection is not made, the browser will show a “Page could not be displayed” error message.

    The linear process of failover can lead to performance problems, if a DNS returns many records which must be tried before a working address is reached. Each connection attempt could take as long as 21 seconds. The most common case where this problem occurs is when a server returns IPv6 addresses to a client that cannot successfully make IPv6 connections due to network configuration problems. A proposal (oddly named “Happy Eyeballs”) was made to address such problems by more quickly attempting to contact IPv4 addresses if IPv6 addresses are slow to resolve. As far as I understand it, Firefox and Chrome utilize a variant of this notion. You can read about how Windows 8 improved IPv6 resiliency and performance over on the B8 blog.

    Address List Caching

    For performance reasons, WinINET caches address lists using an in-process memory cache; this cache allows reuse of recently used addresses without resolving them again. DNS resolutions are also cached by Windows' DNS Resolver itself, but retrieving them from the Windows cache requires an RPC call, which, while much faster than issuing a DNS request on the wire, still takes some time.

    In Internet Explorer 9 and earlier, the per-process cache could hold up to 32 entries; in IE10 and later it holds up to 256 entries. The cache ignores any TTL (time-to-live) specified by the DNS server’s response. Instead each list is stored for 30 minutes by default; the DnsCacheTimeout registry key can be used to adjust this value. It has been speculated that the WinINET DNS cache was created to attempt to prevent DNS Rebinding attacks, but this is a fallacy—the cache exists for performance reasons only, and is trivial to circumvent as a part of a rebinding attack. (WinHTTP, another Windows HTTP stack used primarily by services, has different defaults; it caches up to 32 records for up to 5 minutes).

    What about proxies?

    If the client computer is behind a traditional (“CERN-style”) proxy server, WinINET skips the DNS lookup for the target site and instead sends the request to the proxy server, allowing the proxy server to perform the DNS lookup on the client’s behalf. This is useful in some cases, for instance, the case where the client computer doesn’t itself have access to a DNS server that is willing to return records for non-Intranet sites. Of course, the browser may still need to use DNS even in this case—if your browser is configured to send traffic to CORPPROXY:8080, it will need to use DNS to look up the address of CORPPROXY. It’s possible that the DNS lookup for the proxy will return more than one address; if it does, the same pattern described above is used to decide which address to use.

    However, in the unlikely even that you’re using a SOCKS-style proxy, WinINET must first perform the DNS lookup locally, sending that address information to the proxy server. That’s because IE only supports SOCKSv4, and the ability to rely upon the remote proxy to do DNS lookups wasn’t introduced until the SOCKSv4a protocol.

    -Eric Lawrence

    Braindump: Feature Control Keys and URLActions

    $
    0
    0

    Note: The “brain dump” series is akin to what the support.microsoft.com team calls “Fast Publish” articles—namely, things that are published quickly, without the usual level of polish, triple-checking, etc. I expect that these posts will contain errors, but I also expect them to be mostly correct. I’m writing these up this way now because they’ve been in my “Important things to write about” queue for ~5 years. Alas, these topics are so broad and intricate that a proper treatment would take far more time than I have available at the moment.

    I’m frankly amazed that I’ve made it to the end of an eight-year run on the IE team without having written a general blog about Feature Control Keys and URLActions. It’s time to rectify that oversight, with one day left on the clock before I move along. Both of these topics are covered at length on MSDN, but some of the philosophy behind how they came to be is lacking in the formal documentation.

    Feature Control Keys

    Feature Control Keys were formally introduced in the huge Windows XP Service Pack 2 update to Internet Explorer 6. XPSP2 massively tightened security for Internet Explorer, but the team faced a big problem—thousands of applications host the Web Browser Control and if the Internet Explorer lockdowns were applied to those applications, they could break, leading users to avoid installing XPSP2 and thus impeding the value of the security push entirely. On the other hand, if the team simply exempted all non-IE applications from the lockdowns, those other applications could be vulnerable to the same attacks forbidden in Internet Explorer, allowing attackers a means to compromise the system by going around Internet Explorer’s defenses into an unhardened Web Browser Control host (e.g. Windows Media Player, for one). In some cases, applications would want exactly the same protections as IE (e.g. 3rd party browsers built on the Web Browser Control, which included at that time Maxthon and Avant Browser). On the other hand, some applications would want none of the protections (e.g. Microsoft Money hosted the Web Browser Control, but only loaded fully-trusted content into it).

    Thus were born Feature Controls, a mechanism which allowed an application to opt-in or out to individual security defenses (and later compatibility modes) on a per-process basis. Feature Controls could be set in one of two ways: by manipulating keys in the registry, or by calling the CoInternetSetFeatureEnabled API within the running process. Only a limited number of Feature Controls (often abbreviated FCK for Feature Control Key) can be set via the API for two reasons: First, because some settings must be determined at process startup, before the caller could have called the API, and Second, because the API has generally not been updated to support the many dozens of FCKs introduced after the launch of XPSP2. As a consequence, in almost all cases, FCKs are set via the registry.

    You can see the complete list of public Feature Control Keys on MSDN. This list explains how to set the FCK for your process’ name, as well as listing what each FCK does and what its default is. Note: Internet Explorer internally may use some other FCKs that are not documented, but these are not a part of the public API, and can be subject to change in any monthly update.

    One significant shortcoming of the registry-based Feature Control Key system is that process names must be distinctive if you hope to apply different FCK settings across versions of the program. For instance, all versions of Microsoft Word are named WinWord.exe, which means that if you have side-by-side versions of Office 2010 and Office 15, the FCKs set for the last-installed version will overwrite whatever FCKs were applied to the previous version. This long-standing limitation is a bit of a hassle, but in practice not a big enough problem to warrant a change since 2003.

    Feature Control Keys are sometimes criticized for sometimes prioritizing compatibility over security for 3rd party applications; this seems non-intuitive to some. The apt metaphor I like to use is: “Sports cars go fast because of their brakes.” If sports cars didn’t have excellent brakes to complement their engines, drivers would be unable and unwilling to push them to their performance limits, because the inability to control the speed would be fatal. Similarly, if Internet Explorer adopted a “All security features must be enabled in all contexts at all times” stance, users would quickly stop installing patches in order to prevent the compatibility fallout of such a stance. As a result, enhanced security features would bizarrely result in users becoming less secure.

    URLActions

    Feature Control keys are applied on a per-process basis, which isn’t sufficiently granular for many needs. Some privileges (e.g. the ability to download ActiveX controls or spawn popup windows) can be safe in a trusted context (e.g. an Intranet site) and unsafe in an untrusted context (Internet pages).

    Internet Explorer’s Zone-based security architecture is comprised of two parts:

    1. A set of rules that map content into one of the five security zones, and
    2. A set of security policy settings for each zone that control the privileges (called URLActions) granted to that Zone.

    There are nearly 100 URLActions in the browser today, and a half dozen or more are added in each new version. Most of them can be viewed by opening Internet Explorer and clicking Tools > Internet Options > Security, picking a Zone, and clicking the Custom Level… button. However, some “headless” URLActions are not displayed in the UI and can only be controlled programmatically or via the registry.

    Internet Explorer (and other programs) determine what privileges should be granted to content by calling the ProcessURLAction API on the IInternetSecurityManager for the process. Applications hosting a Web Browser Control can supply their own security manager for the control to use (using the IServiceProvider’s ProfferService API) but most simply rely on the default security manager. The default security manager gets its settings from four registry nodes: the HKLM and HKCU nodes under \SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings\Zones, and the associated policy keys.

    Aaron Margosis’ excellent Zone Analyzer tool allows you to view your default URLAction settings, including determining the “effective” settings which result from the precedence rules for the four registry nodes.

    Working Together

    The URLAction architecture predates Feature Control keys, but some security features are controlled using both mechanisms.

    For instance, FEATURE_ZONE_ELEVATION controls whether a given process is opted into Zone Elevation Restrictions. If and only if a process has these restrictions enabled does a cross-Zone navigation then consult the target site’s URLACTION_FEATURE_ZONE_ELEVATION setting to determine whether the cross-Zone navigation should be permitted. If the FCK is Disabled, or if it is Enabled and the target zone’s URLAction is Allow, then the navigation is permitted.

     

    This was just a quick summary of these two important subsystems, but I hope you find it useful anyway!

     

    -Eric Lawrence

    Understanding Web Proxy Configuration

    $
    0
    0

    Over the last decade, I’ve come to learn a lot about web proxies, having chosen to implement my web debugger as a proxy. In today’s post, I’ll provide an overview of proxy-related information, including information on changes in Internet Explorer 11 / Windows 8.1.

    The “System Proxy”

    Unlike on other systems like Mac OSX, Windows doesn’t really have the concept of a “system” proxy. Most applications respect the WinINET proxy setting, but a few do not.

    • Firefox respects the WinINET setting only when configured to “Use System Proxy Settings” in its Network configuration.
    • WinHTTP-based applications may or may not respect the WinINET setting (see below).
    • Applications built on the .NET Framework typically will adopt the system proxy only when they start (and do not detect changes at runtime). Also, the proxy settings can be overridden by the app.exe.config or machine.config files.

    Historically, most applications were built on WinINET and thus respected its proxy settings directly, but today more and more applications are built on WinHTTP (or a descendent architecture like BITS) and System.NET and thus may require additional configuration.

    Settings are Per-User

    WinINET proxy settings are typically per-user rather than per-machine. This means that individual (even non-admin) users can set their own proxy settings without impacting the proxy settings of other user-accounts. WinINET can be configured to apply proxy changes on a machine-wide basis by creating a registry DWORD named HKLM\SOFTWARE\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\ProxySettingsPerUser with value 0. Subsequently, changes to the proxy settings can only be made by elevated applications running with Administrative permissions.

    Configuring the Proxy

    The WinINET proxy setting can be configured in Internet Explorer by clicking Tools > Internet Options > Connections. On the connections tab, select a Connection and click the Settings button. For most users, the proxy is configured by pressing the LAN Settings button at the bottom of the dialog:

    image

    Settings Precedence: Part 1: While the proxy settings for the Dialup/VPN/RAS connection and the LAN settings button can be configured independently, internally WinINET will use the settings from any active/connected dialup/VPN/RAS Connection. Otherwise, the proxy setting specified in LAN settings is used. Many users incorrectly expect WinINET to first determine which network interface is used to establish a given connection before selecting a proxy; it doesn’t work like this.

    Proxy Configurations

    When you configure your proxy settings, you’re presented with the following dialog box:

    image

    Settings Precedence: Part 2: The settings in this dialog box are presented in the order of their precedence. First, the Automatically detect settings option is consulted, next the automatic configuration script option is evaluated. If neither of those options is enabled or neither specifies a proxy to use, only then are the fixedproxy server settings consulted.

    Automatically Detect Settings

    When Automatically Detect Settings is enabled, Internet Explorer performs a process called Web Proxy Auto-Detection (WPAD). This process consists of two phases:

    1. Issuing a DHCP INFORM query, asking DHCP to provide the URL of a proxy script
    2. Searching for a server in the current domain prefixed with WPAD (e.g. wpad.corp.contoso.com)

    These operations may or may not be performed in parallel, depending on the network stack. Some browsers (e.g. Firefox) only undertake DNS detection and skip DHCP detection. For performance reasons, some clients may cache the result of the detection on a per-network basis ("SmartWPAD"), skipping the WPAD process in future sessions when connected to networks known not to be using WPAD.

    If the client is able to automatically detect a proxy script's URL, it will then attempt to download and use that proxy configuration script.

    Automatic Configuration Script

    The user may also directly specify the URL of a proxy configuration script using the second checkbox in the dialog. The URL field below points directly at the target script (e.g. http://proxy.contoso.com/proxy.pac).

    Proxy configuration scripts, whether discovered via WPAD, or manually specified by the user, are JavaScript files that expose at least one function FindProxyForURL(url, host). This function is called by the browser each time that it needs to decide where to send a given request. It returns a string which is either:

    1. "DIRECT" indicating that the request should bypass the proxy
    2. "PROXY PrimaryProxy:8080; BackupProxy:81" indicating that the request should be forwarded to the proxy PrimaryProxy on port 8080, unless that server is unreachable in which case the request should be sent to BackupProxy on port 81.

    WinINET also offers support for another function FindProxyForURLEx, an extension which supports IPv6-aware proxy scripts.

    NOTE: Proxy Scripts Impact the Zone

    Warning: One sometimes surprising aspect of proxy scripts is that they impact the Internet Explorer Security Zone determination. To summarize my long MSDN article and blog post, by default, if a proxy script is in use and returns DIRECT, the target site will be mapped to the Local Intranet Zone.

     

    NOTE: File://-based Proxy Scripts Deprecated

    In IE11, the WinINET team has made some changes to attempt to improve interoperability of proxy scripts.

    image

    Internet Explorer 10 and other WinINET-based clients would use the specified proxy script. However, WindowsUpdate and any other application built on a WinHTTP-based network stack would silently ignore the specified proxy script because WinHTTP has never supported the use of the file:// protocol as the origin of a proxy configuration script. Note: In November 2012, the .NET Framework was changed to use WinHTTP for PAC processing, which means that, by default, .NET Applications will not support file://-based proxy scripts any longer either.

    In Internet Explorer 11, the WinINET team has disabled WinINET’s support for file:// based scripts to promote interoperability across network stacks. Corporations are advised to instead host their proxy configuration scripts on a HTTP or HTTPS server. As a temporary workaround, this block can be removed by setting the following registry key:

    Key:   HKLM\SOFTWARE\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\
    Value: EnableLegacyAutoProxyFeatures
    Type:  REG_DWORD
    Data:  1

    Keep in mind that this should only be a temporary measure, as this block was introduced for good reasons, and removing the block won’t magically fix your WinHTTP-based applications.

     

    NOTE: File://-based Proxy Scripts Require “Unhealthy” Syntax

    While you shouldn’t use a file://-based proxy script, if you do so, IE requires that you use the legacy “unhealthy syntax” for file URIs in the proxy configuration dialog.

    As you can see, the “Healthy” syntax is incorrectly parsed as a relative URL.

    image

    The legacy “unhealthy” syntax works properly:

    image

    But, to reiterate, don’t use file:// to host your proxy script.

    NOTE: IE11 Deprecates Non-Silent Auth when downloading Proxy Script

    When downloading a proxy configuration script, it’s possible that the server will demand credentials from the client application. A problem arises if the server requests credentials using HTTP BASIC or HTTP DIGEST authentication, as these authentication methods require that the user respond to a credential prompt dialog box. (In contrast, NTLM and Negotiate authenticate silently).

    Many applications cannot handle showing prompts as a part of this workflow and will fail silently. To promote interoperability, IE11 also blocks the use of Proxy Configuration scripts that require authentication. As a temporary workaround, this block can be removed by setting the following registry key:

    Key:   HKLM\SOFTWARE\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\
    Value: EnableLegacyAutoProxyFeatures
    Type:  REG_DWORD
    Data:  1

    Keep in mind that this should only be a temporary measure, as this block was introduced for good reasons, and removing the block won’t magically fix applications which cannot show UI prompts.

    Generally speaking, you should attempt to migrate away from BASIC/DIGEST authentication both for access to the proxy script and for access to use the proxy itself. As I’ve noted previously, Manual Proxy-Authentication breaks many applications.

     

    Fixed Proxy Configuration

    Beyond automatic proxy detection, the user may manually configure “fixed” proxies. By default, the simple UI is shown:

    image

    …but clicking the Advanced button shows more options:

     

    image

    You can either specify a different proxy server/port for each protocol, or you may use the default option which applies the same proxy server to all protocols.

    The Exceptions box allows you to specify what hostnames are configured to bypass the proxy. Beyond hostnames, it supports two special tokens:

    • <local>– Matches “plain” hostnames (with no embedded dots)
    • <-loopback>– Unmatches localhost, 127.0.0.1 and other “loopback” addresses.
      • WinINET defaults to automatically bypassing the proxy for loopback addresses; this token disables that behavior.
      • This token impacts WinINET and current versions of WinHTTP; the .NET Framework simply ignores it.

    Note that Internet Explorer only supports SOCKSv4.

     

    Setting the Proxy Programmatically 

    Fiddler and some other applications attempt to programmatically adjust the WinINET proxy setting. Rather than attempting to “poke” the registry directly, the proper way to update the proxy setting is to use the InternetSetOption API.

    Using the API is straightforward, whether you’re using C/C++ or .NET.

    IE10+ Regression on System Shutdown

    As a part of Internet Explorer 10, proxy configuration was centralized in an existing system service (still labeled “WinHTTP Web Proxy Auto-Discovery Service”) so that proxy configuration code no longer needs to run in every process using WinINET (e.g. each IE tab is in its own process).

    Unfortunately, as a part of this update, a regression was inadvertently introduced. Code that attempts to change the WinINET proxy setting during a system shutdown (like Fiddler’s shutdown code, for instance) will find that the APIs return success, but upon restart you will see that the proxy settings change was discarded. No fix for this issue (also present in IE11) is yet available. A possible workaround for this problem would be to create an out-of-proc COM server and run a method (DllHostKeepAlive) that doesn’t return until the client calls a shutdown method (CancelDllHostKeepAlive). This would open a DLLHost that can be used to adjust the proxy settings during shutdown.

    CONNECT Bug: https://connect.microsoft.com/IE/feedback/details/838086/internet-explorer-10-11-wininet-api-drops-proxy-change-events-during-system-shutdown

    WinHTTP Considerations

    Thanks to Eric Loewenthal, owner of WinHTTP's proxy code, for providing the expertise for this section

    The WinHTTP stack was designed for use in services and other contexts where WinINET would be inappropriate (e.g. because WinINET may show UI or not scale well for unattended use). WinHTTP offers a limited subset of proxy support-- generally speaking, the calling code is expected to set the proxy configuration settings directly on the session or request objects. The user may attempt to configure the "default" proxy for WinHTTP using the proxycfg.exe (XP) or netsh.exe (Vista+) tools, but these tools only support fixed proxy settings (not autodetection or PAC script URLs) and WinHTTP-based applications may or may not use those settings.

    The configuration tools were primarily intended or WinHTTP apps that are running as System (without a user to impersonate). 

    Well-written WinHTTP apps will:

    1. If not running in a user's process, impersonate a user
    2. Call WinHttpGetIEProxyConfigForCurrentUser
    3. Plug the returned settings into WinHttpGetProxyForUrl

    Sample code for this technique can be downloaded from MSDN. 

    Note: WinHTTP will not process a proxy script if the Content-Type response header is not "application/x-ns-proxy-autoconfig" or the URL's file extension is not one of .js, .pac, or .dat. Also, remember that WinHTTP will not use proxy script files from file:// URLs, on any version of Windows.

     

    There’s still quite a bit more to say about proxies. I’ll update this post as time permits and questions arise.

    thanks!

    -Eric

    Strict P3P Validation

    $
    0
    0

    Internet Explorer offers users many tools to help protect their privacy, including InPrivate Browsing, cookie controls (including P3P), and Tracking Protection Lists. In February of 2012, the IE team described how a misleading P3P statement was being used to circumvent users’ privacy settings.

    Default P3P Restrictions

    Internet Explorer’s default settings restrict the use of 3rd party cookies that can be used to track visitors across multiple unrelated sites, as described in the UI text on the Privacy tab:

    clip_image001

    Users may easily adjust the slider to configure the browser with a more or less restrictive policy, or even specify much more granular restrictions using a P3P XML file, as described in my earlier post.

    Circumvention

    Unfortunately, a small number of websites (like YouTube and Facebook) circumvent P3P settings by sending a P3P statement that consists of only undefined tokens, like this one:

    P3P: CP="This is not a P3P policy! See //support.google.com/accounts/bin/answer.py?answer=151657&hl=en-US for more info."

    Browsers compliant with P3P interpret this policy as indicating that associated cookies won’t be used for any tracking purpose (or any purpose at all, since all tokens are undefined). By sending this text, the site bypasses P3P restrictions and enables its cookies to be stored and sent back to its servers when you visit any other site that embeds content (e.g. a “Like” button or an advertisement) from the original site.

    The fact that a site can circumvent P3P via technical deception was well-understood even as the P3P standard was being authored. In his 1999 book, Weaving the Web, Sir Tim Berners-Lee observed:

    Of course, any privacy negotiation is only as trustworthy as the site’s proprietor. However, if a company has, through its Web server, made an undertaking to preserve privacy, and broken that undertaking, then it has acted fraudulently. There are conventional laws to deal with this transgression. Software can't solve this problem. And it should not be up to the consortium or any other technical body to solve it. (page 148)

    While his remarks remain relevant today, IE10 and IE11 expose an option to more skeptically scrutinize a site’s P3P declaration, rejecting any policy containing undefined tokens. An Enable Strict P3P Validation checkbox can be found in the Security section of the Advanced tab in the Internet Options control panel.

    clip_image002

    When this option is enabled, any P3P Compact Policy declaration will be rejected if it contains any invalid tokens. As a consequence, any accompanying cookies will Denied when set from a 3rd party context, and Leashed or Downgraded if set from a 1st party context.

    Try It Out

    You can try out this behavior using a simple test page. In Internet Explorer’s default privacy configuration (Medium slider setting, non-Strict validation), Internet Explorer blocks the first two 3rd party cookies, since both were sent with no P3P information at all. The browser accepts the next two 3rd party cookies because their P3P statement promises that the cookies aren’t used for tracking. However, the browser in its default configuration also accepts the final two 3rd party cookies, which were set with a P3P statement that contains undefined tokens:

    clip_image003

    After opting-in to Strict P3P Validation, IE rejects any 3rd party cookies that were set with a bogus P3P declaration:

    clip_image004

    Guidance

    Web Developers
    Please ensure that when setting cookies, your site expresses its privacy practices using P3P. You can use the IE Developer Tools’ F12 Network tab to view individual responses’ P3P headers, or you can add P3P/Cookie information to the default display in Fiddler:

    image

    You should work with your site’s legal team or Chief Privacy Officer to ensure that your P3P declaration properly represents your use of any data associated with the cookie.

    Users
    Enable the new Strict P3P Validation option to prevent sites from providing certain types of misleading privacy statements. You may also explicitly block or allow any site’s ability to set cookies using the Internet Options control panel’s Privacy tab, and you can use a Tracking Protection List to block requests to sites whose privacy practices do not meet your expectations.

    Comparison to Other Browsers

    Today, no other mainstream browser supports P3P. The Safari browser claims to reject 3rd-party cookies, and Firefox has an active workitem which was originally designed to match Safari's behavior (more complex now). However, it is important to recognize that the blocking in Safari (and that was planned for Firefox) blocks only setting of cookies from a 3rd party context and does not block sending of cookies to a third party context. This means that you're protected from trackers hosted on sites you'd never directly visit (e.g. an advertising network) but not from trackers on sites you do visit directly (e.g. a social network).

    In Safari, cookies from any site you directly visit (e.g. YouTube, Facebook, etc) are returned to those sites anytime their content is embedded in any other site. This transmission of cookies to a 3rd party context is the mechanism by which your social network advertises to you products that you've recently looked at on shopping sites that had embedded "like" buttons from the social network, even if you use a browser that claims to block 3rd party cookies. Such tracking is blocked today in IE10+ when the Strict P3P Validation option is enabled.

    -Eric Lawrence
    2013 MVP – Internet Explorer

    Why do Tab buttons resize temporarily?

    $
    0
    0

    Have you ever noticed that when you close a tab in IE using the tab’s red-X button (or middle-click):

    image

    …the tab to the left gets wider (or narrower)?

    image

    If you then move your mouse, then the tab button size goes back to normal:

    image

    This is probably the most commonly reported “bug” that’s not a bug in the IE UI.

    So why does IE do this?

    The  tab button resizes so that if you’re trying to close multiple tabs, you don’t need to move the mouse. You can just click, click, click to close multiple adjacent tabs. The resizing of the tab to the left ensures that the hovered tab’s red-X remains underneath your pointer.

    As soon as you move the mouse out of the tab bar, the resized tab returns to its normal size.

    -Eric


    What I’d like to see in IE12

    $
    0
    0

    As the holidays approach, I’ve decided to publish my “wishlist” for the next version of Internet Explorer. I’ve been pretty good this year, so hopefully the IE team will deliver some of these presents. :-)

    Please remember: I’m just an MVP, and I don’t have any magic powers that would guarantee that any of my wishes come true.

    Update: In April 2014, the IE team launched http://status.modern.ie, which provides an overview of IE feature support including a roadmap for new feature implementation. You can add suggestions and vote on them using the WebPlatform UserVoice and the Browser Interface UserVoice.

    New Feature Support

    1. HSTS: HTTP Strict-Transport-Security is a relatively simple feature that allows a site to demand that all accesses take place over a secure (HTTPS) connection, with no certificate errors. This feature can be weakly emulated by pinning a site in IE8 or later, but that requires user-interaction and doesn’t cover all scenarios. All major competitive browsers now support this feature. Update: In Development

    2. Support HTTP2.0 on Windows 7. Support for this newer/faster replacement for the aging HTTP/1.1 protocol was brought to Windows 8.1 with IE11 but IE 11 users on Windows 7 were left out, presumably due to the platform dependencies required to support the new protocol (e.g. it requires changes in SChannel to allow NPN/ALPN extensions in the TLS handshake).

    For bonus points, I’d love to see a way for .NET applications to be able to negotiate SPDY/HTTP2 connections (even if it requires a native PInvoke) as this would dramatically simplify adding support for these protocols to Fiddler.

    3. Server-Sent-Events. SSE allows JavaScript to very simply collect and process a stream of messages from a server. The unidirectional stream is simpler than WebSockets and the programming model is convenient for JavaScript programmers. This feature overlaps others (e.g. XHR with streaming, WebSockets) and thus is just syntactic sugar, but it’s oh-so-tasty syntactic sugar. Update: Under consideration

    4. Developer Tools Support for P3P. Today, IE is the only browser that supports the P3P privacy-protection standard, and as a consequence web developers often encounter problems with it. Today, IE's developer tools do not warn the developer if their cookies are being impacted by P3P and thus they often assume that IE is somehow “broken” when it is behaving as designed. Note: It would actually be great to see this for ALL security features; for instance, F12 could help debug problems where sites have been blocked by X-Frame-Options. Update: P3P Appears to be gone entirely in Windows 10 Preview

    5. Native Dictionary. IE added spell-checking in version 10, but the Kindle and Mac browsers have gotten me addicted to being able to quickly get a definition for any word on a webpage. The legacy Accelerators feature could have been a way to get this, but it requires configuration and is not nearly as seamless as the native feature in other products.

    6. Preserve-3d support. Basically everyone else supports this, and the workarounds for lack of support are awkward. Update: In Development, Shipped in Win10 Preview

    7. An off-by-default option to disable (or require confirmation) of the use of the backspace key as a back button. Some users hate this feature (there are many bugs on CONNECT) and even developers inside the IE team have complained that there's no way to turn this off. Tracked as UserVoice here.

    8. A UI option to enable warning the user if Certificate Revocation checks fail to complete. Today, incomplete checks are silent and this makes certificate revocation checks unsuitable for handling key-compromise revocations like the many thousands of revocations caused by HeartBleed. By default, IE should also downgrade any EV site which does not complete revocation checks by removing the green bar. Beyond exposing the "Warn on revocation incomplete" option in the UI, IE/SChannel should support the MustStaple flag for certificates.

    Bug Fixes

    1. When IE8 introduced the postMessage API, it had a bug whereby you could not use the API to communicate between browser windows. This bug is now over four years old and is an interoperability problem. It needs to be fixed.

    2. When IE8 introduced the localStorage API, it had a bug whereby you could not use the API to share data between browser sessions. This bug is now over four years old and should be fixed.

    3. Over the years, we thought we fixed most of the “Cannot SaveAs an image in its native format” bugs, and offered a “Save As PNG” option for the corner cases. Recently, an IE user discovered that the SaveAs code cannot handle URL fragments in the image URL and hits the fallback codepath unnecessarily. This should be an easy fix.

    4. A customer recently uncovered a bug whereby, if a server sends two instances of a cookie on a single response (one a session cookie and one a persistent cookie) it’s possible that both cookies will be immediately discarded (test case). This is clearly a corner case (servers shouldn’t be doing this and should be fixed) but this should be straightforward to fix.

    5. In IE10, we updated IE to behave like other browsers when following redirects when the original URL contained a fragment. However, a corner-case was missed and IE10/IE11 do not behave the same as other browsers when a chain of two or more redirects is processed and one of the redirects in the middle introduces a URL fragment.

    6. IE11 introduced a regression where users InPrivate can be unmasked. This is a regression from IE10 and should be fixed. Update: This was quietly fixed in a monthly update.

    7. IE10 introduced a regression where proxy settings changes are lost. This is very irritating for Fiddler users and impacts other customers too. Still repros in Windows 10 Preview.

    I suspect I’ll be adding to my wishlist over time. If you have succinct straightforward suggestions for additions, please sound off in the comments below!

    Update: Below, Chris Love makes an important point: IE team has an official feedback mechanism at connect.microsoft.com. Also, I'm not looking for a laundry list of "Here's a bunch of proposal/spec hyperlinks, Go!" The IE Engineers are aware of all of the popular sites (CanIUse, etc) and track virtually all of the public specifications. The point here is to provide feedback on the things that we think may have been overlooked, or which may be more important than they initially appear. The best suggestions explain why you think the feature in question is not only valuable, but more valuable than anything else with a similar development cost.

    -Eric

    PS: Perf Guru Steve Souders recently posted his Browser Perf Wishlist.

    “Continue” Link Missing from Certificate Error Page?

    $
    0
    0

    A user recently reported that IE11 wasn’t showing the “Continue” link on the certificate error page shown when visiting their 2009-era router’s configuration UI. They were curious why that link wasn’t shown in this instance.

    The error page’s Continue link is hidden:

    1. If the certificate is revoked
    2. If the certificate is deemed insecure (e.g. contains a 512-bit RSA key)
    3. If the page is in a “pinned site” instance
    4. If group policy is set to Prevent Ignoring Certificate Errors

    In this case, #2 is the most likely.

    Had the user provided a screenshot of the blocking page and the URL of the page (shown in right-click Properties, NOT the address bar) it would simplify troubleshooting of the issue. Similarly, providing the make/model of the router will allow contacting the vendor to request a firmware update.

    Here's what you see if the server sends a certificate with a 512-bit RSA key:

    image[1]

    Old IE versions (prior to IE10) omitted the line “The security certificate presented by this website is not secure” and included the “Continue” link although clicking it was non-functional. IE10 fixed those shortcomings. At the time that this page was designed, complaining about RSA key length specifically in the error page was deemed unlikely to help users, since they’re rarely able to change the certificate a site uses.

    Having said that, as a geek, I do like the page that Chrome shows:

    image[3]

    Firefox 26 doesn’t care or warn about the weak certificate. In contrast, if a certificate with a strong key is signed with a weak hash (e.g. MD5), IE doesn't complain, but both Firefox and Chrome will block access to the site.

    Testing Weak Keys

    You may be wondering how you can easily see how your software behaves with weak keys. Doing so is very easy with Fiddler and its plugin Certificate Generator. After installing the add-on and enabling HTTPS decryption in Fiddler, type prefs set fiddler.certmaker.bc.KeyLength 512in the black QuickExec box underneath the Web Sessions list. Hit Enter, and restart Fiddler. Subsequently, Fiddler will generate server certificates that use a 512 bit key. To later revert this configuration, either type about:config in the QuickExec box and remove the preference using the UI, or type prefs remove fiddler.certmaker.bc.KeyLength hit Enter, and restart Fiddler.

    -Eric

    Debugging Internet Explorer - A Beginner’s Guide

    $
    0
    0

    As a Program Manager on the IE team, I spent comparatively little time running Internet Explorer under the debugger. In contrast, the IE developers were far more adept at solving problems with advanced debugging techniques. Nevertheless, over the years I picked up a few tricks that proved useful from time-to-time. In this post, I outline some of the simpler ways to use WinDbg to get useful information about failures in IE.

    When your webpage’s scripts fail, your first step should be to hit F12 and go to the Script Debugging tab to see what went wrong. However, if IE itself crashes or hangs, the F12 Developer Tools probably can’t help you—you’ll need a native debugger. Native debuggers can be quite a bit more complicated to use than IE’s script debugger; even if you have IE’s source code, native code debugging is simply more complicated than script debugging. Also, unlike with a script bug, you’re unlikely to be able to fix IE itself (unless you find that the crash is due to a buggy browser extension, in which case you could update it or uninstall it).

    Debugging Internet Explorer can be somewhat more complicated than other programs because:

    • There are multiple processes involved. Typically, there’s at least one Frame/Manager process (which hosts the tabs and main window) and one or more Tab/Content processes (which host the HTML and script). This split is called Loosely-Coupled IE.
    • Internet Explorer is available in both 32bit and 64bit versions. In modern IE versions, the Frame process is 64bit and the Tab processes will be either 32bit or 64bit depending on the configuration.

    However, don’t despair—with the tips below, you can explore Internet Explorer under the debugger.

    Install WinDbg

    First, download the Debugging Tools for Windows. You’ll probably want to install the 64bit version as well as the 64bit version, unless you happen to be debugging on a 32bit version of Windows in which case you can simply install the 32bit version. Typically, I install the 64bit version to C:\dbg64\ and the 32bit version to c:\dbg32\

    Configure the Post-Mortem Debugger

    You can configure Windows to launch WinDbg whenever a process crashes by setting it as the post-mortem debugger.

    1. From an elevated 64bit instance of c:\windows\system32\cmd.exe, run c:\dbg64\WinDbg.exe -I to configure WinDbg as the default post-mortem debugger for 64bit process crashes.
    2. Then, from an elevated 32-bit instance of c:\windows\syswow64\cmd.exe, run c:\dbg32\WinDbg.exe –I to set the post-mortem debugger for 32bit processes.

    Note that the -I parameter must be in uppercase. When the command succeeds, WinDbg will show the following notice:

    image

    Manually Attaching

    Of course, you may want to attach the debugger to an existing or new browser instance that hasn’t crashed. To attach to an existing instance, launch WinDbg and click File> Attach to a Process and select the iexplore.exe instance of interest.

    Alternatively, you can start a new instance to debug by clicking File> Open Executable and selecting C:\Program Files\Internet Explorer\iexplore.exe. Be sure to check the Debug child processes also box at the bottom of the Open Executable screen, so that you attach to both the Frame/Manager process and the Tab/Content processes.

    Tip: To simplify things, before attaching, close all browser instances that are not being debugged.

    Symbols

    Debuggers aren’t much fun if they don’t have the “symbol” information which maps binary offsets back to functions. Unfortunately, you aren’t likely to have access to the “private symbols” available to the IE development team, but you can configure WinDbg to automatically download and cache the “public symbols” as follows:

    32bit debugger

    .sympath SRV*C:\dbg32\symbols*http://msdl.microsoft.com/download/symbols; .reload

    64bit debugger

    .sympath SRV*C:\dbg64\symbols*http://msdl.microsoft.com/download/symbols; .reload

    Next Steps

    When using the 64bit debugger to debug a 32bit process, you’ll find that all of the stacks are “mangled” with wow64 virtualization function calls. To fix them, first execute:

    .load wow64exts

    then

    .effmach x86

    After using these commands, WinDbg will helpfully show you the 32-bit process’ information without the virtualization goo.

    There are a huge number of commands you can use once you’re in the debugger, but here are a few of the most useful:

    !analyze -v
    Performs analysis of an exception (e.g. to attempt to determine the origin and nature of a pending access violation crash).

    !analyze -hang
    Performs analysis of an hang.

    !runaway
    Shows you the amount of time each thread has spent on the CPU.

    g
    Resumes execution of all threads when stopped at a breakpoint.     

    ~0kp
    Shows the stack trace and parameters to the functions on the stack for the thread number specified.

    ~*kp
    Shows the stack trace and parameters to the functions on the stack for all threads. This command can be very helpful if, for instance, you’ve broken into Internet Explorer while a dialog box is showing and you want to understand what led to that dialog box being shown.

    .dump /ma C:\tmp\out.dmp
    Creates a dump file that can be used to diagnose a failure later, or from a different machine. Sharing a dump file with a developer is a great way to help them quickly find the source of a problem.

    lm vm partialfilename*
    Shows  verbose information about the modules matching the specified search pattern.

    bu module!function
    Creates a breakpoint for the target function; the debugger will break on each hit to that function.

    .foreach(pid {|}){.if($spat("${pid}","[0-9]")|$spat("${pid}","[0-9][0-9]")){|${pid}s;bu mshtml!fnName}}
    Runs the specified command (in this case bu mshtml!fnName) in each process under debugging, not just the active one. This admittedly verbose syntax is useful when you would like to break whenever a specified function is hit by any process (Frame or Tab) currently loaded.

    Enhancing Failures with gFlags

    In some cases, you’ll find that crashes seem to occur randomly, inconsistently, or far from the code being exercised. In such cases, the problem is often that heap corruption has occurred. The failing code corrupts memory used in other codepaths, which (potentially much later in execution) crash when the trashed data is accessed.

    To help debug heap corruption issues, you can enable page heap for the target process. Page heap tags each heap request with additional metadata such that corruption is more likely to be discovered immediately—the process will halt with an exception at the point of the corruption.

    To enable page heap, use the gflags.exe tool that is included with the WinDbg installation.

    image

    Page heap has relatively little overhead in most situations, but scenarios which result in many small allocations can be impacted, so you’ll generally want this flag set only when debugging.

    Other tools

    If you’re trying to understand how IE interacts with the system, there are several powerful and useful tools to try:

    • Process Explorer– Shows all processes on the system, as well as what files and handles they own.
    • Process Monitor– Shows all registry and filesystem reads and writes. If you configure this tool using its Options> Configure Symbols menu (point to the symbol path you set up above), it can show the stack trace at the point of each call.
    • API Monitor– Shows all API calls made by the process.

    If you’re trying to see how IE interacts with the Network, the F12 Developer Tools’ tab offers a basic view, and you can use Fiddler to take a deeper look.

    Learning more…

    Recently, Microsoft’s Tarik Soulami wrote a great end-to-end guide to debugging on Windows; you can get Inside Windows Debugging from Amazon or local bookstores.Highly recommended.

    -Eric Lawrence

    “Everybody Lies”

    $
    0
    0

    Today we present EricLaw’s 2nd law of Software:If your software platform is sufficiently popular, and it offers a GetVersion API, that API probably lies.

    Recently, a user of Telerik’s automated web testing product (Test Studio) filed a bug noting that they’d recently upgraded their machines to IE11, but the test tool’s GUI claimed that agents would be running IE9. Looking closer, the test agent actually indicated that it would use a non-existent version, IE 9.11.

    How did that happen?

    The agent client software checked the machine’s registry to determine the current IE version. Following common and decades-old practice, the code simply looked at the Version subkey inside HKLM\Software\Microsoft\Internet Explorer. If you open RegEdit on a Windows 8.1 machine, the problem is immediately obvious:

    image

    As you can see, the Version key contains a bogus IE version: 9.11.9600.16476. On a Windows 8 machine running IE10, the Version key contains 9.10.9200.16384.

    So, the Version registry key lies. But why?

    The Version key has lied since IE10 because there’s a common and decades-old practice of looking in the registry to retrieve the IE version. Unfortunately, much of the code that does so is inside product installers that refuse to proceed if a minimal target IE version (e.g. 6+) isn’t found. And that crusty old code never imagined there would one day exist a world in which IE’s major version was more than a single digit long. As a consequence, when IE10+ is installed, many products would refuse to install and users would receive bizarre and inaccurate error messages (“Internet Explorer 6 is required. This system only has Internet Explorer 1.”).

    After examining the broad scope of the compatibility problem, the team decided to change the registry format such that the “true” IE version would be preceded by a leading “9.” to accommodate buggy version checkers. This approach generally worked well, but will confuse any software, like Test Studio, that was written prior to the version lie being introduced.

    This is only one of many version lies.

    User-Agent Lies

    The most notorious of the version lies can be found in the browser’s user-agent string. Consider the following simplistic application which hosts the Internet Explorer Web Browser control (WebOC):

    image

    The browser first claims to be “Mozilla/4.0”, a lie carried over from the mid-1990s when Netscape Navigator had overwhelming marketshare and every other browser needed to mimic it in order to have a chance of rendering important sites. Today, virtually all browsers claim to be a variant of Mozilla, although most modern browsers (Firefox, Chrome, IE11, etc) purport to be  “Mozilla/5.0”. By default, WebOC hosts run in IE7 Emulation mode, which is why you see both  “Mozilla/4.0” and “MSIE 7.0” in the string; the Trident/7.0 token reveals the control’s true nature. Only if the FEATURE_BROWSER_EMULATION feature control key is set for the WebOC’s host executable will the control default to a later emulation mode. Unlike IE itself, WebOCs do not use the downloaded Microsoft Compatibility View list (which can offer site-specific UA string lies for compatibility).

    The  “Windows NT 6.2” token is another interesting one—it lies in numerous ways. First, Windows hasn’t used the “NT” moniker since Windows 2000 was released. Next, my application is running on Windows 8.1, and yet the UA string claims that Windows is v6.2. That’s a lie stacked on top of a lie. With Windows Vista’s release, the Major version returned by GetVersionEx has been frozen at 6; Windows Vista was 6.0, Windows 7 was 6.1, Windows 8 was 6.2, and Windows 8.1 was 6.3. So, even considering the 6.x lie, you’d expect that my test application would be showing 6.3, but it’s not.

    That’s because GetVersionEx now directly lies to applications that call it when run on Windows 8.1; it only returns the 6.3 value if the application specifically indicates compatibility with 8.1 inside its manifest. To prevent applications from lying (and, say, claiming compatibility with Windows 9 before it exists), the manifest requires that callers list their supported operating systems using a GUID; each OS version’s GUID is only documented when the new OS version is reaches its public preview stages.

    Windows’ AppVerifier tool has long offered developers a means to test whether software is inappropriately limiting itself based on the Windows version; when the HighVersionLie test is enabled, the application being verified will receive a high (and fake) version number when calling GetVersionEx; in this case, Windows claims to be version 8.5.10600:

    image

    Unfortunately, not enough applications test with AppVerifier and many still inappropriately perform version checks. In Internet Explorer, we even found that some websites would fail; when Windows Vista was in development, for instance, the TurboTax website refused to load because it didn’t like the Windows NT 6.0 version token.

    API Lies

    Many other versioning APIs will also return bogus results for compatibility.

    For instance, when updating Fiddler to support the new SmartWPAD feature introduced in Internet Explorer 8, I figured I’d ask WinINET for its version information before using IE8’s new INTERNET_PER_CONN_FLAGS_UI flag (since this flag isn’t supported by earlier versions of WinINET).

    For this task, I expected I’d use simply call InternetQueryOption(INTERNET_OPTION_VERSION) and look at the resulting version. Unfortunately, as I soon discovered, this call’s return value was frozen at 1.2 in the mid-1990s. In talking to the developers, I learned that this value was also frozen due to compatibility concerns, where applications refused to run on later versions.

    To reliably use the INTERNET_PER_CONN_FLAGS_UI flag, you must simply check the return value of the InternetQueryOption call, and if it returns ERROR_INVALID_PARAMETER, retry the call without the flag.

    Random Lies and Failures to Lie

    You need only peruse this blog to find other cases where version information either already lies, or should do a better job of lying:

    • The SSL/TLS version communicated during a HTTPS handshake is a bit of a lie (e.g. TLS1.0 is advertised as SSLv3.1), but some servers still unexpectedly fail when they see a version number that they don’t expect, rather than simply using the latest protocol version they do support.
    • For years, the default guidance for Apache would result in disabling keep-alive for any IE version <5 and >9, as I described here.
    • The compatMode property is frozen at CSS1.

    Other Browsers

    Cynical observers everywhere might remark: “No, only Microsoft products lie,” but this is, of course, untrue.

    • Opera was the first browser to include a robust system of compatibility lies
      • With its small marketshare, it was forced to emulate many IE proprietary features so it would be detected as a supported browser
      • It was the first major browser to cross the two-digit version boundary; the User-Agent string remains frozen at Opera/9.8
      • It was the first major browser with a “Compat list” that was downloaded to the client with site-specific lies
    • Firefox’s User-Agent header contains several lies, including the frozen string Gecko/20100101 
    • Firefox’s extension model requires that extensions declare their minimum and maximum supported version; unlike the Windows versioning APIs, the numbers used are entirely predictable and nothing stops extensions declaring compatibility with some future version of the platform. Such lies became a necessity as the Firefox shipping cycle accelerated.
    • Chrome’s User-Agent string is designed to spoof Netscape, Firefox, Safari, and KHTML simultaneously. Having said that, Chrome has been generally successful in shipping new versions as such a frenetic pace that any site that attempts to target a specific Chrome version will likely be broken before the development team manages to push their bits to the server.

    Everybody lies. It’s usually for good reason, to accommodate someone else’s bad code. Please follow best practices like feature detection, and do your best to write future-proof code.

    Thanks!

    -Eric

    There’s never magic, but plenty of butterfly effects

    $
    0
    0

    I’ve always enjoyed magic shows, but I’ve never attempted to understand how the tricks are performed, since that would take all of the fun out of them. In contrast, if I see a web browser demonstrating seemingly magical behavior or misbehavior, I find it hard to sleep until I figure out what’s going on.

    Earlier this month, a new phenomenon was reported that defied easy explanation. A customer posted a comment on this blog noting that her ASP.NET-based web application isn’t working correctly over HTTPS in Internet Explorer 11 on Windows 8.1. With that combination, clicking a button on the site doesn’t correctly load the next page -- doing so instead refreshes the current page. Putting the site in Compatibility View or the Trusted Zone didn’t help at all. Her site works fine in other browsers on Windows 8.1 and it works fine in IE11 on Windows 7. It works fine when accessed over HTTP rather than HTTPS. More interestingly, it works fine even on W8.1 when Fiddler is running, or when the site is in her Intranet zone.

    This was a strange combination indeed, and figuring out the hidden X-factor took a bit of sleuthing. At first, I was a bit stymied because Fiddler is my “go-to” debugger, and if it was causing the change in behavior, I couldn’t use it.

    Or could I? The fact that Fiddler changes behavior is an important clue. As I noted over in “Help! Running Fiddler fixes my app???” there are only a small set of changes that occur when Fiddler is used to monitor traffic. My first guess was that the HTTPS cipher in use changed when Fiddler was in HTTPS decryption mode (because Fiddler defaults to a max of TLS/1.0 while IE11 enables TLS/1.2 by default). After disabling HTTPS Decryption in Fiddler, IE used TLS1.2 through to the site but to my great surprise, the problem still vanished.

    Curiouser and curiouser.

    Fortunately, I recently added support in Fiddler for importing raw packet captures collected using Microsoft Network Monitor or WireShark. While HTTPS traffic is encrypted and cannot be seen, I could use Fiddler to easily compare the HTTPS handshakes between the packet captures of the working (Fiddler or Intranet) and non-working scenarios.

    And I found something quite interesting indeed.

    Here there be Butterflies

    The last few years have seen a number of new and improved attacks against the algorithms used in securing HTTPS traffic, and as a consequence, last November, the IE team announced a change to reduce the use of RC4 for HTTPS connections.

    By default, Internet Explorer 11 on Windows 7 offers the following ciphers in its first ClientHello TLS message:

    Windows 7 IE11 Default

      [003C]    TLS_RSA_WITH_AES_128_CBC_SHA256
      [002F]    TLS_RSA_AES_128_SHA
      [003D]    TLS_RSA_WITH_AES_256_CBC_SHA256
      [0035]    TLS_RSA_AES_256_SHA
      [0005]    SSL_RSA_WITH_RC4_128_SHA
      [000A]    SSL_RSA_WITH_3DES_EDE_SHA
      [C027]    TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
      [C013]    TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA
      [C014]    TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA
      [C02B]    TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
      [C023]    TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
      [C02C]    TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
      [C024]    TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
      [C009]    TLS1_CK_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
      [C00A]    TLS1_CK_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
      [0040]    TLS_DHE_DSS_WITH_AES_128_CBC_SHA256
      [0032]    TLS_DHE_DSS_WITH_AES_128_SHA
      [006A]    TLS_DHE_DSS_WITH_AES_256_CBC_SHA256
      [0038]    TLS_DHE_DSS_WITH_AES_256_SHA
      [0013]    SSL_DHE_DSS_WITH_3DES_EDE_SHA
      [0004]    SSL_RSA_WITH_RC4_128_MD5

    By default, IE11 omits the RC4 ciphers from the offered ciphers when running on Windows 8.1:

    Windows 8.1 IE11 Default

      [003C]    TLS_RSA_WITH_AES_128_CBC_SHA256
      [002F]    TLS_RSA_AES_128_SHA
      [003D]    TLS_RSA_WITH_AES_256_CBC_SHA256
      [0035]    TLS_RSA_AES_256_SHA
      [000A]    SSL_RSA_WITH_3DES_EDE_SHA
      [C027]    TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
      [C013]    TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA
      [C014]    TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA
      [C02B]    TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
      [C023]    TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
      [C02C]    TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
      [C024]    TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
      [C009]    TLS1_CK_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
      [C00A]    TLS1_CK_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
      [0040]    TLS_DHE_DSS_WITH_AES_128_CBC_SHA256
      [0032]    TLS_DHE_DSS_WITH_AES_128_SHA
      [006A]    TLS_DHE_DSS_WITH_AES_256_CBC_SHA256
      [0038]    TLS_DHE_DSS_WITH_AES_256_SHA
      [0013]    SSL_DHE_DSS_WITH_3DES_EDE_SHA

    However, if you are behind a proxy server (like Fiddler) or if the target site is in your Intranet Zone (not the Internet or Trusted Zones), then the RC4 ciphers are again offered in the ClientHello:

    Windows 7/8.1 IE11 Behind Proxy or Intranet
        Same as Win7 IE11 default, above.

    This “offer RC4 to proxies or private networks” behavior was introduced for legacy compatibility reasons; because the IE team cannot “see” your Intranet sites or proxy server, they can’t workaround any compatibility problems occurring on a private network by using a Compatibility View list update or similar mechanism.

    And now we’ve found the clearest difference between the working and non-working cases: when the browser offers RC4, the site works, and when it doesn’t, the site doesn’t work.

    Now that I understood the difference in behavior, I could use Fiddler to explore it more fully. Using a registry key, I manually disabled the use of RC4 by all components that use SChannel (e.g. WinINET, WinHTTP, System.NET etc). Save the following as NoRC4.reg and import it using the Registry Editor:

    Windows Registry Editor Version 5.00

    [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers\RC4 128/128]
    "Enabled"=dword:00000000

    Note that this change is likely to break applications and at this time probably should only be used for testing purposes.

    With RC4 disabled in this way, I could easily reproduce the problem even with Fiddler running or decrypting traffic. Using Fiddler’s Compare feature, I first confirmed that the server was returning exactly the same bytes to the client as it downloaded the page. I then confirmed that the client was sending exactly the same HTTP POST body when the user clicked the button that triggered the ASP.NET postback.

    So, the same content, sent over connections secured using different ciphers, behaved differently.

    Fortunately, in playing with the site, a few other clues came to light. I noticed that the HTTP response’s Server header claimed that the site was served by nginx, an interesting result for a site using ASP.NET. I asked the developer about her topology, and she explained that that they have an nginx/1.2.6 server acting as a HTTPS frontend (using OpenSSL 1.0.0f 4 Jan 2012) it is distributing requests to IIS servers on the backend.

    While debugging the site under Fiddler, I noticed that occasionally one of its requests would cause a malformed response that looked like an attempt to send a HTTP/400 Bad Request status to the client.

    image

    And now I had a theory. The POST sent by the client had a 2kb body that contained the ViewState and, at the end, a parameter which was used to generate the URL to which the browser should be navigated. If I did nothing, or set a breakpoint and manually stripped out that parameter, the server would simply return the same page again. If, however, I padded the POST body with a trailing string of dummy (but well-formed) content, the server would correctly send the user to the next page.

    My current theory is that the outdated nginx/OpenSSL combination in use here is failing to read the entire POST body from the browser client and, as a consequence, it’s passing an incomplete POST to the backend server. The backend server, upon receiving incomplete postback data, simply returns the same page again. The nginx instance then attempts to parse the prematurely truncated end of the first POST’s body as the beginning of a subsequent request on the connection, determines that it isn’t valid HTTP traffic, and returns a HTTP/400. However, when the postback is padded with dummy data, only some portion of that dummy data is truncated, and the IIS server sees the parameters it needs and sends the proper response to the client.

    Now, what could cause the nginx/OpenSSL combo here to have this problem with the TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA cipher combination? My guess is that it’s a beast of a bug. More specifically, at the end of 2011, an attack named BEAST targeted CBC cipher algorithms, and as a consequence, browsers implemented a technique called 1/n-1 record splitting, in which HTTPS traffic sent over CBC-based algorithms is split into multiple records. My current guess is that the older version of the frontend’s software isn’t properly collecting all of the records which represent the POST body, and as a consequence it’s sending incomplete data to the backend server.

    I’ve suggested that the site owner update the frontend to use the very latest nginx and OpenSSL to see whether the problem is resolved.

    In a decade of looking at browsers, I’ve yet to find any magic, but there are plenty of cases where minor quirks, accumulated over decades and across billions of scenarios, lead to butterfly effects that are difficult to explain.

    -Eric Lawrence
    Internet Explorer MVP

    PS: Good references on controlling SChannel via the registry: blogs.technet.com/.../speaking-in-ciphers-and-other-enigmatic-tongues.aspx and http://support.microsoft.com/kb/245030/en-us

    Browser Arcana: IP Literals in URLs

    $
    0
    0

    While virtually all web traffic flows over connections based on the Internet Protocol, most of the time your browser first uses DNS to look up the target hostname’s IP address. However, sometimes URLs directly specify an IP address, skipping DNS altogether. When an IP appears directly within such an URL, it is said to have an IP-Literal Hostname. In general, using IP-Literal hostnames is a bad idea (as they don’t support DNS Failover and other useful features) but in rare cases their use may be reasonable-- e.g. when communicating directly with network devices like switches and routers.

    The most common IP-Literal URLs use the dotted-quad notation for an IP v4 address; for instance, http://127.0.0.1/mypage. The introduction of IPv6 complicated matters a bit, since IPv6 literals must be placed within square-brackets in the URL, like so: http://[::1]/mypage. Many users are surprised, however, to learn that IPv4 literals can be expressed using other notations.

    For instance, any internal “0“ components of a dotted quad may be omitted, and thus http://127.0.1 and http://127.1are both equivalent to http://127.0.0.1.

    The more interesting of the notations are the raw integer forms—remember, an IPv4 address is simply a 32bit integer. As such, you can represent 127.0.0.1 in its decimal form as http://2130706433/ or even in octal form as http://017700000001/. The reason that these variants are interesting is that they don’t contain any dots, and various software components may treat hostnames without dots as special1. In 2001, for instance, incorrect mapping of all dotless hostnames to the (privileged) Intranet security zone resulted in a serious security vulnerability which was patched by introducing special detection for IP address literals.

    In Internet Explorer 7, the CURI object was introduced to standardize handling of URLs throughout the browser and OS; one of the first steps that class undertakes when constructing a URL object from a string is to convert any IP literal hostname into its canonical dotted-quad form. Chrome and Opera appear to match Internet Explorer’s behavior here, while Firefox 27 leaves the undotted decimal in the address bar and in the request sent to the network2:

    IE, Chrome, Opera

    GET / HTTP/1.1
    Host: 127.0.0.1
    User-Agent: Mozilla/5.0 (Windows NT 6.3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.45 Safari/537.36

    Firefox

    GET / HTTP/1.1
    Host: 2130706433
    User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:27.0) Gecko/20100101 Firefox/27.0

    If your code makes any sort of security decision based on the absence of dots within a hostname, be sure that you aren’t fooled by undotted IP literals!

    -Eric

    1 For instance, the isPlainHostName function in PAC scripts, or the network.automatic-ntlm-auth.allow-non-fqdn preference in Firefox.

    2 Mozilla has an issue filed to remove support for undotted IP literals entirely, and while it’s tagged as “New,” it is today just over 13 years old.

    Same Origin Policy Part 0: Origins

    $
    0
    0

    Recently, someone asked a pretty simple question: “Why doesn’t IE consider the port when evaluating Same Origin Policy?” and I realized that my Same-Origin-Policy series lacks an in-depth look at the concepts surrounding origins.

    Table of Contents: Same Origin Policy Posts

    Why do we need origins at all?

    The Web is comprised of many different sites (“principals”) – some official and legitimate (e.g. your bank), some outright malicious (phishers) and every shade in between. As a consequence, browsers must keep the code and data between these principals separated, or the “bad guys” could use their code, running in your browser, to attack or steal data from the “good guy” sites your browser can access.

    On the web, origins are meant to represent a single security principal, or as I sometimes call it, “a single sphere of control." You don’t want each individual page to be an isolated origin, or it would be cumbersome to build interesting websites and applications1. On the other hand, you don't want an origin to encompass resources that are under the control of unrelated entities, or those resources will be able to use the client's browser to attack one another.

    For instance, naïve sites in the early web used to allow different users to serve content from the same host but different path (e.g. //example.com/~userA and example.com/~userB), and security isolation was utterly nonexistent2, because siteA and siteB could scribble all over one another.

    Okay, so we want to partition the websites controlled by different entities. Each entity is identified by its “origin.”

    Origin ≈ URLMon SecurityId

    Within Internet Explorer and (to some extent) across Windows, UrlMon is responsible for managing the access permissions of web content. In most cases, URLMon will end up examining the SecurityId of the source and target resources to determine whether access should be granted to the target. Technically, a SecurityId is an opaque byte array up to 512 bytes long (MAX_SIZE_SECURITY_ID) but, in practice, the SecurityId typically follows the format mentioned in the GetSecurityId method’s documentation:

        <scheme>:<hostname>+<zone#>

    As you can see, this is similar to, but not exactly equivalent to the recent RFC6454 definition, which defines the typical origin as:

        triple(uri-scheme, uri-host, uri-port)

    In typical cases, URLMon will check that the source and target Security Ids match exactly, although there’s also a CompareSecurityIds function which performs a more-liberal (and thus potentially-dangerous) comparison.

    If the SecurityIds match exactly, access is typically granted; if the SecurityIds don’t match, an override setting (e.g. URLACTION_CROSS_DOMAIN_DATA) may be consulted before access is denied.

    So, why isn’t the Port part of URLMon’s SecurityId?

    Short answer: I don’t know – it was before my time.

    Longer answer: I have two guesses. Guesses can be either right or useful.

    Guess #1: In the early days of the Internet, virtually all of the hosts were running some form of Unix-like operating system. Unix was a multi-user OS from the start, and by default, any user could listen on a TCP/IP port (only "low-numbered" ports <1024 were restricted to admins). So, if the concept of an Web Origin didn't include a port, Unix UserA could stand up a web server and attack Unix UserB. In such a world, the port clearly needs to be a part of the Origin.

    However, back in those early days of the web, Windows was basically a single-user operating system, which made the "different users running different servers from the same box" scenario less applicable for a Windows web server. (Of which, there really weren't many until Windows NT became popular, at which point Windows had become a true multi-user OS). The ports could have been considered a part of the SecurityId at that time, but changing this would break any corporate applications that had been written with the expectation that they were not. For instance, you could have a Intranet Timesheet app running on one port and a Payroll app running on another and it might be desirable to allow them to interact.

    Guess #2: When URLMon was first built, it wasn’t entirely clear what protocols would be relevant in the future. As a consequence, URLMon abstracted and generalized many concepts, and “port” is a concept which is specific to network protocols based on IP. As such, it might not have been deemed sufficiently generalized to use as a part of the SecurityId. Furthermore, a protocol implementer could include any non-default port in the host component of the SecurityId even though that never happened.

    Could SecurityIds be changed to include the port?

    Today, I think a decent argument could be made that IE should consider port to be a part of the origin. That's especially true now that IE supports CORS for XHR, which means that it would be possible for a site to "fix itself" by offering up an Access-Control-Allow-Origin directive for XHR interactions (although
    DOM-interactions would be still be blocked).

    However, there are three problems with changing this now:   

    1. Compat. Obviously, this would be a breaking change for any site that was written to ancient IE and never needed to work cross-browser.
    2. Completeness. In IE8 the native XmlHttpRequest object included port as a part of the same-origin-policy evaluation. This was our first stab at trying to move over to the standards-based SOP. Unfortunately, the outcome was awful—a number of sites refused to use the native XHR and kept using the ancient MSXML XHR object to keep their sites working.

      So we didn't get standards OR security. We reverted the "port as part of origin for XHR" in a future update.
    3. The problems IE’s behavior causes are mostly “solved”. Largely due to #2, sites have been forced to solve for this issue. And the solution is pretty simple-- if you want to host multiple unrelated sites on a single box, and have isolation between them, you simply use multiple hostnames, one per principal, and you only route traffic to the destination port if the hostname is correct. That way, traffic is properly isolated regardless of browser version.

    Even if IE12 were to change in behavior to include the port as a part of the origin, sites won’t be able to rely upon such isolation for a very very long time; there are hundreds of millions of legacy clients out there, and an unknown number of extensions and plugins that might never be updated with the new rules. 
      
    When we considered making a change in IE8 and future releases, we had to decide: "Is the (unknown) compat hit we'd take today worth the (unknown) security value this would provide at some point in the future?" And our decision in IE8-IE11 was "no."

    Quirks from the Zone in the SecurityId

    In most cases, Internet Explorer’s inclusion of the Zone in the SecurityId is redundant, because in most scenarios the Zone of a resource is determined by its hostname, which is already a part of the SecurityId. However, there are two scenarios where two SecurityIds may have the same hostname but a different zone.

    Zone Changes

    A user’s security zone configuration can change at almost any time; a user can simply click Tools > Internet Options > Security and move a site from one zone to another. This is, at best, a rare corner case.

    Amusingly, real-life experience presented one case where having the Zone in the SecurityId is problematic. Many users inside Microsoft use Outlook Web Access (OWA) to access their mail at https://mail.microsoft.com/. OWA is a great example of a “single-page web application” where the user keeps a single web page loaded for hours; it uses XHR and IFRAMEs to pull data from the server as needed. One day, we started getting reports that users were having problem with their mail when they brought their laptops from work to home and vice versa. Looking at the JavaScript exception logs, there were a flood of Access Denied errors.

    What went wrong?

    The IT department had recently updated the Proxy AutoConfiguration Script so that accessing the mail server would go DIRECT, bypassing the proxy. Doing so causes the site to be treated as Intranet Zone.  As a consequence, when users moved from work to home or vice versa, the PAC script was either disabled or enabled and the SecurityIds generated for the mail servers resources bounced between Internet and Intranet. The mismatched zone number caused the Same-Origin-Policy checks to fail.

    To resolve the issue, we suggested that the IT Department should use Group Policy to force the mail site into the Intranet zone, so that its SecurityId would remain stable regardless of whether or not the proxy script were in use.

    SECURITY=RESTRICTED IFrames

    Long before the advent of the HTML5 Sandbox attribute, IE6 added the ability for a page to restrict a subframe’s content, by setting an SECURITY=RESTRICTED attribute on the IFRAME. This attribute causes the content of the frame to be treated as if it were running in the Restricted Sites zone, regardless of what hostname it is served from. Interestingly, SOP suggest we shouldn’t be able to use an Internet Zone page to writing into a Restricted Zone page from the same host, but this restriction doesn’t seem to be enforced.

    Quirks for File URIs

    Typically, the SecurityId consists of a protocol scheme, hostname, and zone number. Hostnames are canonicalized to lowercase and thus most SecurityIds are effectively case-insensitive.

    However, file URIs’ SecurityIds consist of:

        <scheme>:<hostname>/<firstPathComponent>+<zone>

    The first path component is included as part of the SecurityId because file shares are named, and different shares may have different access lists. For instance file://server/Accounting and file://server/Dev/ are considered different origins.

    On some file systems, paths and share names are case-sensitive, so as a consequence, the SecurityId of a file URI is also case-sensitive. You will find that file://server/Dev/Page1.htm can interact with file://server/Dev/Page2.htm but not file://server/dev/Page3.htm because the Origin for the first two pages is FILE:server/Dev while the origin for the third is FILE:server/dev.

    Random arcana

    In a future update, we’ll look at the relationship between origin and:

    • postMessage
    • cookies (secure & insecure)
    • XHR’s Origin header
    • relaxation of document.domain

    -Eric Lawrence

    1 Trying to retrofit “fine-grained origins” onto the Web is a risky proposition, as Jackson and Barth explained in their great paper.

    2 This is commonly called "The GeoCities problem" but I think it was some other site (maybe AngelFire?) that did this.


    Windows Server as a Workstation

    $
    0
    0

    Back in the Windows 2003 timeframe, Microsoft had a problem. The security press of the time liked to put out charts showing which operating systems had the most vulnerabilities. Windows 2000 wasn’t looking so hot, owing to the fact that Windows 2000 Server had a full web browser built-in, “out of the box.” Even if a server administrator followed best-practices and never booted the browser, Windows still looked bad in the charts because all browsers, including IE5 and IE6, had an endless stream of security patches.

    Windows cobbled together a small task force to address this problem by introducing the Enhanced Security Configuration feature for Internet Explorer when run on Windows Server.

    ESC: Enhanced Security Configuration

    ESC makes myriad small changes across the browser, but the primary change is that it kicks the security level of the Internet Zone up to High:

    image

    By setting the Internet Zone to use the High Template, ActiveX and script execution are blocked and a huge number of features are disabled by default. This simple change alone would have been sufficient to make the charts look dramatically better (because virtually all browser exploits require one or more of the disabled features).

    To help the user understand that this configuration is enabled, the default homepage is changed to a very wordy explanation:

    image

    This could be summarized as: “This is a server. Don’t browse from your server. That’s what workstations are for!

    However, the notifications don’t stop there. As you browse around, you’ll see many ancient notifications that were long ago hidden by the default security level template, like this prompt from the 1990s that attempted to explain what HTTPS was all about:

    image

    Any time you visit a website that wants to run script or perform another action that is not permitted due to the changes made by ESC, a prompt is shown:

    image

    What this prompt really means is: “Hey, we noticed that you’re browsing from your server. We really don’t want you to do that, but we’ll let you. If you’re really really committed to browsing securely from your server, you can load the page in this mode which will probably break it. Or you can manually add this site to the list of sites you trust to run with regular permissions.”

    Some … hyper-vigilant  users find these prompts useful and don’t seem to mind them. Some administrators feel they have a genuine need to use a browser on the server itself and they don’t feel they can accomplish their goals by browsing from a workstation.

    However, if you’re simply a developer who’s running a Windows Server as a workstation (e.g. your dev box) so you have a full IIS / SQL instance, etc, and you’re not really using it as a production server, it is likely that these prompts will quickly get intensely irritating.

    Fortunately, you can very easily instruct the Server to knock it off. From the Local Server tab of the Server Manager, click the link next to the IE Enhanced Security Configuration item:

    image

    A dialog will launch that allows you to control the ESC feature:

    image

    Changes take effect the next time Internet Explorer starts.

    Note that clicking the “More about Internet Explorer Enhanced Security Configuration” link will launch a browser which prompts you with the ESC “Content Blocked” dialog for 9 different domains (including Facebook and about:blank) before rendering the generic Internet Explorer Help page.

    After you disable ESC, the browser’s default homepage will change to a warning to remind you that you’ve done so:

    image

    The ESC feature has received only minimal attention from the IE development team over the last decade. By default, the recommended “Windows Server Core” configuration doesn’t include a GUI at all, which means that servers that are acting as proper “servers” are in a very secure configuration automatically. Even when you enable the GUI for Server, Windows supports uninstalling the Internet Explorer browser if it isn’t needed.

    In my opinion, the ESC feature should probably be yanked out—it’s irritating, unnecessary, and has an ongoing maintenance cost for the IE development team.

    For now, however, disabling ESC isn’t the only change you need to make to make your server behave like a workstation.

    HTML5 Video

    If you’re using a PC running Windows Server 2012 R2, you might find that HTML5 video doesn’t play in Internet Explorer. For instance, when visiting a page like the FishBowl benchmark, it might stop loading at the “Initializing” stage, with the F12 Developer Tools’ Console tab showing an inscrutable error:

    SCRIPT65535: Unexpected call to method or property access.

    The problem is that, by default, Windows Server does not include the HTML5 video codecs, and thus they’re not available to Internet Explorer. To resolve this, simply boot a Windows PowerShell command prompt (e.g. by clicking the icon in the task bar):

    image

    and then enter the following two commands:

    Import-Module ServerManager

    Install-WindowsFeature Desktop-Experience

    A reboot is required for the installation to complete.

     

    -Eric Lawrence
    MVP - Internet Explorer

    Awesome IE11 News, in case you missed it

    $
    0
    0

    Big news from the //build conference this week:

    1. The IE team has announced a feature-implementation tracking site, which you can find at http://status.modern.ie/. This site shows what IE supports (and when it supported it) and provides a look at what to expect in future versions of Internet Explorer. It also provides links to relevant specifications and information about cross-browser support. This is an awesome resource and I’m very excited that it’s out! Tweet any feedback to @iedevchat.

    2. IE11 now offers an Enterprise Mode feature, which allows IT administrators to deploy a list of sites which should run in IE8-Compatibility mode. This feature significantly improves compatibility with legacy sites, while offering major performance improvements over IE8 itself.

    3. The F12 Developer tools have been enhanced, and IE11 will ship on Windows Phone 8.1. You can read all about it on the IEBlog.

    For all the gory details, check out this MSDN article on the IE11 on Windows 8.1 Update.

    -Eric

    Managed Code Browser Extensions

    $
    0
    0

    I love the .NET Framework. I’ve been programming in C# since 2001, I spent much of my free time for a decade building Fiddler on .NET, and I now code in C# for a living. .NET provides a fantastic, highly-productive platform suitable for building a huge range of tools and applications, and as it grows in power and performance, its scope has only grown.

    However, there’s one task for which .NET code isn’t suitable: building in-process browser extensions like Toolbars, BHOs, Pluggable Protocols, and ActiveX controls. These COM-based extensibility mechanisms were exposed long before the .NET Framework, and while .NET offers powerful interop with COM, it’s not an appropriate technology to implement browser extensions.

    .NET-based browser extensions are responsible for significant performance and reliability problems in the browser. Even now that the .NET Framework version 4 resolved the side-by-side versioning problem, Raymond Chen notes that in-process browser & shell extensions shouldn’t be written in managed code. The Issues Specific to the .NET Framework section of the Guidance for Implementing In-Process Extensions MSDN article explains this topic in further detail.

    Of the extension types, Toolbars and BHOs are the most problematic, as they are automatically loaded by every tab upon startup and often perform processing on every page load. The performance impact of such extensions can severely hurt the overall performance of the browser. Managed Pluggable Protocols and ActiveX controls are somewhat less problematic, as they’re only loaded when invoked by web content, but such usage should still be avoided.

    Obviously, .NET remains a great choice for out-of-process interaction with browsers (e.g. like Fiddler or applications invoked by Application Protocol url schemes). If necessary, you could even use .NET to do most of the heavy lifting for your BHO or toolbar—just do so by writing a native-code COM extension (using C++, Delphi, etc) that itself uses RPC/named pipes/etc to marshal data to the out-of-process .NET code. That way, the only code running in-process with the browser is native and you avoid loading the framework into the browser process.

    Over the years, IE has increased the restrictions and hurdles placed on binary browser extensions, going so far as to block them entirely in the Immersive/Metro mode of the browser. If there’s a new extension model in a future version of IE, I expect it will be based on JavaScript. But who knows, perhaps one day we’ll see a safe, fast, and stable way to build add-ons in managed code that is automatically executed out-of-process.

    -Eric Lawrence

    Internet Explorer 11 and Perfect-Forward-Secrecy

    $
    0
    0

    In case you missed it, the recent Windows 8.1 Update update adds four new ciphersuites (including two supported by Chrome32) and changes the ciphersuite order to prefer algorithms that offer Perfect-Forward-Secrecy. You can read more about this update here.

    Wikipedia has a nice article on PFS, but the short summary is as follows:

    When your browser makes a HTTPS connection, typically, two keys are used: the client generates a random secret key that is used by a fast, symmetric (“bulk”) encryption algorithm, and it encrypts that secret using the public asymmetric key (slow) provided by the server. The problem is that if the server’s private key is ever compromised, an attacker who had previously recorded your traffic could then decrypt the secret symmetric key and turn the “gibberish” he had recorded back into the plaintext of your web session’s traffic, even if it took place months or years ago.

    In PFS, each connection to the server generates a new asymmetric key pair specific to that session, such that if the server’s private key is compromised, only future traffic is at risk of disclosure.

    The Windows 8.1 Update isn’t the first time that IE has supported PFS, but the new ciphersuites added in this update have performance characteristics that make servers more likely to use them.

    -Eric

    Unicode in URL changes for IE11

    $
    0
    0

    I wrote a bit about Internet Explorer’s International Settings back in July of 2012. Internet Explorer 10 and 11 quietly brought some changes:

    image

    In IE10, the Use UTF-8 for mailto links option was removed.

    In IE11, the misleadingly-named Send UTF-8 URLs option is renamed to correctly reflect its function (Send URL path as UTF-8) and it’s joined by two off-by-default options to Send UTF-8 query strings. We had considered adding these options in IE8 but ultimately decided that we didn’t have time and runway to introduce a potentially-breaking change to IE’s handling of non-ASCII query strings.

    Unfortunately, as noted in this CONNECT bug, these new checkboxes don’t appear to work. Even when you tick both Send UTF-8 query strings boxes and restart IE, IE fails to update its behavior.

    Consider the following URL:

    http://webdbg.com/ほむら/?Query=ほむら

    On a US-English system, if you paste this URL into IE11’s address bar and hit enter, you can watch in Microsoft Network Monitor and see that the query string has been thunked down to ASCII with the three Unicode characters replaced by three question marks:

    image

    This problem only applies to the query string; Unicode characters in the path are still sent as %-encoded UTF-8.

    In contrast, navigating via Chrome’s Address bar shows expected results:

    image

    -Eric Lawrence

    Viewing all 63 articles
    Browse latest View live


    <script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>