Anti SQL Inject

Anti SQL Inject

1.Web 应用程序执行时如果发生异常,通过配置严禁将任何技术信息暴露:
 Web.Config:  

<
customErrors 
mode
=”RemoteOnly”
 
/>

2.在客户端应用程序
 2.1 程序代码中一定要拼接 “参数化 SQL” ,并采取安全的”命令参数式” ADO.Net API
  ,连接数据库并提交该查询,另外今后尽量减少应用程序拼接 SQL,而多使用存储过程。
  参阅如下代码:

ContractedBlock.gif
ExpandedBlockStart.gif
Code

private void cmdLogin_Click(object sender, System.EventArgs e)
{

 
string strCnx = ConfigurationSettings.AppSettings[cnxNWindBad];
 
using (SqlConnection cnx = new SqlConnection(strCnx))
 {

  SqlParameter prm;
  cnx.Open();
  
string TableName = [users];
  
string strQry =
   
//注意 @username 和 @password 就是前面所指参数化 SQL 中的参数
   
//可以理解为是 “字段值” 的”值占位符”,不要用它去占位表名、列名、以及关键字
   
//同时用户交互录入的也的确只能是 “字段值”
   
//这样 ADO.Net + SQL Server 就可以自动免疫,免于被注入恶意但语法正确的 SQL
   SELECT Count(*) FROM  + TableName +   WHERE UserName=@username  +
   
AND Password=@password;
  
int intRecs;
  SqlCommand cmd 
= new SqlCommand(strQry, cnx);
  cmd.CommandType
= CommandType.Text;
  prm 
= new SqlParameter(@username,SqlDbType.VarChar,50);
  prm.Direction
=ParameterDirection.Input;
  prm.Value 
= txtUser.Text;
  cmd.Parameters.Add(prm);
  prm 
= new SqlParameter(@password,SqlDbType.VarChar,50);
  prm.Direction
=ParameterDirection.Input;
  prm.Value 
= txtPassword.Text;
  cmd.Parameters.Add(prm);
  intRecs 
= (int) cmd.ExecuteScalar();
  
if (intRecs>0)
  {

   FormsAuthentication.RedirectFromLoginPage(txtUser.Text, 
false);
  }
  
else
  {

   lblMsg.Text 
= Login attempt failed.;
  }
 }
}

 2.2 程序代码中直接调用存储过程,采取安全的”命令参数式” ADO.Net API,连接数据库并提交,
  不要以 CommandType.Text 的方式使用ADO.Net API 执行类似 exec sp_help ‘sysobjects’ 语句。
  参阅代码同前
3.数据库服务器端程序
 3.2 存储过程 T-SQL 程序代码中,如果其传入参数只用于静态 SQL ,且客户端采取安全的”命令参数式”
  ADO.Net API 调用该存储过程,则是安全代码,自动免疫 SQL 注入攻击。
  参阅如下代码:

ContractedBlock.gif
ExpandedBlockStart.gif
Code

静态 SQL 代码:
declare @value varchar(100)
set @value = sys or 1=1 — 根本无法注入恶意 sql,得到所有记录,因为 @value 被认为是一个”值”
select * from sysobjects where name like % + @value +%

存储过程:
create procedure zsp_WithStaticSQL
@Parameter varchar(100)
as
select *
from sysobjects
where name = @Parameter

 3.3 存储过程 TSQL 程序代码中,如果其传入参数被用于拼接动态 SQL,该参数应该只接受”值”,
  ,而不要用于传入包含表名、列名、关键字的 SQL 语句的一部分,并将该存储过程参数用于
  构造参数化的动态 SQL,并使用 sp_executesql 及其形参声明参数,实参参数执行,
  而绝对禁止直接拼接 SQL,并 
exec 执行
create proc zsp_WithParameterizedDynamicSQL
 
