當前位置:首頁 » 編程語言 » sqlparametersql注入
擴展閱讀
webinf下怎麼引入js 2023-08-31 21:54:13
堡壘機怎麼打開web 2023-08-31 21:54:11

sqlparametersql注入

發布時間: 2022-04-30 12:35:07

A. sql 注入 查詢 特殊符號怎麼處理

防止sql注入,最簡單的辦法就是不要拼接sql,而是採用SqlParameter參數化形式,如果條件可能有可能沒有,可以採用:
string sql = "select * from xx where 1=1";
if(true){
sql += " and id=@id";
command.Parameters.Add(new SqlParameter
}

如果非要拼接sql,那麼對於數值型,拼接前判斷下是否數值,
字元串類型拼接前進行str.Replace("'", "''");// 把一個單引號替換為兩個單引號
就可以避免sql注入了

B. 『求指導』網站過濾了sql注入怎麼整

防止SQL注入式攻擊,一般都會採用參數化編程,即一些拼接性的條件改成用參數化的佔位符來代替就可以防止SQL注入攻擊。

1)C#

using(SqlCommandcom=con.CreateCommand()){
com.CommandType=CommandType.Text;
com.CommandText="UPDATEEmployeeSETTitle=@title"+
"WHEREId=@Employeeid";

//.
SqlParameterp1=com.CreateParameter();
p1.ParameterName="@title";
p1.SqlDbType=SqlDbType.VarChar;
p1.Value=title;
com.Parameters.Add(p1);

//.
com.Parameters.Add("@Employeeid",SqlDbType.Int).Value=employeeID;

//.
intresult=com.ExecuteNonQuery();
}

2)JAVA

PreparedStatementpstmt=null;
try{
StringSQL="UpdateEmployeesSETage=?WHEREid=?";
pstmt=conn.prepareStatement(SQL);
pstmt.setInt(1,yourvalue);//對應第1個?號
pstmt.setString(2,yourvalue);//對應第2個?號
}
catch(SQLExceptione){
...
}
finally{
...
}

C. SqlParameter是怎麼防止SQL注入的

常,網路攻擊者針對Web應用程序的可能漏洞、Web系統軟體的不當配置以及http協議本身薄弱之處,通過發送一系列含有特定企圖的請求數據,對Web站點特別是Web應用進行偵測和攻擊,攻擊的目的包括:非法獲取站點信息、篡改資料庫和網頁、繞過身份認證和假冒用戶、竊取用戶資料和數據、控制被攻擊的伺服器等。
iWall應用防火牆實現了對Web站點特別是Web應用的保護。它通過全面分析應用層的用戶http請求數據(如URL、參數、鏈接、Cookie、請求行、頭部信息、載荷等),區分正常用戶訪問Web應用和攻擊者的惡意行為,對攻擊行為進行實時阻斷和報警。

D. 為什麼參數化查詢可以防止SQL注入

首先:我們要了解SQL收到一個指令後所做的事情:

具體細節可以查看文章:Sql Server 編譯、重編譯與執行計劃重用原理

在這里,我簡單的表示為: 收到指令 -> 編譯SQL生成執行計劃 ->選擇執行計劃 ->執行執行計劃。

具體可能有點不一樣,但大致的步驟如上所示。

接著我們來分析為什麼拼接SQL 字元串會導致SQL注入的風險呢?

首先創建一張表Users:
CREATE TABLE [dbo].[Users](

[Id] [uniqueidentifier] NOT NULL,

[UserId] [int] NOT NULL,

[UserName] [varchar](50) NULL,

[Password] [varchar](50) NOT NULL,

CONSTRAINT [PK_Users] PRIMARY KEY CLUSTERED

(

[Id] ASC

)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]

) ON [PRIMARY]

插入一些數據:
INSERT INTO [Test].[dbo].[Users]([Id],[UserId],[UserName],[Password])VALUES (NEWID(),1,'name1','pwd1');
INSERT INTO [Test].[dbo].[Users]([Id],[UserId],[UserName],[Password])VALUES (NEWID(),2,'name2','pwd2');
INSERT INTO [Test].[dbo].[Users]([Id],[UserId],[UserName],[Password])VALUES (NEWID(),3,'name3','pwd3');
INSERT INTO [Test].[dbo].[Users]([Id],[UserId],[UserName],[Password])VALUES (NEWID(),4,'name4','pwd4');
INSERT INTO [Test].[dbo].[Users]([Id],[UserId],[UserName],[Password])VALUES (NEWID(),5,'name5','pwd5');

假設我們有個用戶登錄的頁面,代碼如下:

驗證用戶登錄的sql 如下:
select COUNT(*) from Users where Password = 'a' and UserName = 'b'

這段代碼返回Password 和UserName都匹配的用戶數量,如果大於1的話,那麼就代表用戶存在。

本文不討論SQL 中的密碼策略,也不討論代碼規范,主要是講為什麼能夠防止SQL注入,請一些同學不要糾結與某些代碼,或者和SQL注入無關的主題。

可以看到執行結果:

這個是SQL profile 跟蹤的SQL 語句。

注入的代碼如下:
select COUNT(*) from Users where Password = 'a' and UserName = 'b' or 1=1—'

這里有人將UserName設置為了 「b' or 1=1 –」.

實際執行的SQL就變成了如下:

可以很明顯的看到SQL注入成功了。

很多人都知道參數化查詢可以避免上面出現的注入問題,比如下面的代碼:
class Program
{
private static string connectionString = "Data Source=.;Initial Catalog=Test;Integrated Security=True";

static void Main(string[] args)
{
Login("b", "a");
Login("b' or 1=1--", "a");
}

private static void Login(string userName, string password)
{
using (SqlConnection conn = new SqlConnection(connectionString))
{
conn.Open();
SqlCommand comm = new SqlCommand();
comm.Connection = conn;
//為每一條數據添加一個參數
comm.CommandText = "select COUNT(*) from Users where Password = @Password and UserName = @UserName";
comm.Parameters.AddRange(
new SqlParameter[]{
new SqlParameter("@Password", SqlDbType.VarChar) { Value = password},
new SqlParameter("@UserName", SqlDbType.VarChar) { Value = userName},
});

comm.ExecuteNonQuery();
}
}
}

實際執行的SQL 如下所示:
exec sp_executesql N'select COUNT(*) from Users where Password = @Password and UserName = @UserName',N'@Password varchar(1),@UserName varchar(1)',@Password='a',@UserName='b'
exec sp_executesql N'select COUNT(*) from Users where Password = @Password and UserName = @UserName',N'@Password varchar(1),@UserName varchar(11)',@Password='a',@UserName='b'' or 1=1—'

可以看到參數化查詢主要做了這些事情:
1:參數過濾,可以看到 @UserName='b'' or 1=1—'
2:執行計劃重用

因為執行計劃被重用,所以可以防止SQL注入。

首先分析SQL注入的本質,

用戶寫了一段SQL 用來表示查找密碼是a的,用戶名是b的所有用戶的數量。

通過注入SQL,這段SQL現在表示的含義是查找(密碼是a的,並且用戶名是b的,) 或者1=1 的所有用戶的數量。

可以看到SQL的語意發生了改變,為什麼發生了改變呢?,因為沒有重用以前的執行計劃,因為對注入後的SQL語句重新進行了編譯,因為重新執行了語法解析。所以要保證SQL語義不變,即我想要表達SQL就是我想表達的意思,不是別的注入後的意思,就應該重用執行計劃。

如果不能夠重用執行計劃,那麼就有SQL注入的風險,因為SQL的語意有可能會變化,所表達的查詢就可能變化。

在SQL Server 中查詢執行計劃可以使用下面的腳本
DBCC FreeProccache

