作者:老葛,北京亚艾元软件有限责任公司,http://www.yaiyuan.com
check_plain做两件事情,一个是把HTML标签转义,二是检查字符串是不是UTF-8的。这两点都能帮我们防止XSS攻击。
我们举个例子,来看这段代码:
$output ="";
$user_input = '<script src=”http://evil.example.com/xss.js”></script>';
$output = check_plain($user_input);
return $output;
用户的输入就是前面我们所给的一段恶意脚本,返回的输出已经经过了转义:
我们看到此时的<script>标签已经是灰色的了,而不是蓝色的了。我们可以在页面的正文中看到对应的文本,此时的输入已经没有任何危害了。对应的页面内容如下所示:
此时,如果我们把这个html页面保存起来,然后再用写字板打开对应的htm文件,我们会看到真实的输出:
<script src=”http://evil.example.com/xss.js”></script>
此时我们已经把“<”、“〉”作了转义,我们通过浏览器看到的则是用户的实际输入。
如果我们的代码这样写:
$output ="";
$user_input = '<script src=”http://evil.example.com/xss.js”></script>';
//$output = check_plain($user_input);
$output = $user_input;
return $output;
我们通过firebug看到的输出则是:
对应的页面则没有内容输出。
Drupal自带的一些函数,内置了对check_plain的支持,比如:
t():占位符比如'%name'、'@name'将被处理成为纯文本,如果想在这里使用html的,则使用'!name'。
l():链接的标题,处理成为纯文本。如果想使用html的话,需要将html参数设置为TRUE。
菜单项的标题,和面包屑的标题,自动使用check_plain。
drupal_placeholder($text):占位符文本内置支持check_plain。
区块描述内置支持check_plain。
theme_username输出用户名时,内置支持check_plain。
表单元素的#default_value属性自动支持check_plain。
如果Drupal已经内置支持了check_plain,我们就不需要重复使用它了。比如:
$form['good'] = array(
'#type' => 'textfield',
'#default_value' => $user_input,
);
这些写就可以了。如果加上check_plain,就多余了。
$form['bad'] = array(
'#type' => 'textfield',
'#default_value' => check_plain($user_input), //这里使用check_plain就多余了。
);
有些地方,则需要自己明确的调用check_plain。比如页面标题,区块标题,Watchdog消息,表单元素的#description、#title属性、#value属性、#options属性。
比如:
drupal_set_title($user_input); // 存在安全隐患, drupal_set_title(check_plain($user_input)); // 正确。
//正确写法
$form['good'] = array(
'#type' => 'textfield',
'#title' => check_plain($user_input),
);
//错误写法
$form['bad'] = array(
'#type' => 'textfield',
'#title' => $user_input,
);