网站安全性测试需要注意的一些问题0+

5,446 views / 2011.12.16 / 9:09 上午
  1. https的访问有可能是用http方式也能够访问。
  2. 所有需要认证的页面都需要直接输入url 来验证
  3. java的类都需要进行加密后才能够发布。(程序员完成)
  4. 所有的java页面报错有可能泄漏程序信息,所有的页面都要加上异常
  5. 管理员的后台页面的用户名尽量长,密码也要尽量复杂。(程序员完成,不要使用ROOT ADMIN ADMINISTRATROR的字符)。
  6. COOKIE中的不能包含明文的用户明和密码信息,最后能够将COOKIE的信息都加密。
  7. 如果获得一个用户的COOKIE文件,则不能够让用户直接不通过登陆就自动登录。
  8. 所有的输入字段都将英文的<> 屏蔽掉,防止用户输入恶意的JAVASCRIPT代码获取相应信息。
  9. 输入username’–这样的信息验证用户登录的健壮性。
  10. url 中不能包含明文的密码和帐户信息
  11. 所有的重要提交页面提交后,再使用ie的返回后,则页面都应该提示页面已经过期,或者用户再次提交相同的信息,则系统能够提示此表单已经被提交过,不能在提交。
  12. 网页的session过期应该有时间限制,一般是30分钟,cookie也应该有30分钟过期限制(可根据业务的安全性而定)。
  13. 网页HTML中的hidden 的类型应该不包含敏感的认证信息和安全信息,防止他人盗用。

 

对于输入验证攻击的一些关键点:

  1. 服务器端的输入验证,所有的字段前台输入后,后台程序都要进行判断有效性,而不是单纯的使用javascript来判断。
  2. 字符编码:HTML字符应该被当作编码,这样可以防止应用程序错误地解析他们。例如:将角扩号表示成“&lt”和“&gt”.屏蔽select (sel) insert update del grant revoke这些关键字的输入。
  3. 正则表达式:使用正则表达式来匹配未经授权的数据内容。
  4. 健壮的数据类型:数字值应该指派一个数字结构类型,字符值应当指派一个字符结构类型。长度限制在前台程序和后台程序都要加上判断。
  5. 所有异常都要使用try Catch来捕捉,或者使用errorpage的属性来定义不能捕获的异常信息,不能够将任何出错后的代码信息显示给用户。
  6. 要求认证,培植服务器,要求对每个目录中的所有文件都有恰当的认证。
  7. 使用最小权限访问 以尽可能低的权限的用户涨好赖运行web服务器上的应用程序。应用程序可能可以执行命令但是不能访问象/sbin这样的系统目录,因为只有具有root权限的用户才可以执行改目录中的命令。

 

关于防止sql语句注入的一些防范错误:

  1. 健壮的错误处理:

一定不要吧未经处理的odbc或者其他错误传递给用户。使用普通的错误页面和错误处理程序通知用户所发生的错误。但是不要提供系统信息、变量或其他数据。

  1. 参数列表:

将用户提供的数据存储到特定的变量中,字符串的连接是安全sql语句的最大隐患,因为它给用户提供了一种最简单的方法,用户可以使用单引号来操作sql语句。

在web 服务器上应该进行输入验证,而且数据库中的条目也应该有严格的类型定义。一个仅使用数值的字段应该被定义为int类型,而不是varchar类型。

  1. 存储过程:

用户自定义的存储过程更加难于进行sql注入。因为他们需要以特定的格式在特定的地方给出特定数量的参数,因此有许多前台条件需要满足。用户字定义的存储过程还可以提高性能。

  1. 以较低的权限运行:数据库应用程序应该在最低权限下运行。同样,web服务器使用的用户账号也应该具有有限的功能。当然,该账号必须能对数据库进行读写操作,但是他不必修改master数据库或者执行备份的操作。
  2. 保护计划:

表名、列名和sql的结构都不应在HTML中出现。不要将敏感信息放到用户能看到的页面文件的注释中。

  1. 使用数据绊网:

用模糊的方法进行保护的一个例外就是利用一些容易识别的文件存储假的用户ID和密码。用这些假文件中的用户ID登录就会警告支持人员有人已经非法进入到了应用程序的数据库,并且试图进一步行动。这个方法的缺点是,只有在有人注意到警告时,绊网才会起作用,这个需要有人进行实时监控。

  1. 将数据写到高速光驱上,让敏感信息不能被改写。
  2. 数据伪装,将很多数据不要加密成很明显的加密形式,而是加密成很象正常数据的形式,这样黑客进入系统后拿到的数据也不能用。起到了欺骗的作用。
  3. 分布式的数据拷贝,将数据库的敏感文件放在不同的服务器上,这样黑客需要攻破多个数据库服务器才能够将数据获取。或者将敏感的数据库字段分别放在不同的数据库文件的表中,这样黑客和难获得完整的数据。
  4. 敏感的文件不要使用显示其真正用途的名字
