Secure ActiveX Best Practices

Secure ActiveX Best Practices

Incorrectly designed or poorly written ActiveX controls can cause serious security problems in two container types, Web browsers and e-mail clients, because Web pages can invoke ActiveX controls by using HTML or a scripting language and e-mail applications can often display HTML-formatted text, which means that e-mail messages can also invoke ActiveX controls, depending on the security settings your mail reader applies. Outlook 2002 (part of Microsoft Office XP) does not invoke ActiveX controls in e-mail by default, nor does Outlook Express in Windows .NET Server 2003 and Windows XP.

If a vulnerability exists in an ActiveX control, the issue is exacerbated if the user is not warned that the HTML page or e-mail containing an HTML page is about to invoke the vulnerable ActiveX control.

For an HTML page either in a Web browser or in an e-mail client to invoke an ActiveX control without notifying the user that it's doing so requires that certain security policy settings be in place. Most notably, if the code is marked as safe for initialization (SFI) or safe for scripting (SFS), the host application might not warn the user that the code is about to be used in a potentially unsafe manner.

What ActiveX Components Are Safe for Initialization and Safe for Scripting?

When a control is instantiated, or initialized, it can open local or remote data through various COM IPersist interfaces. This is a potential security problem because the data can come from an untrusted source. Controls that guarantee no security problems when any persistent initialization data is loaded, regardless of the data source, are deemed safe for initialization.

Safe for scripting means the control author has determined that it's safe to invoke the control from script because the control has no capabilities that could lead to security problems. Even if a control is safe when used by users, it is not necessarily safe when automated by an untrusted script or Web page. For example, Microsoft Excel is a trusted tool from a reputable source, but a malicious script can use its automation features to delete files and create viruses.

I will enumerate the capabilities that make a control unsafe for initialization and scripting shortly.

IMPORTANT
ActiveX controls are executable programs and, as such, can be digitally signed using a technology called Authenticode. Although code signing can guarantee the identity of the control author and guarantee that the control has not been tampered with, it does not guarantee that the code is free from errors and security vulnerabilities.

Let me give an example of a control that is not safe for scripting. In May 2001, I performed a security review for a Web site that required users of the site to install the ActiveX control hosted on the site. The first question I asked was whether the control was safe for scripting. The developer of the control informed me it was. So I asked if the control had methods that access resources, such as files, on the user's computer. It turned out that the control had a method called Print, which allowed the control to print a file, any file, to any printer! With this in mind, I informed the developer that the control was not safe for scripting because when a user browses to my malicious Web site, I can print any document on his hard disk on my printer and the user won't know the document was printed!

If you wonder how this all happens, remember that any ActiveX control loaded on a computer can be used by any Web site unless you take steps to prevent it from being loaded. The vulnerability above exists because a malicious Web site invokes the ActiveX control from within one of its Web pages and then calls the Print method to print a sensitive document on a printer owned by the attacker.

Look at some past examples, in which signed ActiveX controls, written by well-meaning and capable developers, have led to serious security vulnerabilities. Examples include Outlook View Control Exposes Unsafe Functionality at http://www.microsoft.com/technet/security/bulletin/MS01-038.asp, Active Setup Control Vulnerability at http://www.microsoft.com/technet/security/bulletin/MS99-048.asp, and Office HTML Script and IE Script Vulnerabilities at http://www.microsoft.com/technet/ security/bulletin/MS00-049.asp.

IMPORTANT
A control does not need to be intentionally hostile to be a danger in fact, very few hostile controls exist. The real danger is legitimate controls repurposed by attackers using vulnerabilities in the control.

If you want to mark a control as SFI or SFS, refer to msdn.microsoft.com, and search for safe for scripting. But read the next section before doing so!

Best Practices for Safe for Initialization and Scripting

The first rule of safe for initialization and scripting is this:

Your control is not safe for initialization or safe for scripting!

Next you need to determine what makes your control safe for both categories. If you find any functionality that harbors potential insecurities, the control must remain marked as unsafe. If in doubt, do not mark it as safe for scripting.

IMPORTANT
It's important that you do not mark your control as safe for either category and then look for insecure functions to invalidate the belief that the control is safe. If you do this, you will often miss an undocumented or poorly documented unsafe function and leave your users vulnerable to attack.

Is Your Control Safe?

The process for determining whether a control is safe is quite simple: list all the control's events, methods, and properties. So long as each event, method, or property exposed by the control performs none of the following, it can be deemed safe for scripting:

  • Accesses any information on the local computer or network, such as registry settings or files

  • Discloses private information, such as private keys, passwords, and documents

  • Modifies or deletes information on the local computer or network

  • Crashes the host application

  • Consumes excessive time or resources, such as memory and disk space

  • Executes potentially damaging system calls, including executing files

If any of these are true, the control cannot be marked as SFS. A quick and useful method is to look at all the names looking for verbs, taking special notice of function names such as RunCode, PrintDoc, EraseFile, Shell, Call, Write, Read, and so on.

Note that simply reading a file or registry key is not necessarily a security problem. However, if an attacker can set the name of the resource and the data in that resource can be sent to the attacker, that is indeed a problem.

Another option is to implement IObjectSafety. This allows a container application (typically Internet Explorer) to query your object and determine whether it's safe for scripting or initialization. You can also make more complex decisions about whether you want to enable this functionality.

