Skip to main content

用于 Building Block 开发人员的安全 API

Blackboard 已与 Open Web Application Project (OWASP) 的企业安全 API (ESAPI) 中的最佳实践开源安全库集成。默认情况下,此安全库通过名为“ESAPI 安全模块”的构建块安装在 Blackboard 上,并且是系统作所必需的。Blackboard 强烈建议所有 Building Block 开发人员利用这个基于 OWASP ESAPI for JavaESAPI for JavaScript 的新安全 API。这些安全 API 更改不仅包括最佳实践实现,还通过一致的命名法提高了方法的易用性。

注意

在以后的版本中,ESAPI 安全模块构建块 API 是 Blackboard 核心代码的一部分,默认情况下可用。

作为安全编码实践的一部分,可能受用户影响的输入(无论是否可信)都应在处理(输入验证)和显示(输出验证或转义)之前在服务器端进行验证。这有助于确保系统弹性并防止跨站点脚本等安全问题。

输入验证

从请求接收输入时,请始终验证并始终在服务器端验证。Blackboard 已实现几个需要验证的常用用例。下面提供了一些示例。

  • blackboard.platform.security.ValidationUtility.isValidDirectoryPath( 字符串 )

  • blackboard.platform.security.ValidationUtility.isValidGuid( 字符串 )

  • blackboard.platform.security.ValidationUtility.isValidEnumeratedType( 枚举, 字符串 )

输出验证/编码/转义

显示任何输入时,请始终确保它在将嵌入的正确上下文中显示:

Java 方法

  • blackboard.platform.security.EscapeUtility.escapeForHTML ( 字符串 )

  • blackboard.platform.security.EscapeUtility.escapeForHTMLAttribute ( 字符串 )

  • blackboard.platform.security.EscapeUtility.escapeForJavascript ( 字符串 )

  • blackboard.platform.security.EscapeUtility.escapeForUrl ( 字符串 )

  • blackboard.platform.security.EscapeUtility.escapeForCSS ( 字符串 )

  • blackboard.platform.security.EscapeUtility.escapeForXML ( 字符串 )

  • blackboard.platform.security.EscapeUtility.escapeForXMLAttribute ( 字符串 )

JSP 方法

  • ${bbNG:EscapeForHTML( String )}

  • ${bbNG:EscapeForJavascript( String )}

  • ${bbNG:EscapeForURL( String )}

  • ${bbNG:EscapeForCSS( String )}

  • ${bbNG:EscapeForXML( String )}

  • ${bbNG:EscapeForXMLAttribute( String )}

JavaScript 方法

所有 ESAPI for JavaScript 方法都可供使用。更常用的方法列表:

  • $ESAPI.encoder().canonicalize( String )

  • $ESAPI.encoder().encodeForHTML( String )

  • $ESAPI.encoder().encodeForHTMLAttribute( String )

  • $ESAPI.encoder().encodeForCSS( String )

  • $ESAPI.encoder().encodeForJavaScript( String )

  • $ESAPI.encoder().encodeForURL( String )

破译加密文本

破译加密上下文

要在上下文传递期间加密数据,Blackboard 和外部 URL 必须能够访问相同的上下文加密密钥。必须从管理员面板上提供的管理上下文加密密钥功能创建密钥。创建密钥后,必须将其下载并分发到接受上下文的外部服务器。

代码示例

下载上下文加密密钥后,必须将其提供给将通过上下文传递接收加密数据的 URL。下面的代码示例演示了如何在传递外部 URL 时以编程方式破译外部 URL 上的加密上下文数据。

目标 URL 指示的对象(在本例中为 index.jsp)可以按如下方式解密上下文(导入 blackboard.client.decryption.*):

String context = request.getParameter("context");//if isEncryptionEnabled = false, base 64 encoding will be used instead //of encryptionboolean isEncryptionEnabled = true;ContextDecryptor bfd = ContextDecryptorFactory.getContextDecryptor(isEncryptionEnabled ); // retrieve the Blackboard encryption key as a File or InputStream File key = new File( strKeyLocation ); // or InputStream key = // implementation detail...// to simply decrypt the context string String decryptedContext = bfd.decrypt( context, key );// or, to get a HashMap of all key-value pairsHashMap map = bfd.parseEncryptedContext( context, key );// then search the HashMap for an expected value, and continue.if (map.containsKey( "user" ){ // execute...}

解析多个键

当外部 URL 和 Blackboard 之间存在一对一关系时,上面的代码示例非常有用。对于外部 URL 支持多个 Blackboard 实例的构建块的实例,实例的主机名可用于处理多个键。

在下面的示例中,密钥是通过与 Blackboard 实例或虚拟安装的主机名相关联来找到的。在这种情况下,主机名是 physics.your机构.com。由于客户端解密代码能够将解密密钥传递给 ContextDecryptor 对象,因此客户端服务器必须能够将主机名映射到其适当的密钥(通常作为文件访问,但也可以是 动态)。

Building Block 服务器开发人员可以编写一个简单的包装器,用于:

  1. 从请求中提取主机名。

  2. 在 hostname-encryptionKey 映射中查找加密密钥文件。

  3. 将加密密钥传递给 decrypt() 方法。

由客户端服务器实用程序对象实现的伪代码包装器:

/**

* 实用程序伪代码

*/

decryptByHostname( HttpServletRequest 请求)

{

从请求中获取上下文参数

String context = request.getParameter("context");

确定上下文是否已加密

String strEncryptInd = request.getParameter("encrypt");

if ( (strEncryptInd != null) && (strEncryptInd.equalsIgnoreCase("y")) )

{

isEncrypted = true;

}

如果是Encrypted,则查找密钥

key = null;

if (是加密)

{

从 HttpUtils.getRequestURL().getHost() 获取主机名;

get 键映射,可能存储为格式为

// physics.yourinstitution.com= /key/file/location/physics_yourinstitution_com/key.sec

从地图中获取加密密钥作为 File 或 动态,

取决于客户端实现详细信息(如果

// isEncrypted= false, and Base64Encoding is used instead)

}

ContextDecryptor decryptor =

ContextDecryptorFactory.getContextDecryptor(isEncrypted);

然后返回上下文中传递的值作为

键值对的 HashMap

HashMap values = decryptor.parseEncryptedContext(context, key);

或字符串

String values = decryptor.decrypt (context, key);

返回值;

}