@Value varchar(20)
,
@OutValue int output
as
用于保存动态 SQL 的一定要使用 nvarchar 数据类型
declare @sql nvarchar(200
set @sql = select * from sysobjects 
if @value = null or len(@value> 0
begin
  
@value 是存储过程的参数,将其拼接到动态 sql 语句中,起到了一个”字段值”的”值占位符”的作用
  (一般是”=”右边的以”@”开始的 T-SQL 变量)
  从而构造出安全的 “参数化动态SQL”
  set @sql = @sql +  where name like (% + @ +%)
end

select @sql

exec sp_executesql @sql
  , N
@ varchar(20)
  , 
@value

set @OutValue = @@rowcount
GO

declare @ varchar(100)
set @ = sys
set @ = ”’%
declare @i int
exec zsp_WithParameterizedDynamicSQL @,@i out
select @i

Anti SQL Inject

SQL 2000+ XQuery解决参数化In子句的问题

ContractedBlock.gif
ExpandedBlockStart.gif
Code

建测试表
create table #testTable (UserID int,UserName varchar(50))
插测试数据
insert into #testTable(UserID,UserName) values (1,aaa)
insert into #testTable(UserID,UserName) values (2,aaa)
insert into #testTable(UserID,UserName) values (3,aaa)
insert into #testTable(UserID,UserName) values (4,aaa)

declare @ids xml
set @ids = cast(<ids><id>1</id><id>2</id><id>3</id></ids> as xml)

select A.* from TestUser A
 
inner join
 (
  
select X.c.value(.intas UserID 
   
from @ids.nodes(/ids/idas X(c)
 ) B 
on A.UserID = B.UserID 
 
 
drop table #testTable

SQL 2008 UDT 解决参数化 In 子句的问题

ContractedBlock.gif
ExpandedBlockStart.gif
Code

In(‘a’,’b’,’c’) 转换为 in (select colname from @Table)

D
 ================================
 Create User-defined Table Type
 ================================
USE Test
GO
 Create the data type
CREATE TYPE dbo.MyType AS TABLE 
(
 col1 
int NOT NULL
 col2 
varchar(20NULL
 col3 
datetime NULL
 
PRIMARY KEY (col1)
)
GO

DECLARE @MyTable MyType
INSERT INTO @MyTable(col1,col2,col3)
VALUES (1,abc,1/1/2000),
 (
2,def,1/1/2001),
 (
3,ghi,1/1/2002),
 (
4,jkl,1/1/2003),
 (
5,mno,1/1/2004)
 
SELECT * FROM @MyTable 

go
CREATE PROC usp_test @MyTableParam MyType READONLY
as
begin
 
select *
 
from [Table_1]
 
where f2 in(select col1 FROM @MyTableParam)
end 
GO

 

ContractedBlock.gif
ExpandedBlockStart.gif
Code

Create a local table
Dim table As New DataTable(temp)
Dim col1 As New DataColumn(col1, System.Type.GetType(System.Int32))
Dim col2 As New DataColumn(col2, System.Type.GetType(System.String))
Dim col3 As New DataColumn(col3, System.Type.GetType(System.DateTime))
table.Columns.Add(col1)
table.Columns.Add(col2)
table.Columns.Add(col3)
        
Populate the table
For i As Integer = 20 To 30
    
Dim vals(2As Object
    vals(
0= i
    vals(
1= Chr(i + 90)
    vals(
2= System.DateTime.Now
    table.Rows.Add(vals)
Next

Code
Create a command object that calls the stored proc
Dim command As New SqlCommand(usp_AddRowsToMyTable, conn)
command.CommandType = CommandType.StoredProcedure

Create a parameter using the new type
Dim param As SqlParameter = command.Parameters.Add(@MyTableParam, SqlDbType.Structured)
command.Parameters.AddWithValue(@UserIDKathi)

Code
Set the value of the parameter
param.Value = table

Execute the query
command.ExecuteNonQuery()

SQL 2000 + Split String to Table

ContractedBlock.gif
ExpandedBlockStart.gif
Code

CREATE function [dbo].[zufn_SplitStringToTable]
(
    
@Text   varchar(8000),  待分拆的字符串
    @Separator varchar(10= ,     数据分隔符
)RETURNS @Table TABLE(id int,F varchar(100))
AS
/*
select *
from zufn_SplitStringToTable(‘,,44,,,55,77,77,’,’,’)
*/

BEGIN
set @Text = replace(@Text, ,)
set @Separator = ,
DECLARE @SeparatorLen int
SET @SeparatorLen=LEN(@Separator+$)2
set @Text = replace(@Text, ,)
declare @i int
set @i = 1
WHILE CHARINDEX(@Separator,@Text )>0
BEGIN
    
declare @v varchar(100)
    
set @v = (LEFT(@Text ,CHARINDEX(@Separator,@Text )1))
    
INSERT @Table (id,F)
    
select @i,@v
    
where rtrim(ltrim(@v)) !=  
            
and not exists (select 1 from @Table  where F = @v)
    
if @@rowcount > 0
    
begin
        
set @i = @i + 1
    
end
    
SET @Text = STUFF(@Text ,1,CHARINDEX(@Separator,@Text )+@SeparatorLen,)
END
INSERT @Table  (id,F)
select @i,@Text
where rtrim(ltrim(@Text)) != 
        
and not exists (select 1 from @Table where F = @Text)
return
end

C# 参数化 SQL in 子句

ContractedBlock.gif
ExpandedBlockStart.gif
Code

//参数化 SQL in 子句
namespace Microshaoft.Test
{

    
using System;
    
using System.Data;
    
using System.Data.SqlClient;
    
using Microshaoft.ParameterizedSqlTest;

    /// <summary>
    
/// Class1 的摘要说明。
    
/// </summary>
    public class Class1
    {

        
/// <summary>
        
/// 应用程序的主入口点。
        
/// </summary>
        //[STAThread]
        static void Main(string[] args)
        {

            
//
            
// TODO: 在此处添加代码以启动应用程序
            
//
            Console.WriteLine(Hello World);
            Console.WriteLine(Environment.Version.ToString());

            DataTable dt = DataAccess.Execute_SQL
                                (
                                    
abc
                                    , 
d
                                    , 
a,b,c,d
                                    , SqlDbType.VarChar
                                    , 
3
                                    , 
sqlPara
                                );
            Console.WriteLine(dt.Rows.Count);
            Console.ReadLine();
        }
    }
}

namespace Microshaoft.ParameterizedSqlTest
{

    
using System;
    
using System.Data;
    
using System.Data.SqlClient;

    using System.Text;

    class DataAccess
    {

        public static string _ConnectionString = @”Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=Northwind;Data Source=.\sqlexpress;//ConfigurationManager.ConnectionStrings[“ConnectionString”].ConnectionString;
        public static DataTable Execute_SQL
                                (
                                    
string Parameter1                    //普通参数
                                    , string Parameter2                    //普通参数
                                    , string inClause                    //in 子句字段值列表
                                    , SqlDbType inClauseSqlDbType        //in 子句字段类型
                                    , int inClauseSqlDbTypeSize            //in 子句字段大小
                                    , string prefixSqlParameterName        //参数前缀
                                )
        {

            SqlConnection connection 
= new SqlConnection(_ConnectionString);

            StringBuilder sql = new StringBuilder(select 1 where ‘abc’ = @Parameter1);

            SqlCommand command = new SqlCommand();
            command.CommandType 
= CommandType.Text;

            SqlParameter sqlParameter1 = command.Parameters.Add(@Parameter1, SqlDbType.VarChar, 3);
            sqlParameter1.Direction 
= ParameterDirection.Input;
            sqlParameter1.Value 
= Parameter1;

            SqlParameter sqlParameter2 = command.Parameters.Add(@Parameter2, SqlDbType.VarChar, 3);
            sqlParameter2.Direction 
= ParameterDirection.Input;
            sqlParameter2.Value 
= Parameter2;

            string[] a = inClause.Split(,);
            
if (a.Length > 0)
            {

                sql.Append(
 and @Parameter2 in ();
                
int i = 0;

                foreach (string var in a)
                {

                    i 
++;
                    
if (i > 1)
                    {

                        sql.Append(
,);
                    }
                    
string sqlParameterName = @ + prefixSqlParameterName + _ + i;
                    sql.Append(sqlParameterName);
                    SqlParameter parameter;
                    
if (inClauseSqlDbTypeSize > 0)
                    {

                        parameter 
= command.Parameters.Add(sqlParameterName, inClauseSqlDbType, inClauseSqlDbTypeSize);
                    }
                    
else
                    {

                        parameter 
= command.Parameters.Add(sqlParameterName, inClauseSqlDbType);
                    }
                    parameter.Direction 
= ParameterDirection.Input;
                    parameter.Value 
= var;

                }
                sql.Append());
            }
            command.CommandText 
= sql.ToString();
            command.Connection 
= connection;

            Console.WriteLine(command.CommandText);
            SqlDataAdapter sda = new SqlDataAdapter(command);
            DataSet ds 
= new DataSet();
            sda.Fill(ds);
            connection.Close();
            
return ds.Tables[0];
            
        }

    }
}

1. 采用最少权限的原则
运行脚本或执行代码的进程应当尽可能用权限最少的帐户运行,从而在危及进程安全时限制可能造成的破坏。如果恶意用户设法将代码注入某个服务器进程,那么授予该进程的权限会在很大程度上决定该用户可执行的操作类型。应当将需要更多信任(和更高权限)的代码分别隔离在不同的进程内。
2. 使用纵深防御
在应用程序中的每一层和每个子系统中设置检查点。检查点是网关守卫,它们确保只有经过身份验证和授权的用户能够访问下一个下游层。
3. 不要信任用户输入
应用程序彻底验证所有用户输入,然后再根据用户输入执行操作。验证可能包括筛选特殊字符。针对用户意外地错误使用和某些人通过在系统中注入恶意命令蓄意进行攻击的情况,这种预防性措施对应用程序起到了保护作用。常见的攻击包括 SQL 注入攻击、脚本注入和缓冲区溢出。
4. 使用默认安全设置
杜绝仅仅为了使应用程序运行而使用安全性较低的设置。如果应用程序所需的功能不得不减小默认安全设置的安全级别或更改默认的安全设置,在更改前,充分测试更改所带来的后果,并了解可能带来的隐患。
5. 不要通过隐藏来保障安全
尝试使用让人迷惑的变量名来隐藏机密信息或将它们存储在不常用的文件位置,这些方法都不能提供绝对的安全保障。最好使用平台功能或使用已被证实可行的技术来保护数据。
6. 在关口进行检查
在关口检查客户端意思是在第一个身份验证点(例如,Web 服务器上的 Web 应用程序内)授予用户权限,并确定允许用户访问的资源和操作(可能由下游服务提供)。如果在关口设计可靠的身份验证和授权策略,就不必将原调用方的安全上下文一路委派到应用程序数据层。
7. 假定外部系统是不安全的系统
如果外部系统不归您所有,不要假定有人为您保证安全。
8. 减小表面区域
避免公开不需要公开的信息。如果公开这些信息,就可能进一步引起漏洞。同时,处理错误的方式一定要适当。向最终用户返回错误消息时,不要公开任何不需要公开的信息。
9. 以安全的方式显示错误消息
如果应用程序失败,一定要保护好机密数据。同时,不要在错误消息中提供过于详细的数据,也就是不要提供任何有助于攻击者发现应用程序漏洞的详细信息。详细的错误信息应写入 Windows 事件日志。
10, 不要忘记您的安全程度受最薄弱环节制约
考虑安全性时,应该将应用程序所有层的安全性都考虑在内。
11. 禁用不使用的内容
通过禁用应用程序不需要的模块和组件来去除一些潜在的攻击点。例如,如果应用程序不使用输出缓存,则应禁用 ASP.NET 输出缓存模块。这样,即使以后在该模块中发现安全漏洞,应用程序也不会受到威胁。

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/110888.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • hash冲突以及hash冲突的解决方法

    hash冲突以及hash冲突的解决方法首先说一下hash冲突吧,hash冲突在hash表中一般情况下是会遇到的;hash冲突指的是你在向hash表中存数据时,首先要通过key值进行指定的hash算法进行计算,然后得到一个值,这个值就是你要将这个key对应的value存入的地址。但是在这个地址中已经有值存在,所以这个时候就发生了hash冲突,不同的key通过hash算法得到了对应的同一个值。hash冲突解决的方法:再hash法:这种方法就是有多个hash算法,当使用一个hash算法计算得到值发生hash冲突时那就使用另外一个hash算法

  • 谷歌地球无法连接服务器解决方法_谷歌地图无法连接服务器是什么原因

    谷歌地球无法连接服务器解决方法_谷歌地图无法连接服务器是什么原因从2020年11月20号左右,谷歌地球中国服务器全部关停,所有原来可以使用的hosts,全部不能使用了,导致原来可以在电脑上打开谷歌地球的,现在全部提示无网络,如下图:这个是谷歌地球的最新版,一样打不开:解决办法,尝试了,国内所有的有关谷歌地图的软件。唯一现在可以使用的:BIGEMAP如下图分享地址给大家,大家可以安装来试一试,免费可用:http://download.bigemap.com/bmsetup.rar欢迎留言,提供更多谷歌地球的信息…

  • latex的参考文献写法标准_endnote怎么修改参考文献编号格式

    latex的参考文献写法标准_endnote怎么修改参考文献编号格式LaTeX参考文献的排版与引用​ 在论文写作的过程中,为了体现论文的科学性、严谨性和规范性,我们常常需要引用大量的参考文献来引证自己的观点。参考文献(Reference)往往都是放在论文的最后,记录了所引用论文的标题、作者、期刊或会议、出版时间等信息,文中还需要明确有顺序的进行引用标注。​ 本篇将介绍LaTeX常用的参考文献排版与引用方式,所用到的宏包都要写在\documentclass命令之后和\begin{docuemnt}之前,在本文中,我们会用的宏包文件有:\usepackag

  • Laravel 5框架Mutator,Scope

    Laravel 5框架Mutator,Scope首先修改控制器:publicfunctionstore(){Article::create(Request::all());returnredirect(‘articles’);}然后修改视图,添…

  • mysql 联合主键_Mysql 创建联合主键[通俗易懂]

    mysql 联合主键_Mysql 创建联合主键[通俗易懂]Mysql创建联合主键2008年01月11日星期五下午5:21使用primarykey(fieldlist)比如:createtablemytable(aaint,bbchar(8),ccdate,primarykey(aa,bb));aa,bb为联合主键不知道是不是因为mysql(6.0)的版本问题,还是各版本都是这种情况,mysql中创建联合主键,联合主键列名之外…

  • rhel6 裸设备绑定

    rhel6 裸设备绑定

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号