You should also test every method and property for buffer overruns, as discussed in Chapter 19, Security Testing.

Limit Domain Usage

Irrespective of whether you mark a control safe for scripting, you might want to allow the control to be scripted only when invoked from a specific restricted domain. For example, you might restrict your ActiveX control so that it can be used only when called from a Web page that is part of the northwindtraders.com domain. You can achieve this by following these steps in your control:

  1. Implement an IObjectWithSite interface, which has a SetSite method that's called by the container, such as Internet Explorer, to get a pointer to the container's IUnknown interface. (You'll need to include Ocidl.h in your code.) IObjectWithSite provides a simple way to support communication between a control and the container.

  2. Next use the following pseudocode to get the site name:

    pUnk->QueryInterface(IID_IServiceProvider, &pSP); pSP->QueryService(IID_IWebBrowser2, &pWB); pWB->getLocationURL(bstrURL);

  3. Finally, the code should determine whether the value in bstrURL represents a trusted URL. This requires some careful thought. A common mistake is to check whether northwindtraders.com, or whatever the expected server is, exists in the server name. But this can be defeated by creating a server name like www.northwindtraders.com.foo.com! Therefore, you should perform a search by calling the InternetCrackUrl function, exported from Wininet.dll, to get the host name from the URL it's the lpUrlComponent->lpszHostName variable and performing a rightmost search on the string.

The following code outlines how to achieve the last step:

/* InternetCrackURL.cpp */ BOOL IsValidDomain(char *szURL, char *szValidDomain, BOOL fRequireHTTPS) { URL_COMPONENTS urlComp; ZeroMemory(&urlComp, sizeof(urlComp)); urlComp.dwStructSize = sizeof(urlComp); // Only interested in the hostname char szHostName[128]; urlComp.lpszHostName = szHostName; urlComp.dwHostNameLength = sizeof(szHostName); BOOL fRet = InternetCrackUrl(szURL, 0, 0, &urlComp) ; if (fRet==FALSE) { printf("InternetCrackURL failed - > %d", GetLastError()); return FALSE; } //Check for HTTPS if HTTPS is required. if (fRequireHTTPS && urlComp.nScheme != INTERNET_SCHEME_HTTPS) return FALSE; //Quick 'n' dirty rightmost case-sensitive search int cbHostName = lstrlen(szHostName); int cbValid = lstrlen(szValidDomain); int cbSize = (cbHostName > cbValid) ? cbValid : cbHostName; for (int i=1; i <= cbSize; i++) if (szHostName[cbHostName - i] != szValidDomain[cbValid - i]) return FALSE; return TRUE; } void main() { char *szURL="https://www.northwindtraders.com/foo/default.html"; char *szValidDomain = "northwindtraders.com"; BOOL fRequireHTTPS = TRUE; if (IsValidDomain(szURL, szValidDomain, TRUE)) { printf("Cool, %s is in a valid domain.", szURL) ; } }

This code is also available on the companion CD in the folder Secureco2\Chapter 16\InternetCrackURL. If the call to IsValidDomain fails, your control should fail to load because the control is being invoked in a Web page from an untrusted domain in this case, a domain other than northwindtraders.com.

Note that you can find more information regarding all of the COM interfaces and functions described in this section at msdn.microsoft.com, and a Knowledge Base article, HOWTO: Tie ActiveX Controls to a Specific Domain, at support.microsoft.com/support/kb/articles/Q196/0/61.ASP includes ATL code to limit domain usage.

Using SiteLock

SiteLock, a C++ ATL template library, was developed during the Windows and Office security pushes in early 2002 to make it much easier to bind ActiveX controls to Web sites and to restrict how the controls operated. The SiteLock template enables an ActiveX developer to restrict access so that the control is deemed safe only in a predetermined list of domains, limiting the ability of attackers to reuse the control for malicious purposes. Developers can also use the SiteLock template to create a control that behaves differently in different domains. The template consolidates domain checking into a single, shared library that makes an ActiveX control much more secure and makes problems much easier to fix when they are found.

NOTE
The SiteLock code is now publicly available at http://msdn.microsoft.com/downloads/samples/internet/components/sitelock/default.asp.

Setting the Kill Bit

Suppose that all your best efforts have failed and you've shipped an ActiveX control that has a security bug. You might think that shipping a new one would take care of the problem you've thought wrong, especially if the user has chosen to always trust ActiveX controls signed by you. A malicious Web site could invoke your old control that it provides to the user, and now your user has been hacked. Here's how you solve this problem. In the HKLM\Software\Microsoft\Internet Explorer registry key, locate the ActiveX Compatability subkey. Under that key will be a number of controls listed by CLSID (class id). To kill your control, take its CLSID represented as a string, use it to create a new subkey (if it isn't already present), and then set a REG_DWORD value named Compatibility Flags to 0x00000400. That's all there is to it. I'd recommend making all new versions of your control set this bit for all previous versions so that a user who is installing your control for the first time is protected from your previous mistakes. For more information, see Knowledge Base article Q240797.



Writing Secure Code
Writing Secure Code, Second Edition
ISBN: 0735617228
EAN: 2147483647
Year: 2001
Pages: 286

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net