您的位置:首页 > 数据库

《学习日记》---参数化存储结构防止SQL注入攻击

2015-09-17 16:44 225 查看
参考资料:http://www.cnblogs.com/xyd21c/archive/2010/12/09/1901140.html

参考这个大哥而写的SQL注入。

存储过程:

组成:几条SQL语句的组合。

作用:只需要在第一次调用时编译一次,再次调用时就不需要编译,而普通的SQL语句则每次调用都要编译(对比法)

格式:

CREATE PROCEDURE [拥有者.]存储过程名[;程序编号]

[(参数#1,…参数#1024)]

[WITH

{RECOMPILE | ENCRYPTION | RECOMPILE, ENCRYPTION}

]

[FOR REPLICATION]

AS

SQL STATEMENT

例子:

创建存储过程:

create procedure getUser

@name varchar,

@id varchar

AS

Select USER_NAME FROM USER_TABLE WHERE USER_ID = @id;

解释:

output:表示此参数是可传回的

with {recompile|encryption}

recompile:表示每次执行此存储过程时都重新编译一次

encryption:所创建的存储过程的内容会被加密

调用存储过程:

存储过程名字+参数。

getUser(参数)

删除存储过程:

drop procedure sp_name

优点:

①重复使用。存储过程可以重复使用,从而可以减少数据库开发人员的工作量。

②提高性能。存储过程在创建的时候在进行了编译,将来使用的时候不再重新翻译。一般的SQL语句每执行一次就需要编译一次,所以使用存储过
程提高了效率。

③减少网络流量。存储过程位于服务器上,调用的时候只需要传递存储过程的名称以及参数就可以了,因此降低了网络传输的数据量。

④安全性。参数化的存储过程可以防止SQL注入式攻击,而且可以将Grant、Deny以及Revoke权限应用于存储过程。

SQL注入:

SQL注入:是指客户的不合法输入(加入一些SQL语句)通过表单(这个表单是的信息是跟数据库信息有关的)提交去修改原来的SQL语句。

例子:

以下脚本显示了一个简单的 SQL 注入。此脚本通过串联硬编码字符串和用户输入的字符串而生成一个 SQL 查询:

var Shipcity = Request.form. ("ShipCity");

var sql = "select * from OrdersTable where ShipCity = '" + ShipCity + "'";用户将被提示输入一个市县名称。如果用户输入 Redmond,则查询将由与下面内容相似的脚本组成:

SELECT * FROM OrdersTable WHERE ShipCity = 'Redmond'

但是,假定用户输入以下内容:Redmond'; drop table OrdersTable--

此时,脚本将组成以下查询:SELECT * FROM OrdersTable WHERE ShipCity = 'Redmond';drop table OrdersTable--'

解决方案:

1、验证输入的字符的长度:防止用户输入一个10M的东西,这样会造成数据库瘫痪。

2、用参数化的存储过程

3、用@Parameters(对参数进行长度和类型的验证,不符合则抛出异常)

4、对危险字符验证:

; 查询分隔符。

' 字符数据字符串分隔符。

-- 注释分隔符。

/* ... */ 注释分隔符。服务器不对 /* 和 */ 之间的注释进行处理。

xp_ 用于目录扩展存储过程的名称的开头,如 xp_cmdshell。

范式的浅显解读:

先说明几个属性:

码:能唯一确定一是个元组(就是表的一行)的属性或者属性组。如果所有属性才能确定一组就是全码。

主属性:是指出现在所有码中的一个属性。

非主属性:所有码和候选码中不会出现的属性。

1NF:就是每列都是不可分割的原子,都是独立存在的,而不存在集合。一个属性只有一个值,就是说,一个属性列不能有两个值。

2NF:就相当于主键,一个主键可以决定一个实体,是完全依赖的(就是说如果一个主属性,如果他不是码,那么他不能确定任何非主属性)

3NF:在2NF基础上,不存在传递依赖。传递依赖是值:X->Y(Y!->X),Y->T,所以X->T,那么就是传递依赖。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: