当前位置:首页>网络学院>程序开发>JSP教程>文章内容

权衡安全和功能 编写安全的Web2.0应用

[ 来源:www.it55.com | 作者: | 时间:2007-07-14 | 收藏 | 推荐 ] 【

开发人员必须权衡好安全和功能之间的关系,这要看某种攻击得逞的可能性有多大、这个系统有多重要。 www.it55.com在线教程

  开发人员可以运用诸多基本原则来增强Web应用程序的安全性。主要有以下三条原则: vd;k;l www.it55.com rdfg

  尽量减小权限 IT资讯之家 www.it55.com

  对访问资源的账户进行配置时,始终要把这些账户的权限限制在需要的最小权限。 sflj www.it55.com kg^&fgd

  千万不要相信用户的输入,验证任何输入的内容 sflj www.it55.com kg^&fgd

  这对Web应用程序来说尤为重要。确保应用程序并不依赖客户端的验证。在服务器上应当重复所有的检查工作,因为要是没有约束条件,比较容易构建网页副本,有可能导致破坏性代码在运行,或者导致引起系统崩溃的拒绝服务(DoS)攻击。

IT资讯之家 www.it55.com

  有节制地使用错误消息 http://www.it55.com/

  虽然在开发程序时,详细的错误消息很有帮助,但它们对恶意用户来说同样是宝贵的信息来源。所以指定函数名这类细节没有太大的意义。这样的细节记录在另一个日志中比较好。

http://www.it55.com/

  下面几个示例介绍了没有经过验证的用户输入如何被坏人利用的具体情况,并且介绍了避免这些问题的建议。 http://www.it55.com/

  SQL注入

IT资讯之家 www.it55.com

  如果允许任意的SQL命令执行,就会出现SQL注入(SQL injection)。当SQL语句在代码里面动态构建时,通常会出现这种情况。 45398 www.it55.com it55学习IT知识,享受IT生活 4dfkjn

  以下面用C#编写的代码为例,该代码试图检查用户名/密码组合是否正确:

www.it55.com在线教程

  string username = txtUsername.Text;

vd;k;l www.it55.com rdfg

  string password = txtPassword.Text; IT资讯之家 www.it55.com

  string SQL = "SELECT * FROM tblUsers www.it55.com在线教程

  WHERE username = '"+ username +"'

免费资源www.it55.com

  AND password = '"+ password + "';"; sflj www.it55.com kg^&fgd

  //执行SQL

www.it55.com在线教程

  用户名和密码从服务器端的两个文本框获取,并且SQL语句被创建,然后该语句执行。如果没有记录返回,那么表明用户输入的详细资料不正确,或者没有经过注册; 否则用户可以进入到下一个阶段。

sflj www.it55.com kg^&fgd

  如果用户在两个文本框里面输入了Joe和mypassword,那么SQL语句会是: http://www.it55.com/

  SELECT * FROM tblUsers

www.it55.com

  WHERE username = 'Joe' sflj www.it55.com kg^&fgd

  AND password = 'mypassword'; vd;k;l www.it55.com rdfg

  这正是开发人员的意图。不过要是用户往密码文本框里面输入: ' OR 'a' = 'a,SQL就会是: www.it55.com

  SELECT * FROM tblUsers IT资讯之家 www.it55.com

  WHERE username = 'Joe'

IT资讯之家 www.it55.com

  AND password = '' sflj www.it55.com kg^&fgd

  OR 'a' = 'a'; sflj www.it55.com kg^&fgd

  现在,密码不重要了,因为'a'='a'总是正确的。如果用来连接到数据库的账户有权删除数据而不是仅仅有权读取数据,就会出现更糟糕的情形。假设用户往密码文本框里面输入: '; DELETE FROM tblUsers WHERE 'a' = 'a'。这会得出以下的语句:

IT资讯之家 www.it55.com

  SELECT * FROM tblUsers vd;k;l www.it55.com rdfg

  WHERE username = 'Joe' 免费资源www.it55.com

  AND password = ''; www.it55.com

  DELETE FROM tblUsers

45398 www.it55.com it55学习IT知识,享受IT生活 4dfkjn

  WHERE 'a' = 'a'; it55.com

  现在,整个用户表就会被清空。

45398 www.it55.com it55学习IT知识,享受IT生活 4dfkjn

防止这类问题主要有两种办法。一是,可以使用存储过程(stored procedure)来执行用户验证步骤。设置参数值时,避免使用单引号等特殊符号,因而不可能为WHERE语句添加额外的断言(predicate),也不会运行多个SQL语句。譬如说,可以构建像下面这样的存储过程,接受两个输入参数后,返回表明用户是不是合法用户的第三个参数: IT资讯之家 www.it55.com

  CREATE PROCEDURE spCheckUser it55.com

  ( http://www.it55.com/

  @Username VARCHAR(20), IT资讯之家 www.it55.com

  @Password VARCHAR(20),

IT资讯之家 www.it55.com

  @IsValid BIT OUTPUT

www.it55.com

  ) it55.com

  AS