select total_elapsed_time / execution_count 平均時間,total_logical_reads/execution_count 邏輯讀,
usecounts 重用次數,SUBSTRING(d.text, (statement_start_offset/2) + 1,
((CASE statement_end_offset
WHEN -1 THEN DATALENGTH(text)
ELSE statement_end_offset END
- statement_start_offset)/2) + 1) 語句執行 from sys.dm_exec_cached_plans a
cross apply sys.dm_exec_query_plan(a.plan_handle) c
,sys.dm_exec_query_stats b
cross apply sys.dm_exec_sql_text(b.sql_handle) d
--where a.plan_handle=b.plan_handle and total_logical_reads/execution_count>4000
ORDER BY total_elapsed_time / execution_count DESC;

E. sql注入攻擊怎麼解決

網路:

SQL注入攻擊是你需要擔心的事情,不管你用什麼web編程技術,再說所有的web框架都需要擔心這個的。你需要遵循幾條非常基本的規則:
1)在構造動態SQL語句時,一定要使用類安全(type-safe)的參數加碼機制。大多數的數據API,包括ADO和ADO. NET,有這樣的支持,允許你指定所提供的參數的確切類型(譬如,字元串,整數,日期等),可以保證這些參數被恰當地escaped/encoded了,來避免黑客利用它們。一定要從始到終地使用這些特性。
例如,在ADO. NET里對動態SQL,你可以象下面這樣重寫上述的語句,使之安全:
Dim SSN as String = Request.QueryString("SSN")
Dim cmd As new SqlCommand("SELECT au_lname,au_fname FROM authors WHERE au_id = @au_id")
Dim param = new SqlParameter("au_id",SqlDbType.VarChar)
param.Value = SSN
cmd.Parameters.Add(param)
這將防止有人試圖偷偷注入另外的SQL表達式(因為ADO. NET知道對au_id的字元串值進行加碼),以及避免其他數據問題(譬如不正確地轉換數值類型等)。注意,VS 2005內置的TableAdapter/DataSet設計器自動使用這個機制,ASP. NET 2.0數據源控制項也是如此。
一個常見的錯誤知覺(misperception)是,假如你使用了存儲過程或ORM,你就完全不受SQL注入攻擊之害了。這是不正確的,你還是需要確定在給存儲過程傳遞數據時你很謹慎,或在用ORM來定製一個查詢時,你的做法是安全的。
2) 在部署你的應用前,始終要做安全審評(security review)。建立一個正式的安全過程(formal security process),在每次你做更新時,對所有的編碼做審評。後面一點特別重要。很多次我聽說開發隊伍在正式上線(going live)前會做很詳細的安全審評,然後在幾周或幾個月之後他們做一些很小的更新時,他們會跳過安全審評這關,推說,「就是一個小小的更新,我們以後再做編碼審評好了」。請始終堅持做安全審評。
3) 千萬別把敏感性數據在資料庫里以明文存放。我個人的意見是,密碼應該總是在單向(one-way)hashed過後再存放,我甚至不喜歡將它們在加密後存放。在默認設置下,ASP. NET 2.0 Membership API 自動為你這么做,還同時實現了安全的SALT 隨機化行為(SALT randomization behavior)。如果你決定建立自己的成員資料庫,我建議你查看一下我們在這里發表的我們自己的Membership provider的源碼。同時也確定對你的資料庫里的信用卡和其他的私有數據進行了加密。這樣即使你的資料庫被人入侵(compromised)了的話,起碼你的客戶的私有數據不會被人利用。
4)確認你編寫了自動化的單元測試,來特別校驗你的數據訪問層和應用程序不受SQL注入攻擊。這么做是非常重要的,有助於捕捉住(catch)「就是一個小小的更新,所有不會有安全問題」的情形帶來的疏忽,來提供額外的安全層以避免偶然地引進壞的安全缺陷到你的應用里去。
5)鎖定你的資料庫的安全,只給訪問資料庫的web應用功能所需的最低的許可權。如果web應用不需要訪問某些表,那麼確認它沒有訪問這些表的許可權。如果web應用只需要只讀的許可權從你的account payables表來生成報表,那麼確認你禁止它對此表的 insert/update/delete 的許可權。
6)很多新手從網上下載SQL通用防注入系統的程序,在需要防範注入的頁面頭部用 來防止別人進行手動注入測試(。
可是如果通過SQL注入分析器就可輕松跳過防注入系統並自動分析其注入點。然後只需要幾分鍾,你的管理員賬號及密碼就會被分析出來。
7)對於注入分析器的防範,筆者通過實驗,發現了一種簡單有效的防範方法。首先我們要知道SQL注入分析器是如何工作的。在操作過程中,發現軟體並不是沖著「admin」管理員賬號去的,而是沖著許可權(如flag=1)去的。這樣一來,無論你的管理員賬號怎麼變都無法逃過檢測。
第三步:既然無法逃過檢測,那我們就做兩個賬號,一個是普通的管理員賬號,一個是防止注入的賬號,為什麼這么說呢?筆者想,如果找一個許可權最大的賬號製造假象,吸引軟體的檢測,而這個賬號里的內容是大於千字以上的中文字元,就會迫使軟體對這個賬號進行分析的時候進入全負荷狀態甚至資源耗盡而死機。下面我們就來修改資料庫吧。
⒈對表結構進行修改。將管理員的賬號欄位的數據類型進行修改,文本型改成最大欄位255(其實也夠了,如果還想做得再大點,可以選擇備注型),密碼的欄位也進行相同設置。
⒉對表進行修改。設置管理員許可權的賬號放在ID1,並輸入大量中文字元(最好大於100個字)。
⒊把真正的管理員密碼放在ID2後的任何一個位置(如放在ID549上)。
由於SQL注入攻擊針對的是應用開發過程中的編程不嚴密,因而對於絕大多數防火牆來說,這種攻擊是「合法」的。問題的解決只有依賴於完善編程。專門針對SQL注入攻擊的工具較少,Wpoison對於用asp,php進行的開發有一定幫助...。

