SAMPLE: Implementing IObjectSafety in an ActiveX Control

Last reviewed: January 19, 1998
Article ID: Q164119

The information in this article applies to:

  • Microsoft ActiveX SDK, version 1.0
  • Microsoft Internet Client SDK, versions 4.0, 4.01
  • Microsoft Visual C++, 32-bit Editions, versions 4.1, 4.2, 5.0

SUMMARY

This sample shows the modifications that can be made to an MFC-based ActiveX control to indicate that the control is safe for scripting and safe to initialize from persistent data.

The following file is available for download from the Microsoft Software Library:

 ~ Safectl.exe (size: 65017 bytes) 

For more information about downloading files from the Microsoft Software Library, please see the following article in the Microsoft Knowledge Base:

   ARTICLE-ID: Q119591
   TITLE     : How to Obtain Microsoft Support Files from Online Services


MORE INFORMATION

Internet Explorer 3.0 (IE3) allows users to add code in the form of ActiveX controls to their Web pages. The <OBJECT> tag is used to specify a control. Once a control is instantiated, its attributes can be set through the control’s persistence interfaces. For example, for each <PARAM> tag IE3 encounters within the context of an <OBJECT> tag while parsing an HTML page, IE3 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 IE3 security settings, which are accessible via the Security tab of the IE3 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, IE3 queries the control for IObjectSafety. If supported, IE3 then calls the SetInterfaceSafetyOptions 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 safe on some interfaces but not on others, and in this example that is unimportant. The sample implementation merely 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 IObjectSafety::SetInterfaceSafetyOptions should return S_OK. Otherwise, E_FAIL should be returned.

Before allowing any scripts embedded in the page to be run, IE3 similarly calls through the control’s IObjectSafety:: SetInterfaceSafetyOptions 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, IE3 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 the IE3 safety level is set to high, the default, IE3 will not initialize the control’s properties, nor will it execute any scripts embedded in the page. In this scenario, end users will encounter a dialog box containing 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.

How does a developer determine that their control is safe? The following is a list of guidelines taken from Paul Johns' article on signing and marking ActiveX controls (see the REFERENCES section below):
  • The control does not manipulate the file system.
  • The control does not manipulate the registry (except to register and 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 provided by the user or about that user.
  • The control was tested in a variety of scenarios.

If a control author has verified that the above criteria have been met in addition to any others they can think of, they should consider supporting both IObjectSafety and registering their control as implementing the appropriate component categories. For a discussion of the advantages and disadvantages of each of these methods, see the corresponding section in Paul Johns' signing and marking article cited below.

To Compile

Building the sample requires Microsoft Visual C++ version 5.0. Once the files are extracted from the archive, load the project Safectl.dsw into Microsoft Developer Studio and build the project. As part of the build process, the control should register itself.

WARNING: Before modifying the sample through the manipulation of the two pre-processor symbols mentioned below, you will need to unregister the control if it has been built or registered on the machine already. This can be done by running 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. From the Tools menu, click customize and then select 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 adding or removing the sample specific preprocessor definitions.

To build the control so that it registers itself as implementing the safe for initializing and safe for scripting component categories, use the following steps:

  1. From the Project menu choose Settings.

  2. Under the C++ tab define the following preprocessor definition:

          L_USE_COMCAT
    

  3. Close the Settings dialog box by clicking OK, and 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 pre-processor symbols. Observe that these symbols are specific to this project. By default, the build settings of the project define both pre-processor symbols.

To Run

Once the sample control has been built and has been registered successfully, launch IE3 and load the page, Safectl.htm, 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!" Clicking on the control should yield a message box that reads "I must be safe for scripting!" Otherwise, with IE3 set to its highest safety setting the caption reads "NOT safe for initializing!" and clicking on the control does not produce a message box since the associated script does not execute.

NOTE: If you are building and testing different configurations of this sample, make sure that you refresh the Web page in the browser or you may be using the cached version of the control instead of the latest build.

REFERENCES

For more information on the Safety APIs, see the Safety API reference in the ActiveX SDK online documentation.

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

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

For additional information on implementing a Component Object Model (COM) interface in MFC, please see the following article in the Microsoft Knowledge Base:

   ARTICLE-ID: Q141277
   TITLE     : How to Override an Interface in an MFC Application

For in depth coverage on developing an ActiveX control and deploying it on the Web, see Paul Johns' article "The ABCs of MFC ActiveX Controls." For topics relevant to this discussion see his companion article "Signing and Marking ActiveX Controls."

   http://microsoft.com/intdev/controls/stoplite
   http://microsoft.com/intdev/controls/signmark-f.htm


Additional query words: SAFE SAFETY SOFTLIB
Keywords : AXSDKControls AXSDKSripting kbfile kbprg
Version : 1.0,4.01,4.10,4.20
Platform : NT WINDOWS
Issue type : kbfile
Solution Type : kbsample


THE INFORMATION PROVIDED IN THE MICROSOFT KNOWLEDGE BASE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. MICROSOFT DISCLAIMS ALL WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL MICROSOFT CORPORATION OR ITS SUPPLIERS BE LIABLE FOR ANY DAMAGES WHATSOEVER INCLUDING DIRECT, INDIRECT, INCIDENTAL, CONSEQUENTIAL, LOSS OF BUSINESS PROFITS OR SPECIAL DAMAGES, EVEN IF MICROSOFT CORPORATION OR ITS SUPPLIERS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. SOME STATES DO NOT ALLOW THE EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES SO THE FOREGOING LIMITATION MAY NOT APPLY.

Last reviewed: January 19, 1998
© 1998 Microsoft Corporation. All rights reserved. Terms of Use.