日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

Dapper防sql注入,同一条SQL支持多种数据库

發(fā)布時間:2023/12/4 数据库 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Dapper防sql注入,同一条SQL支持多种数据库 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

前言

防SQL注入,常用的方案是使用Dapper執(zhí)行SQL的參數(shù)化查詢。例如:

using?(IDbConnection?conn?=?CreateConnection()) {string?sqlCommandText?=?@"SELECT?*?FROM?USERS?WHERE?ID=@ID";Users?user?=?conn.Query<Users>(sqlCommandText,?new?{?ID?=?2?}).FirstOrDefault();Console.WriteLine(user.Name); }

但是,不同數(shù)據(jù)庫支持不同的sql參數(shù)格式,例如,ORACLE必須使用:ID,否則上述代碼會報錯:

Pseudo-Positional Parameters

查看Dapper的源代碼[1],發(fā)現(xiàn)有這樣一段:

cmd.CommandText?=?pseudoPositional.Replace(cmd.CommandText,?match?=> {string?key?=?match.Groups[1].Value;if?(!consumed.Add(key)){throw?new?InvalidOperationException("When?passing?parameters?by?position,?each?parameter?can?only?be?referenced?once");}else?if?(parameters.TryGetValue(key,?out?IDbDataParameter?param)){if?(firstMatch){firstMatch?=?false;cmd.Parameters.Clear();?//?only?clear?if?we?are?pretty?positive?that?we've?found?this?pattern?successfully}//?if?found,?return?the?anonymous?token?"?"if?(Settings.UseIncrementalPseudoPositionalParameterNames){param.ParameterName?=?(++index).ToString();}cmd.Parameters.Add(param);parameters.Remove(key);consumed.Add(key);return?"?";}else{//?otherwise,?leave?alone?for?simple?debuggingreturn?match.Value;} });

通過查看Dapper教程[2],原來,這是實(shí)現(xiàn)被稱為Pseudo-Positional Parameters(偽位置參數(shù))的代碼,作用是為了不支持命名參數(shù)的數(shù)據(jù)庫提供者能夠使用參數(shù)化SQL,例如OleDB:

//代碼 var?docs?=?conn.Query<Document>(@"select?*?from?Documentswhere?Region?=??region?and?OwnerId?in??users?",?new?{?region,?users?}).AsList();//SQL select?*?from?Documentswhere?Region?=??and?OwnerId?in?(?,?,?)

自定義Pseudo-Positional Parameters

依葫蘆畫瓢,我們可以實(shí)現(xiàn)自己的Pseudo-Positional Parameters,以便支持更多的數(shù)據(jù)提供者:

private?static?readonly?Regex?pseudoRegex?=?new?Regex(@"\$([\p{L}_][\p{L}\p{N}_]*)\$",?RegexOptions.IgnoreCase?|?RegexOptions.CultureInvariant?|?RegexOptions.Compiled);public?static?string?ReplacePseudoParameter(IDbConnection?conn,?string?cmdText) {return?pseudoRegex.Replace(cmdText,?match?=>?{var?key?=?match.Groups[1].Value;if?(conn?is?OleDbConnection){return?"?"?+?key?+?"?";}return?(conn?is?OracleConnection???":"?:?"@")?+?key;}); }

使用方式是在參數(shù)名稱兩邊加上$:

string?sqlCommandText?=?@"SELECT?*?FROM?USERS?WHERE?ID=$ID$";Users?user?=?conn.Query<Users>(ReplacePseudoParameter(conn,?sqlCommandText),?new?{?ID?=?2?}).FirstOrDefault();

結(jié)論

通過實(shí)現(xiàn)Pseudo-Positional Parameters功能,我們讓Dapper防sql注入支持了多種數(shù)據(jù)庫。

如果你覺得這篇文章對你有所啟發(fā),請關(guān)注我的個人公眾號”My IO“

參考資料

[1]

源代碼: https://github.com/DapperLib/Dapper/blob/main/Dapper/SqlMapper.cs#L1783

[2]

Dapper教程: https://riptutorial.com/Dapper/example/13835/pseudo-positional-parameters--for-providers-that-don-t-support-named-parameters-

總結(jié)

以上是生活随笔為你收集整理的Dapper防sql注入,同一条SQL支持多种数据库的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。