F. c# sqlparameter絕對能防注入

沒有絕對的事情...
現在的黑客也會與時俱進...你會防他就會想到辦法去功...
sqlparameter估計是最經常用的啦...參數可以降低注入的攻擊...
如何防範SQL注入攻擊:
http://ke..com/view/983303.htm
下面有介紹

G. C#防止sql注入問題

採用了參數法給sql傳遞參數

SQL注入的原理你要先了解,因為以前SQL語句是用字元串拼接來組的.所以就有人想到如果我輸入一個單引號來閉合原本程序里的單引號 然後在自己加些條件呢.

加入原本代碼
String SQLStr = "select * from t_users where username='"+ txtusername.Text +"'";

如果你輸入'or 1=1 -- 我們的SQLStr會變成什麼呢

select * from t_users where username = '' or 1=1 --'
--後面屬於sql的注釋 所以都忽略了 即使後面有其他條件也忽略了

所以這條SQL執行總是有返回結果,至於其他的高級的試探性語句你可以搜索其他資料

====================================================================
採用參數法添加數據的話 就不會出現這樣的問題.

程序會把'or 1=1 -- 當成一個整體的字元串 然後在兩頭加單引號 變成這樣'\' or 1=1 --' 由於\屬於轉義字元 所以不會閉合前面的單引號

所以這樣就防止了注入

//望採納

H. 關於注冊防止sql注入,用參數的形式,怎麼實現呢

sql語句書寫格式:
string sql = "insert into tablename values(@canshu1,@canshu2,@canshu3)";
SqlParameter[] sp = new SqlParameter[]{ //參數賦值
new SqlParameter ("@canshu1",canshu1 ),
new SqlParameter ("@canshu2",canshu2 ),
new SqlParameter ("@canshu3",canshu3 ),

};
int rs = db.Execute(sql, sp);//執行sql語句

執行參數化SQL語句的方法:
public int Execute(string sql, SqlParameter[] values)
{
SqlCommand cmd = new SqlCommand();
cmd.CommandText = sql;
cmd.Connection = DBMM.Conn;
cmd.Parameters.AddRange(values);
cmd.Connection.Open();
SqlTransaction tran = cmd.Connection.BeginTransaction();
cmd.Transaction = tran;
try
{
cmd.ExecuteNonQuery();
tran.Commit();
}
catch (Exception ex)
{
tran.Rollback();
return 0;
}
finally
{
cmd.Connection.Close();
}
return 1;
}