Categories: 感悟 Tags:

如何去管理php的用户名和密码(三)0+

3,614 views / 2011.12.15 / 7:07 下午

(接上文:http://71j.cn/archives/183)

用户传入数据的过滤

我们不能紧紧依靠mysql的过滤的机制,而需要对用户输入的变量进行非法字符过滤,防止DoS攻击和sql注入。

$user = get_post_var('user');
if(!preg_match('/^[a-zA-Z0-9_]{1,60}$/', $user))
fail('用户名不合法');
 
$pass = get_post_var('pass');
/* 好歹我们也应该节省点CPU和内存吧,哈哈 */
if (strlen($pass) > 72)
fail('The supplied password is too long');

这一步很关键。在每个项目中,我们都有专门的类来处理$_POST和$_GET过来的数据,保障数据安全。

 

验证用户身份

一般开发过程中,从安全角度考虑,我们都不建议存储用户密码的明文,这是为什么呢?杜工卖个关子,读者自己思考吧。

 

创建新用户:

$hash = $hasher->HashPassword($pass);
if (strlen($hash) < 20)
fail('密码分配失败');
unset($hasher);
 
($stmt = $db->prepare('insert into users (user, pass) values (?, ?)'))
|| fail('MySQL prepare', $db->error);
$stmt->bind_param('ss', $user, $hash)
|| fail('MySQL bind_param', $db->error);
if (!$stmt->execute()) {
if ($db->errno ===1062 /* ER_DUP_ENTRY */)
fail('This username is already taken');
else
fail('MySQL execute', $db->error);
}

验证用户身份:

($stmt = $db->prepare('select pass from users where user=?'))
|| fail('MySQL prepare', $db->error);
$stmt->bind_param('s', $user)
|| fail('MySQL bind_param', $db->error);
$stmt->execute()
|| fail('MySQL execute', $db->error);
$stmt->bind_result($hash)
|| fail('MySQL bind_result', $db->error);
if (!$stmt->fetch() && $db->errno)
fail('MySQL fetch', $db->error);
 
if ($hasher->CheckPassword($pass, $hash)) {
$what= 'Authentication succeeded';
} else {
$what = 'Authentication failed';
}
unset($hasher);

 

由此,验证过程完毕。非常安全。

 

修改密码

修改密码前一定要验证原来的密码是否正确:

if ($hasher->CheckPassword($pass, $hash)) {
$what= 'Authentication succeeded';
} else {
$what = 'Authentication failed';
$op = 'fail'; // Definitely not 'change'
}

随后进行密码规则判断,看是否符合要求,再进行update操作。

$newpass = get_post_var('newpass');
if(strlen($newpass) > 72)
fail('The new password is too long');
$hash = $hasher->HashPassword($newpass);
if(strlen($hash) < 20)
fail('Failed to hash new password');
unset($hasher);
 
($stmt = $db->prepare('update users set pass=? where user=?'))
|| fail('MySQL prepare', $db->error);
$stmt->bind_param('ss', $hash, $user)
|| fail('MySQL bind_param', $db->error);
$stmt->execute()
|| fail('MySQL execute', $db->error);
 
$what = 'Password changed';

 

这样,已经存在的用户密码就会被修改成功了。

Categories: 感悟 Tags:

杜工在windows下定时备份mysql的脚本0+

3,592 views / 2011.12.12 / 8:08 下午

嘿嘿,大家是不是经常为找不到windows下的定时备份脚本而苦恼(哭闹?),这里杜工分享下bat脚本做自动备份的例子,使用前请先安装WinRAR。

rem
rem C:\Program Files (x86)\WinRAR 需要配置到系统环境变量 path 下,才能调用rar cli工具
rem
rem 跳转到工作目录下
e:
cd e:\DBBAK
rem 设置备份文件名
SET BAK_FILE=MY_DBBAK_%DATE:~0,-4%.sql
rem 设置日志文件名
SET LOG_FILE=MY_DBBAK.log
rem 记录日志
echo "%date%" >> %LOG_FILE%
rem 开始dump
mysqldump --default-character-set=utf8 -hlocalhost -uroot -R --triggers --single-transaction -B mydb > %BAK_FILE%
rem 压缩备份文件
rar a %BAK_FILE%.rar %BAK_FILE%
rem 删除临时文件
del /F %BAK_FILE%
echo "%date%" >> %LOG_FILE%
echo "" >> %LOG_FILE%
Categories: 感悟 Tags: