SafeCtl.exe implements IObjectSafety in ActiveX control

This article has been archived. It is offered "as is" and will no longer be updated.
The SafeCtl.exe sample demonstrates how to modify an MFC-based ActiveX control to indicate who published the code and whether a control has been tampered with. The sample can help to identify whether the control is safe for scripting and safe for initialization.
More information
The following file is available for download from the Microsoft Download Center:
For more information about how to download Microsoft support files, click the following article number to view the article in the Microsoft Knowledge Base:
119591 How to obtain Microsoft support files from online services
Microsoft scanned this file for viruses. Microsoft used the most current virus-detection software that was available on the date that the file was posted. The file is stored on security-enhanced servers that help prevent any unauthorized changes to the file.

In Internet Explorer 3.0 and later versions, users can add code in the form of ActiveX controls to their Web pages. The <OBJECT> tag is used to specify a control. After an instance of the control is created, its attributes can be set through the control's persistence interfaces. For example, for each <PARAM> tag that Internet Explorer encounters in the context of an <OBJECT> tag while parsing an HTML page, Internet Explorer passes a property bag through the corresponding control's IPersistPropertyBag interface. Furthermore, the behavior of a control can be customized through the use of scripts embedded in the page that execute the methods and modify the properties exposed through the control's automation interface.

Authenticode code signing technology allows end users to identify who published the code and to verify that no one has tampered with that code since it was signed. It does not guarantee that the code is safe when its properties are initialized with untrusted values or when its automation model is driven by untrusted scripts. To avoid such potential security hazards, the default Internet Explorer security settings, which are accessible via the Security tab of the Internet Explorer Options property sheet, require that a control register itself as implementing the appropriate component categories or that the control implement the IObjectSafety interface. The sample illustrates both.

Before it sets the properties of a control embedded in an HTML page, Internet Explorer queries the control for IObjectSafety. If supported, Internet Explorer then calls the SetInterfaceSafetyOptions method on this interface, passing the value INTERFACESAFE_FOR_UNTRUSTED_DATA as well as the interface identifier (IID) of a persistence interface. On HTML pages today, where properties tend to be initialized via the <PARAM> tag, the IID is IID_IPersistPropertyBag. The IID is provided for situations where you might want to be protect the safety on some interfaces but not on others, and in this example that is not important. The sample implementation checks to make sure that the interface is supported. If the control can do no harm to the client's system regardless of the data with which it may be initialized through that persistence interface and that persistence interface is supported, the control's implementation of the IObjectSafety::SetInterfaceSafetyOptions method should return S_OK. Otherwise, E_FAIL should be returned.

Before allowing any scripts that are embedded in the page to be run, Internet Explorer similarly calls through the control's IObjectSafety:: SetInterfaceSafetyOptions method but instead passes the value INTERFACESAFE_FOR_UNTRUSTED_CALLER and the IID of some scripting interface, which typically is IID_IDispatch. The control should return S_OK or E_FAIL appropriately.

If the control does not support IObjectSafety, Internet Explorer uses the component categories manager to see if the control implements the "safe for initialization" category, CATID_SafeForInitializing, and the "safe for scripting" category, CATID_SafeForScripting, respectively.

If the control does not support IObjectSafety and has not registered itself as implementing the appropriate component categories, and if the Internet Explorer safety level is set to High, the default, Internet Explorer will not initialize the control's properties, nor will it execute any scripts that are embedded in the page. In this scenario, end users receive a dialog box that contains the following text:
Potential safety violation avoided
This page contains active content that is not verifiably safe to display. To protect your computer, this content will not be displayed.
The following is a list of guidelines that are taken from Paul Johns' article, "Signing and Marking ActiveX Controls:"
  • The control does not manipulate the file system.
  • The control does not manipulate the registry (except to register and to unregister itself).
  • The control does not overindex arrays or otherwise manipulate memory incorrectly.
  • The control validates (and corrects) all input, including initialization, method parameters, and property set functions.
  • The control does not misuse any data that is provided by the user or that is about that user.
  • The control was tested in a variety of scenarios.
