浏览器内的数据操纵
有一类浏览器插件允许用户篡改页面上的头部元素和表单元素。使用 Tamper Data(一个 Mozilla 插件),可以很容易地操纵包含许多隐藏文本字段的简单表单,从而向 PHP 和 MySQL 发送指令。
用户在点击表单上的 Submit 之前,他可以启动 Tamper Data。在提交表单时,他会看到表单数据字段的列表。Tamper Data 允许用户篡改这些数据,然后浏览器完成表单提交。
让我们回到前面建立的示例。已经检查了字符串长度、清除了 HTML 标记并删除了十六进制字符。但是,添加了一些隐藏的文本字段,如下所示:
if ( $_POST [ ' submit ' ] == " go " ){
// strip_tags
$name = strip_tags ( $_POST [ ' name ' ]);
$name = substr ( $name , 0 , 40 );
// clean out any potential hexadecimal characters
$name = cleanHex( $name );
// continue processing....
}
function cleanHex( $input ){
$clean =
preg_replace ( " ![][xX]([A-Fa-f0-9]{1,3})! " , "" , $input );
return $clean ;
}
?>
< form action =
" <?php echo $_SERVER['PHP_SELF'];?> " method = " post " >
< p >< label for = " name " > Name </ label >
< input type =
" text " name = " name " id = " name " size = " 20 " maxlength = " 40 " /></ p >
< input type = " hidden " name = " table " value = " users " />
< input type = " hidden " name = " action " value = " create " />
< input type = " hidden " name = " status " value = " live " />
< p >< input type = " submit " name = " submit " value = " go " /></ p >
</ form >
注意,隐藏变量之一暴露了表名:users
。还会看到一个值为 create
的 action
字段。只要有基本的 SQL 经验,就能够看出这些命令可能控制着中间件中的一个 SQL 引擎。想搞大破坏的人只需改变表名或提供另一个选项,比如 delete
。
图 1 说明了 Tamper Data 能够提供的破坏范围。注意,Tamper Data 不但允许用户访问表单数据元素,还允许访问 HTTP 头和 cookie。
图 1. Tamper Data 窗口
要防御这种工具,最简单的方法是假设任何用户都可能使用 Tamper Data(或类似的工具)。只提供系统处理表单所需的最少量的信息,并把表单提交给一些专用的逻辑。例如,注册表单应该只提交给注册逻辑。
如果已经建立了一个通用表单处理函数,有许多页面都使用这个通用逻辑,那该怎么办?如果使用隐藏变量来控制流向,那该怎么办?例如,可能在隐藏表单变量中指定写哪个数据库表或使用哪个文件存储库。有 4 种选择:
- 不改变任何东西,暗自祈祷系统上没有任何恶意用户。
- 重写功能,使用更安全的专用表单处理函数,避免使用隐藏表单变量。
- 使用
md5()
或其他加密机制对隐藏表单变量中的表名或其他敏感信息进行加密。在 PHP 端不要忘记对它们进行解密。 - 通过使用缩写或昵称让值的含义模糊,在 PHP 表单处理函数中再对这些值进行转换。例如,如果要引用
users
表,可以用u
或任意字符串(比如u8y90x0jkL
)来引用它。
后两个选项并不完美,但是与让用户轻松地猜出中间件逻辑或数据模型相比,它们要好得多了。
现在还剩下什么问题呢?远程表单提交。