Drupal专业开发指南 第20章 编写安全的代码(4)

权限和页面回调
          译者:老葛 Eskalate科技公司
当你编写自己的模块时,需要注意的另一个方面是“access”键,你会在菜单钩子中定义的每个菜单项中用到它。在前面我们用来说明不安全代码的例子中,我们这样使用“access”键:
/*
* Implementation of hook_menu()
*/
function insecure_menu($may_cache) {
$items = array();
if ($may_cache) {
$items[] = array(
'path' => 'insecure',
'title' => t('Insecure Module'),
'description' => t('Example of how not to do things.'),
'callback' => 'insecure_code',
'access' => user_access('access content')
);
}
return $items;
}
 
一个非常重要的一个问题是允许谁访问这个回调函数。 “access content”(“访问内容”)权限是个很泛的权限。你可能想使用hook_perm()来定义你自己的权限,并使用它们来保护你的菜单回调函数。例如,你可以定义一个“access insecure content”(“访问不安全内容”)权限,并使用它。(更多详细信息可参看第4章的“访问控制”部分)。
由于你实现的菜单钩子实际上就是个门卫,它允许或者拒绝用户对菜单钩子后面代码的访问(通过回调),对于你在这里使用哪些权限,你需要认真的考虑一些。
 
对邮件头部进行编码
当你编写的代码需要使用用户来构建 e-mail消息时,需要考虑一下两点:
1. E-mail头部用提示(line feed)来分隔(只有在提示后面没有空格或者tab键时才被作为头部分隔符)
2..如果你没有检查用户的输入是否包含提示(line feed)的话,那么用户就可以在邮件的主体中注入它们自己的头部。
例如,假如你希望用户为他 /她的消息输入一个标题,而用户输入了一下内容,它包含转义的提示(line feed) (%0A)和空格(%20)字符:
Have a nice day%0ABcc:spamtarget@example.com%0A%0AL0w%20c0st%20mortgage!
 
结果将如下所示:
Subject: Have a nice day
Bcc: spamtarget@example.com
L0w c0st mortgage!
...
 
因此, Drupal内置的邮件函数drupal_mail()使用mime_header_encode()来过滤所有的头部。所有的不能打印的字符将被根据RFC 2047编码为ASCII可打印的字符,这样就消除了潜在的风险。这涉及到在字符前面添加前缀=?UTF-8?B?,接着输出基于64位编码的字符,再加上?=。
我们鼓励你使用drupal_mail();如果你不使用它的话,那么你需要自己直接调用mime_header_encode()。
SSL支持
默认情况下, Drupal通过HTTP使用纯文本来处理用户登录。然而,如果你的web服务器支持HTTPS的话,那么Drupal也可以通过HTTPS来处理登录。此时不需要做任何修改。
 
独立的PHP
偶尔,你可能需要编写一个独立的 .php文件来代替将代码放到Drupal的模块中。当你这样做时,你需要仔细的考虑安全性。假如,当你正在测试你的网站时,你快速的编写了一些有点垃圾的代码用来将用户插入到数据库中,这样你就可以使用多用户来测试站点性能了:
 
<?php
/**
* This script generates users for testing purposes.
*/
// These two lines are all that is needed to have full
// access to Drupal's functionality.
include_once 'includes/bootstrap.inc';
drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);
db_query('DELETE FROM {users} WHERE uid > 1'); // Whoa!
for ($i = 2; $i <= $num; $i++) {
$uid = $i;
$name = md5($i);
$mail = $name .'@localhost';
$status = 1;
db_query("INSERT INTO {users} (uid, name, mail, status, created, access)
VALUES (%d, '%s', '%s', %d, %d, %d)", $uid, $name, $mail, $status, time(),
time());
}
db_query("UPDATE {sequences} SET id = %d WHERE name = 'users_uid'", $uid);
}
这对于测试很有用,当时如果你一不小心把这个脚本放到了你真实的站点上,那么将会发生什么呢?任何发现了指向你的这个脚本的人都可以使用一个简单的请求来删除你数据库中的用户数据。这就是为什么安全检查这么重要,即便是对于一次性的脚本来说,也需要包含它,如下所示:
<?php
/**
* This script generates users for testing purposes.
*/
// These two lines are all that is needed to have full
// access to Drupal's functionality.
include_once 'includes/bootstrap.inc';
drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);
// Security check; only superuser may execute this.
if ($user->uid != 1) {
print t('Not authorized.');
exit();
}
db_query('DELETE FROM {users} WHERE uid > 1'); // Whoa!
for ($i = 2; $i <= $num; $i++) {
$uid = $i;
$name = md5($i);
$mail = $name .'@localhost';
$status = 1;
db_query("INSERT INTO {users} (uid, name, mail, status, created, access)
VALUES (%d, '%s', '%s', %d, %d, %d)", $uid, $name, $mail, $status, time(),
time());
}
db_query("UPDATE {sequences} SET id = %d WHERE name = 'users_uid'", $uid);
}
 
通过这个例子领会到以下两点:
1.即便是在快速编写的脚本中也要编写安全检查代码,你可以从一个包含必要代码的模板开始。
2.记住在部署中的重要一步就是删除或者禁用测试代码。
 
Ajax安全性
当你需要使用 Ajax比如jQuery时,你一般在开发Ajax的服务器端代码时都会假定对这些代码的调用是通过JavaScript完成的,而与Ajax相关的安全性的重要一点就是,恶意用户可以直接调用Ajax的服务器端代码。你需要从这两个方面来对你的代码进行测试。
 
表单API的安全性
使用表单 API的一个好处就是它为你处理了许多安全性问题。例如,Drupal通过检查来保证,用户从下拉选择框中选择的值,确实是Drupal生成的选项中的一个。表单API使用一系列的事件集,比如表单构建、验证、和执行。在验证阶段前面,你不能够使用用户输入,因为用户输入还没有被验证。例如,如果你使用的值来自于$_POST,那么你就不能确保用户是否操作了该值。还有就是,使用#value元素在表单中传递信息,尽可能的使用它来代替隐藏域,因为恶意用户可以操作隐藏域但是却访问不到#value元素。更多关于表单API的信息参看第10章。
 
使用eval()
千万不要使用它。使用 PHP函数eval(),你可能觉得它是进行元编程的极好的方式,或者想用它来减少多行代码,这个函数将一个字符串文本作为输入并使用PHP解释器对其求值。这完全是一个错误。如果有任何方式允许一个用户使用eval()来操作输入的话,那么你就会将PHP解释器的威力暴露给用户的风险。,这离泄露私密数据的时间也不会太长了,因为用户就可能使用这一威力来获取你的数据库中的用户名和密码。
这也是为什么你只能在 Drupal后台管理接口中使用PHP过滤器的原因,而且只有在非常特定的环境中并具有相关授权的前提下才使用它。为了能够睡个安稳觉,避免使用eval()和PHP过滤器。Drupal的确在其内核中使用了eval(),但是情况非常少并且使用了drupal_eval()对其进行封装,drupal_eval()可以阻止要进行估值的代码覆盖调用drupal_eval()的代码中的变量。drupal_eval()位于includes/common.inc。
 
总结
读完本章后,你应该知道:
• 永远不要相信用户的输入
• 如何将用户的输入转换为安全的形式
• 如何阻止XSS攻击
• 如何阻止SQL注入攻击
• 如何编写考虑了节点访问模块的代码
• 如何阻止e-mail头部注入
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值