ActiveX的初始化和脚本安全
2011-04-29 15:17
519 查看
转自:http://fjf122.blog.163.com/blog/static/72132128201074115831658/
1、两个概念
> 控件初始化:用持久性数据来初始化控件,包括本地和远程;
> 控件可脚本编码:提供一系列的方法、属性、事件供脚本编码。
这两种方式都需要安全机制来保证系统安全,包括控件在初始化时确保安全(压缩和解压缩时不包含木马文件),以及编码时的安全(安全得修改系统配置等)。
2、控件安全问题及解决办法
> 初始化安全
当一个控件初始化,它可以接收来自任意IPersist *接口,无论是从本地或远程URL(数据)用于初始化的状态。这是一个潜在的安全隐患,因为数据可能来自不受信任的来源。
> 脚本安全
代码签名可以保证这些代码是值得信赖的用户。但是,允许ActiveX控件是从脚本访问引起了若干新的安全问题。即使是已知在一个用户手中安全的控件,但由一个不受信任的脚本自动化时未必是安全的。例如,Microsoft Word是一个受信的工具,但一种恶意的脚本可以使用它的自动化模式,删除用户的计算机上的文件,安装的宏病毒,甚至更糟的事。
两种解决办法标记控件初始化及脚本时为安全。一是使用组件类别管理器(Component Categories Manager)在系统注册表中创建相应的条目。IE浏览器载入您的控制之前检查注册表,以确定这些项是否出现。第二种方法是在您的控件中实现一个名为IObjectSafety的接口。如果Internet Explorer确定您的控件支持IObjectSafety,它载入您的控件之前调用IObjectSafety::SetInterfaceSafetyOptions方法,以确定是否您的控件初始化安全。
以下部分描述第一种方法。
3、使用组件类别管理器(Component Categories Manager)
如果一个控件使用组件类别管理器被注册为安全,则该控件包含一个Implemented Categories项,其中包含一个或两个注册表项的子项。其中一个子项设置控件支持安全初始化的,而另一个子项设置控件支持安全脚本。安全初始化子项对应于CATID_SafeForInitializing;安全脚本子项对应于CATID_SafeForScripting。 (不同其它组件定义在Comcat.h文件中,为安全初始化和脚本的子项定义在Objsafe.h中。)
如下图所示控件标记脚本安全 (7DD95801-9882-11CF-9FA9-00AA006C42C4)和初始化安全(7DD95802-9882-11CF-9FA9-00AA006C42C4).
> 如何注册控件安全
系统注册表包含一个Component Categories项,它列出了安装于系统的组件或应用程序所需或所实现的功能性分类。
如下图,CATID_SafeForScripting (7DD95801-9882-11CF-9FA9-00AA006C42C4) 和 CATID_SafeForInitializing (7DD95802-9882-11CF-9FA9-00AA006C42C4)都在列表中。
第一步:创建Component Categories子项
要创建相应的组件类别的子项,您的控件必须完成以下步骤:
1.创建一个组件分类管理器(Component Categories Manager)实例,并检索ICatRegister接口地址。
2.设置CATEGORYINFO结构的适当成员。
3.调用ICatRegister::RegisterCategories方法,传递的初始化CATEGORYINFO结构的地址。
示例代码如下:
第二步:实现分类项(Implemented Categories项)
实现分类项包含以下几个步骤:
1. 创建一个组件分类管理器(Component Categories Manager)实例,并检索ICatRegister接口地址。
2. 调用ICatRegister::RegisterClassImplCategories方法,传递该控件的类标识符(CLSID)和必要的类ID作为参数。
示例代码如下:
第三步
接着通过控件的DllRegisterServer函数调用实现安全初始化和脚本分类的注册。
DllRegisterServer由Component Object Model (COM)调用,来为控件支持的所有类创建注册表条目。
示例代码如下:
> 卸载控件:
与注册控件相对应,如果要卸载一个已注册的控件,则是通过COM调用控件的DllUnregisterServer函数来删除相应的注册表项。
先编辑注销函数,如下:
1. 创建一个组件分类管理器(Component Categories Manager)实例,并检索ICatRegister接口地址。
2. 调用ICatRegister::UnRegisterClassImplCategories方法,传递该控件的类标识符(CLSID)和必要的类ID作为参数。
示例代码:
然后调用DllUnregisterServer实现注销,示例代码如下:
代码和图片参考自:http://msdn.microsoft.com/ko-kr/library/aa751977(en-us,VS.85).aspx
1、两个概念
> 控件初始化:用持久性数据来初始化控件,包括本地和远程;
> 控件可脚本编码:提供一系列的方法、属性、事件供脚本编码。
这两种方式都需要安全机制来保证系统安全,包括控件在初始化时确保安全(压缩和解压缩时不包含木马文件),以及编码时的安全(安全得修改系统配置等)。
2、控件安全问题及解决办法
> 初始化安全
当一个控件初始化,它可以接收来自任意IPersist *接口,无论是从本地或远程URL(数据)用于初始化的状态。这是一个潜在的安全隐患,因为数据可能来自不受信任的来源。
> 脚本安全
代码签名可以保证这些代码是值得信赖的用户。但是,允许ActiveX控件是从脚本访问引起了若干新的安全问题。即使是已知在一个用户手中安全的控件,但由一个不受信任的脚本自动化时未必是安全的。例如,Microsoft Word是一个受信的工具,但一种恶意的脚本可以使用它的自动化模式,删除用户的计算机上的文件,安装的宏病毒,甚至更糟的事。
两种解决办法标记控件初始化及脚本时为安全。一是使用组件类别管理器(Component Categories Manager)在系统注册表中创建相应的条目。IE浏览器载入您的控制之前检查注册表,以确定这些项是否出现。第二种方法是在您的控件中实现一个名为IObjectSafety的接口。如果Internet Explorer确定您的控件支持IObjectSafety,它载入您的控件之前调用IObjectSafety::SetInterfaceSafetyOptions方法,以确定是否您的控件初始化安全。
以下部分描述第一种方法。
3、使用组件类别管理器(Component Categories Manager)
如果一个控件使用组件类别管理器被注册为安全,则该控件包含一个Implemented Categories项,其中包含一个或两个注册表项的子项。其中一个子项设置控件支持安全初始化的,而另一个子项设置控件支持安全脚本。安全初始化子项对应于CATID_SafeForInitializing;安全脚本子项对应于CATID_SafeForScripting。 (不同其它组件定义在Comcat.h文件中,为安全初始化和脚本的子项定义在Objsafe.h中。)
如下图所示控件标记脚本安全 (7DD95801-9882-11CF-9FA9-00AA006C42C4)和初始化安全(7DD95802-9882-11CF-9FA9-00AA006C42C4).
> 如何注册控件安全
系统注册表包含一个Component Categories项,它列出了安装于系统的组件或应用程序所需或所实现的功能性分类。
如下图,CATID_SafeForScripting (7DD95801-9882-11CF-9FA9-00AA006C42C4) 和 CATID_SafeForInitializing (7DD95802-9882-11CF-9FA9-00AA006C42C4)都在列表中。
第一步:创建Component Categories子项
要创建相应的组件类别的子项,您的控件必须完成以下步骤:
1.创建一个组件分类管理器(Component Categories Manager)实例,并检索ICatRegister接口地址。
2.设置CATEGORYINFO结构的适当成员。
3.调用ICatRegister::RegisterCategories方法,传递的初始化CATEGORYINFO结构的地址。
示例代码如下:
#include "comcat.h" HRESULT CreateComponentCategory(CATID catid, WCHAR *catDescription) { ICatRegister *pcr = NULL ; HRESULT hr = S_OK ; hr = CoCreateInstance(CLSID_StdComponentCategoriesMgr, NULL, CLSCTX_INPROC_SERVER, IID_ICatRegister, (void**)&pcr); if (FAILED(hr)) return hr; // Make sure the HKCR/Component Categories/{..catid...} // key is registered. CATEGORYINFO catinfo; catinfo.catid = catid; catinfo.lcid = 0x0409 ; // english int len; // Make sure the provided description is not too long. // Only copy the first 127 characters if it is. // The second parameter of StringCchLength is the maximum // number of characters that may be read into catDescription. // There must be room for a NULL-terminator. The third parameter // contains the number of characters excluding the NULL-terminator. hr = StringCchLength(catDescription, STRSAFE_MAX_CCH, &len); if (SUCCEEDED(hr)) { if (len>127) { len = 127; } } else { TODO: Write an error handler; } // The second parameter of StringCchCopy is 128 because you need // room for a NULL-terminator. hr = StringCchCopy(catinfo.szDescription, len + 1, catDescription); // Make sure the description is null terminated. catinfo.szDescription[len + 1] = '/0'; hr = pcr->RegisterCategories(1, &catinfo); pcr->Release(); return hr; } |
实现分类项包含以下几个步骤:
1. 创建一个组件分类管理器(Component Categories Manager)实例,并检索ICatRegister接口地址。
2. 调用ICatRegister::RegisterClassImplCategories方法,传递该控件的类标识符(CLSID)和必要的类ID作为参数。
示例代码如下:
#include "comcat.h" HRESULT RegisterCLSIDInCategory(REFCLSID clsid, CATID catid) { // Register your component categories information. ICatRegister *pcr = NULL ; HRESULT hr = S_OK ; hr = CoCreateInstance(CLSID_StdComponentCategoriesMgr, NULL, CLSCTX_INPROC_SERVER, IID_ICatRegister, (void**)&pcr); if (SUCCEEDED(hr)) { // Register this category as being "implemented" by the class. CATID rgcatid[1] ; rgcatid[0] = catid; hr = pcr->RegisterClassImplCategories(clsid, 1, rgcatid); } if (pcr != NULL) pcr->Release(); return hr; } |
接着通过控件的DllRegisterServer函数调用实现安全初始化和脚本分类的注册。
DllRegisterServer由Component Object Model (COM)调用,来为控件支持的所有类创建注册表条目。
示例代码如下:
STDAPI DllRegisterServer(void) { HRESULT hr; // return for safety functions AFX_MANAGE_STATE(_afxModuleAddrThis); if (!AfxOleRegisterTypeLib(AfxGetInstanceHandle(), _tlid)) return ResultFromScode(SELFREG_E_TYPELIB); if (!COleObjectFactoryEx::UpdateRegistryAll(TRUE)) return ResultFromScode(SELFREG_E_CLASS); // Mark the control as safe for initializing. hr = CreateComponentCategory(CATID_SafeForInitializing, L"Controls safely initializable from persistent data!"); if (FAILED(hr)) return hr; hr = RegisterCLSIDInCategory(CLSID_SafeItem, CATID_SafeForInitializing); if (FAILED(hr)) return hr; // Mark the control as safe for scripting. hr = CreateComponentCategory(CATID_SafeForScripting, L"Controls safely scriptable!"); if (FAILED(hr)) return hr; hr = RegisterCLSIDInCategory(CLSID_SafeItem, CATID_SafeForScripting); if (FAILED(hr)) return hr; return NOERROR; } |
与注册控件相对应,如果要卸载一个已注册的控件,则是通过COM调用控件的DllUnregisterServer函数来删除相应的注册表项。
先编辑注销函数,如下:
1. 创建一个组件分类管理器(Component Categories Manager)实例,并检索ICatRegister接口地址。
2. 调用ICatRegister::UnRegisterClassImplCategories方法,传递该控件的类标识符(CLSID)和必要的类ID作为参数。
示例代码:
HRESULT UnRegisterCLSIDInCategory(REFCLSID clsid, CATID catid) { ICatRegister *pcr = NULL ; HRESULT hr = S_OK ; hr = CoCreateInstance(CLSID_StdComponentCategoriesMgr, NULL, CLSCTX_INPROC_SERVER, IID_ICatRegister, (void**)&pcr); if (SUCCEEDED(hr)) { // Unregister this category as being "implemented" by the class. CATID rgcatid[1] ; rgcatid[0] = catid; hr = pcr->UnRegisterClassImplCategories(clsid, 1, rgcatid); } if (pcr != NULL) pcr->Release(); return hr; } |
STDAPI DllUnregisterServer(void) { HRESULT hr; // HResult used by Safety Functions AFX_MANAGE_STATE(_afxModuleAddrThis); if (!AfxOleUnregisterTypeLib(_tlid)) return ResultFromScode(SELFREG_E_TYPELIB); if (!COleObjectFactoryEx::UpdateRegistryAll(FALSE)) return ResultFromScode(SELFREG_E_CLASS); // Remove entries from the registry. hr=UnRegisterCLSIDInCategory(CLSID_SafeItem, CATID_SafeForInitializing); if (FAILED(hr)) return hr; hr=UnRegisterCLSIDInCategory(CLSID_SafeItem, CATID_SafeForScripting); if (FAILED(hr)) return hr; return NOERROR; } |
相关文章推荐
- 注册表中启用对没有标记为安全的 ActiveX 控件进行初始化和脚本运行
- 如何将MFC ActiveX 控件标记为可安全编写脚本和初始化
- 如何将 MFC ActiveX 控件作为安全标记为脚本和初始化
- ActiveX的初始化和脚本安全
- 如何将 MFC ActiveX 控件作为安全标记为脚本和初始化
- 如何将 MFC ActiveX 控件标记为脚本和初始化安全
- 如何将MFC ActiveX 控件标记为可安全编写脚本和初始化
- ActiveX的初始化和脚本安全
- 如何标记为安全 MFCActiveX 控件对于脚本和初始化
- 如何标记为安全 MFCActiveX 控件对于脚本和初始化
- linux服务器安全初始化shell脚本
- MFC OCX控件实现安全初始化和脚本安全的方法
- ActiveX控件实现安全的初始化和脚本
- 标记为可安全执行脚本的Activex
- ActiveX控件实现安全的初始化和脚本
- \t\t用C#编写ActiveX控件 自定义html控件 ActiveX 控件注册 标记Activex控件为脚本安全
- ActiveX控件的安全初始化和脚本操作 和 数字签名SIGN
- ActiveX控件实现安全的初始化和脚本
- Linux服务器安全初始化自选安装Shell脚本
- MFC OCX控件实现安全初始化和脚本安全的方法http://blog.csdn.net/xiliang_pan/article/details/8264685