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.

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 certain security policy settings 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 www.microsoft.com/technet/security/bulletin/MS01-038.asp, Active Setup Control Vulnerability at www.microsoft.com/technet/security/bulletin/MS99-048.asp, and Office HTML Script and IE Script Vulnerabilities at 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.

You should also test every method and property for buffer overruns, as discussed in Chapter 14, Secure 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 Secureco\Chapter 10\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.



Writing Secure Code
Writing Secure Code, Second Edition
ISBN: 0735617228
EAN: 2147483647
Year: 2005
Pages: 153

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