http://www.it55.com/

  DECLARE @UserCount INT

vd;k;l www.it55.com rdfg

  SELECT @UserCount = COUNT(*)

http://www.it55.com/

  FROM tblUsers sflj www.it55.com kg^&fgd

  WHERE Username = @Username

sflj www.it55.com kg^&fgd

  AND Password = @Password it55.com

  IF @UserCount = 1

免费资源www.it55.com

  SET @IsValid = 1 免费资源www.it55.com

  ELSE

免费资源www.it55.com

  SET @IsValid = 0 www.it55.com

  现在,初始代码经改动后可以使用存储过程:

it55.com

  SqlCommand sqlCommand =

http://www.it55.com/

  new SqlCommand("spCheckUser"); 免费资源www.it55.com

  SqlParameter sqlParam =

it55.com

  new SqlParameter("@Username", vd;k;l www.it55.com rdfg

  SqlDbType.VarChar, 20)

http://www.it55.com/

  sqlParam.Value = txtUsername.Text;

免费资源www.it55.com

  sqlParam.Direction =

http://www.it55.com/

  ParameterDirection.Input; 免费资源www.it55.com

  sqlCommand.Parameters.Add(sqlParam);

www.it55.com在线教程

  sqlParam =

www.it55.com在线教程

  new SqlParameter("@Password",

www.it55.com在线教程

  SqlDbType.VarChar, 20)

www.it55.com

  sqlParam.Value = txtPassword.Text;

http://www.it55.com/

  sqlParam.Direction = www.it55.com

  ParameterDirection.Input;

免费资源www.it55.com

  sqlCommand.Parameters.Add(sqlParam); http://www.it55.com/

  sqlParam = http://www.it55.com/

  new SqlParameter("@IsValid", IT资讯之家 www.it55.com

  SqlDbType.Bit, 1)

45398 www.it55.com it55学习IT知识,享受IT生活 4dfkjn

  sqlParam.Direction = it55.com

  ParameterDirection.Output; www.it55.com

  sqlCommand.Parameters.Add(sqlParam); www.it55.com在线教程

  //执行命令,并检索输出参数值 www.it55.com

输入和输出参数使用相关类型来说明。如今区别在于,基本的ADO.NET类会把字符串' OR 'a' = 'a当成实际用户的密码来处理,而不是当成可执行SQL来处理。 it55.com

避免这种安全漏洞的第二种办法(也适用于所有的用户输入)就是,确保特殊字符或者字符串被禁用。对SQL而言,导致问题的那个字符就是单引号,所以如果没法使用存储过程,那么就把所有单引号变成双引号,这可以防止有人构建额外的SQL:

vd;k;l www.it55.com rdfg

  string username = txtUsername.Text;

http://www.it55.com/

  string password = txtPassword.Text;

sflj www.it55.com kg^&fgd

  username = username.Replace("'","''"); sflj www.it55.com kg^&fgd

  password = password.Replace("'","''"); sflj www.it55.com kg^&fgd

  string SQL = "SELECT * www.it55.com在线教程

  FROM tblUsers www.it55.com在线教程

  WHERE username = '"+ username +"'

www.it55.com

  AND password = '"+ password +"';";

免费资源www.it55.com

  //执行SQL

45398 www.it55.com it55学习IT知识,享受IT生活 4dfkjn

  现在,构建的SQL成为:

sflj www.it55.com kg^&fgd

  SELECT *

it55.com

  FROM tblUsers

vd;k;l www.it55.com rdfg

  WHERE username = 'Joe'

45398 www.it55.com it55学习IT知识,享受IT生活 4dfkjn

  AND password = ''' www.it55.com在线教程

  OR ''a'' = ''a';

sflj www.it55.com kg^&fgd

  这意味着该用户没有被识别。

免费资源www.it55.com

  跨站脚本 45398 www.it55.com it55学习IT知识,享受IT生活 4dfkjn

  跨站脚本(有时缩写成XSS)允许来自一个地方的代码在另一个网站里面运行。正如在大多数情况下一样,只要验证用户输入的内容就可以避免这问题。以接受HTML格式的帖子的公告牌为例。假定用户在发布消息中加入了以下内容: it55.com

  Hello everyone

(编辑:IT资讯之家 www.it55.com

返回顶部
共2页: 上一页 1 [2] 下一页  

网友评论

[以下评论为网友观点,不代表本站。请自觉遵守互联网相关政策法规,所有连带责任均有评论者自负。]
[不超过250字]

图片文章