管理与程序设计指南

宏开发技术

Net.Data 提供了几个允许用户为输入变量赋值的机制。为了确保宏以预期方式执行,宏应确认这些 输入变量。您的数据库和应用程序在设计时也应将用户对数据的访问限制在该用户被授权看到的范围内。

在编写 Net.Data 宏时,可以使用以下开发技术。这些技术将帮助您确保应用程序预期完成,并且对数据的访问仅限于正确授权的用户。

确保 Net.Data 变量在 URL 中不会被覆盖
用户在 URL 中对 Net.Data 变量的设置会覆盖宏中用于初始化变量的 DEFINE 语句 所产生的作用。这可能会改变宏执行的方式。为了避免这种可能性,可以使用 DTW_ASSIGN() 函数来 初始化 Net.Data 变量。

示例: 不使用 %DEFINE SHOWSQL="NO" 设置 Net.Data SHOWSQL 变量,而使用 @DTW_ASSIGN(SHOWSQL, "NO")。那么,诸如 SHOWSQL=YES 等查询字符串赋值就不会覆盖宏的设置了。

您可以使用 以下的某种方法在生产环境中禁用 SQL 语句的显示:

参见 Net.Data 参考的变量章节中有关 SHOWSQL 的内容,获取 SHOWSQL Net.Data 变量的语法和示例。

也可以使用 DTW_ASSIGN 来确保 其他 Net.Data 变量(例如 RPT_MAX_ROWS 或 START_ROW_NUM) 未被覆盖。参见 Net.Data 参考中的变量章节以了解有关这些变量的更多信息。

请确认 SQL 语句不能以可能改变应用程序预期行为的方式进行修改

对宏中的 SQL 语句添加一个 Net.Data 变量可以允许用户在执行 SQL 语句之前动态地改变该语句。宏的编写者应负责确认用户提供的输入值并确保包含变量引用的 SQL 语句不能以非预期的方式 进行修改。Net.Data 应用程序应确认用户从 URL 提供的输入值,这样,Net.Data 应用程序就 可以拒绝无效的输入。确认设计过程应包含以下步骤:

  1. 标识有效输入的语法;例如,客户 ID 必须以字母开头,并且只能包含字母数字字符。
  2. 确定在允许不正确的输入、人为的有害输入、为了访问 Net.Data 应用程序的内部内容而输入某些信息 的情况下可能存在哪些潜在的问题。
  3. 在满足应用程序需要的宏中包括输入验证语句。这样的验证取决于输入的语法以及如何使用。在比较简单的 情况中,它足以检查输入中的无效内容或调用 Net.Data 来验证输入类型。如果输入的语法更为复杂一些, 宏的开发者可能就不得不对输入进行部分或完全的语法分析以验证它是否有效。

例 1: 使用 DTW_POS() 字符串函数来验证 SQL 语句

%FUNCTION(DTW_SQL) query1() {  		
   select * from shopper where shlogid = '$(shlogid)'              
%}
shlogid 的值是一个购物者 ID。其作用是将 SELECT 语句返回的行限制在某些特定的行中, 这些行中包含有关由购物者 ID 所标识的购物者的信息。当然,如果字符串 "smith' or shlogid<>'smith" 被作为变量 shlogid 的值进行传递,则查询将变为:
select * from shopper where shlogid = 'smith' or shlogid<>'smith'

原来的 SQL SELECT 语句经过用户如此修改之后将返回整个购物者的表格。

Net.Data 字符串函数 可用于验证 SQL 语句未被用户以不恰当的方式修改。例如,以下逻辑可用于确保与 shlogid 变量相 关联的输入值仅有一个购物者 ID:

@DTW_POS(" ", $(shlogid), result)
%IF (result == "0")
  @query1()
%ELSE
       %{ perform some sort of error processing %}
%ENDIF

例 2:使用 DTW_TRANSLATE()

假定应用程序需要确认输入变量 num_orders 中所提供的值是一个整数。一种方法是 创建一个事务表格 trans_table,其中包含除数字字符 0-9 之外的所有键盘字符, 并使用 DTW_TRANSLATE 和 DTW_POS 字符串函数来确认输入:

@DTW_TRANSLATE(num_orders, "x", trans_table, "x", string_out) 
      
 @DTW_POS("x", string_out, result)
 
     %IF (result = "0")
 
%{ continue with normal processing %}
 
%ELSE
 
       %{ perform some sort of error processing %}
 
%ENDIF

请注意,浏览器前的用户无法修改存储过程中的 SQL 语句,并且用户提供的输入参数值 受到与输入参数相关联的 SQL 数据类型的约束。在使用 Net.Data 字符串函数确认用户输入值不可行的情况下, 可以使用存储过程。

请确保 INCLUDE 语句中的文件名未以可能改变应用程序预期行为的方式进行修改
如果使用 Net.Data 变量对具有 INCLUDE 语句的文件名指定值,则在执行 INCLUDE 文件之前不会 确定要包含的文件。如果您打算在宏中设置此变量的值,但不允许浏览器前的用户覆盖该宏 提供的值,则应使用 DTW_ASSIGN 而不是 DEFINE 来设置此变量的值。如果不打算让浏览器前的用户为文件名提供值, 则您的宏应确认提供的值。

示例:诸如 filename="../../x" 的 查询字符串赋值将导致从非 INCLUDE_PATH 配置语句正常指定的目录中包含文件。假定 Net.Data 初始化文件中包含以下路径配置语句:

INCLUDE_PATH /usr/lpp/netdata/include

而 Net.Data 宏中包含以下 INCLUDE 语句:

%INCLUDE "$(filename)"

查询字符串赋值 filename="../../x" 将包含文件 /usr/lpp/x,而这不是 INCLUDE_PATH 配置语句说明所期望的。

Net.Data 字符串函数可用于验证所提供的文件名对于应用程序来说是恰当的。例如, 以下逻辑可用来确保与文件名变量相关联的输入值不包含字符串 "..":

@DTW_POS("..", $(filename), result)
%IF (result > "0")
       %{ perform some sort of error processing %}
%ELSE
%{ continue with normal processing %}
%ENDIF 

设计数据库与查询,以便使用户请求无权访问有关其他用户的敏感数据
有些数据库设计为将敏感的用户数据收集在一个单独的表格中。除非 SQL SELECT 请求在某些方面 受到限制,否则这种方法可能会使 Web 浏览器前的任何用户都能够看到敏感数据。

示例:以下 SQL 语句返回由变量 order_rn 标识的某个订单的订单信息:

select setsstatcode, setsfailtype, mestname
	from   merchant, setstatus
	where  merfnbr   = setsmenbr
	and    setsornbr = $(order_rn)

这种方法允许浏览器前的用户随机指定订单号码, 这样,他们就可能获得其他客户订单的敏感信息。要防止此类泄密的一个方法是进行以下更改:

例如,如果 shlogid 是包含与订单相关联的客户 ID 的列,SESSION_ID 是一个包含 浏览器前用户的授权 ID 的 Net.Data 变量,则可以用以下语句来替换前面的 SELECT 语句:

select setsstatcode, setsfailtype, mestname
  from   merchant, setstatus
  where  merfnbr   = setsmenbr
  and    setsornbr = $(order_rn)
  and    shlogid   = $(SESSION_ID)

使用 Net.Data 隐藏变量
您可以使用 Net.Data 隐藏变量,对于那些用 Web 浏览器查看您的 HTML 源码的用户 隐藏 Net.Data 宏的各种特性。例如,您可以隐藏数据库的内部结构。参见隐藏变量,以获取有关隐藏变量的更多信息。

来自用户的请求确认信息
您可以根据用户提供的输入创建自己的保护方案。例如,您可以通过 HTML 表请求来自用户的验证信息,并使用 Net.Data 宏从数据库中检索到的数据进行验证, 也可以从 Net.Data 宏中所定义的函数中调用一个外部程序。

有关保护资产的更多信息,参见以下 Web 站点中有关“经常询问的 问题”(FAQ) 的 Internet 安全性列表:

http://www.w3.org/Security/Faq


[ 页的顶部 | 上一页 | 下一页 | 目录 | 索引 ]