For additional information, visit the following Microsoft Web site:If a control author has verified that the above criteria have been met in addition to any others that they can think of, they should consider supporting both IObjectSafety and registering their control as implementing the appropriate component categories. For a list of the advantages and disadvantages of each of these methods, review the corresponding section in Paul Johns' article, "Signing and Marking ActiveX Controls."

To Compile

Building the sample requires Microsoft Visual C++ 5.0 or Microsoft Visual C++ 6.0. After you extract the files from the archive, load the Safectl.mdp project into Microsoft Developer Studio, and build the project. As part of the build process, the control should register itself.

Warning Before you modify the sample by using the two preprocessor symbols that are listed later in this section, you have to unregister the control if it has already been built or registered on the computer. To do this, run Regsvr32.exe with the /u switch for your control. You can also add a custom tool entry in Developer Studio that will do this for the current project. On the Tools menu, click Customize, and then click the Tools tab. Create a new entry with the following information:
                Name: &Un-register ActiveX Control             Command: e:\Program Files\DevStudio\SharedIDE\BIN\REGSVR32.EXE           Arguments: /u /v "$(TargetPath)"   Initial Directory: $(TargetDir)				
At this point, you can use the "tools/Un-register ActiveX Control" entry to unregister your control before you add or remove the sample-specific preprocessor definitions.

To build the control so that it registers itself as implementing the "safe for initializing" and the "safe for scripting" component categories, follow these steps:
  1. On the Project menu, click Settings.
  2. Click the C++ tab, and then define the following preprocessor definition:
  3. Click OK to close the Settings dialog box, and then rebuild the control.
To build the control so that it instead implements IObjectSafety, follow the previous steps, but replace L_USE_COMCAT with L_IMPL_OBJECTSAFETY.

It is also valid to define both preprocessor symbols. Observe that these symbols are specific to this project. By default, the build settings of the project define both preprocessor symbols.

To Run

After the sample control has been built and has been registered successfully, start Internet Explorer, and then open the Safectl.htm page, which is included with the sample.

If the control has been configured to register itself as safe or implement IObjectSafety, the controls caption should read "Safe for initializing!" When you click the control, you should receive the following message:
I must be safe for scripting!
If Internet Explorer is set to its highest safety setting, the associated script does not run, and you receive the following message:
NOT safe for initializing!

Note If you are building and testing different configurations of this sample, make sure that you refresh the Web page in the browser. If you do not refresh the page, you may be using the cached version of the control instead of the latest build.
For more information about the Safety APIs, see the Safety API reference in the ActiveX SDK online documentation.

For more information about code signing, see "Signing with Microsoft Authenticode Technology" in the ActiveX SDK online documentation.

For more information about Component Categories, see the "Component Categories" topic in the ActiveX SDK online documentation.

For more information about how to implement a Component Object Model (COM) interface in MFC, click the following article number to view the article in the Microsoft Knowledge Base:
141277 How to override an interface in an MFC application by using Visual C++
For in-depth information about how to develop an ActiveX control and how to deploy it on the Web, visit the following Microsoft Web site:
Note This is a "FAST PUBLISH" article created directly from within the Microsoft support organization. The information contained herein is provided as-is in response to emerging issues. As a result of the speed in making it available, the materials may include typographical errors and may be revised at any time without notice. See Terms of Use for other considerations.

Article ID: 164119 - Last Review: 01/12/2015 15:55:20 - Revision: 1.0

Microsoft Internet Explorer 5.0, Microsoft Internet Explorer 6.0, Microsoft Visual C++ 5.0 Enterprise Edition, Microsoft Visual C++ 5.0 Professional Edition

  • kbnosurvey kbarchive kbdownload kbfile kbinfo kbsample KB164119