delete from|from|count\(|drop table|update|truncate|mid\(|char\(|xp_cmdshell|exec master|netlocalgroup administrators|net user|[\{|\}|!|\'] 我怎么写一个正则表达式去匹配这些, 比如说 : select 什么 from 这样,我中间不限制, 但只要这串字符,里面同时出现 select 什么 from 我就要过滤了
如from delete count update select 这些字符单个出现,我不过滤它,可能有点用户名或密码就是这样的。
如from delete count update select 这些字符单个出现,我不过滤它,可能有点用户名或密码就是这样的。
var reg = /(.*?((select)|(from)|(count)|(delete)|(update)|(drop)|(truncate)).*?){2,}/i;
alert(reg.test(str));
但推荐用类似 JAVA 里 Prestatement 的方式,全用 ? 代替关键词
不管是否是可执行的SQL,在 ? 面前都没辙
(ASP.net 里有类似方法,估计其它语言也有吧)
就是说: 我现在要过滤那些关键字 ,假如说我现在在文本框中输入: select * from 是不是要过滤啊! 但我单输入一个select 这样就不能防止它。。 我现在就是防止过当了, 我现在只要输入的字符串中出现 关键字, 比如说: 我输入的是 aselect 这样也被防止了
不要把问题弄太繁琐了,有利必有弊。
网上一搜一大堆~~~!
SQL 指令撰写方法
在撰写 SQL 指令时,利用参数来代表需要填入的数值,例如:
[编辑] Microsoft SQL Server
Microsoft SQL Server 的参数格式是以 "@" 字符加上参数名称而成,SQL Server 亦支持匿名参数 "?"。 SELECT * FROM myTable WHERE myID = @myID
INSERT INTO myTable (c1, c2, c3, c4) VALUES (@c1, @c2, @c3, @c4)[编辑] Microsoft Access
Microsoft Access 不支持具名参数,只支持匿名参数 "?"。 UPDATE myTable SET c1 = ?, c2 = ?, c3 = ? WHERE c4 = ?[编辑] MySQL
MySQL 的参数格式是以 "?" 字符加上参数名称而成。 UPDATE myTable SET c1 = ?c1, c2 = ?c2, c3 = ?c3 WHERE c4 = ?c4[编辑] 用户端程序撰写方法
在用户端代码中撰写使用参数的代码,例如:
[编辑] ADO.NET
SqlCommand sqlcmd = new SqlCommand("INSERT INTO myTable (c1, c2, c3, c4) VALUES (@c1, @c2, @c3, @c4)", sqlconn);
sqlcmd.Parameters.AddWithValue("@c1", 1); // 設定參數 @c1 的值。
sqlcmd.Parameters.AddWithValue("@c2", 2); // 設定參數 @c2 的值。
sqlcmd.Parameters.AddWithValue("@c3", 3); // 設定參數 @c3 的值。
sqlcmd.Parameters.AddWithValue("@c4", 4); // 設定參數 @c4 的值。
sqlconn.Open();
sqlcmd.ExecuteNonQuery();
sqlconn.Close();[编辑] PHP
$query = sprintf("SELECT * FROM Users where UserName='%s' and Password='%s'",
mysql_real_escape_string($Username),
mysql_real_escape_string($Password));
mysql_query($query);
或是$db = new mysqli("localhost", "user", "pass", "database");
$stmt = $mysqli -> prepare("SELECT priv FROM testUsers WHERE username=? AND password=?");
$stmt -> bind_param("ss", $user, $pass);
$stmt -> execute();[编辑] JDBC
PreparedStatement prep = conn.prepareStatement("SELECT * FROM USERS WHERE USERNAME=? AND PASSWORD=?");
prep.setString(1, username);
prep.setString(2, password);[编辑] Cold Fusion
<cfquery name="Recordset1" datasource="cafetownsend">
SELECT *
FROM COMMENTS
WHERE COMMENT_ID =<cfqueryparam value="#URL.COMMENT_ID#" cfsqltype="cf_sql_numeric">
</cfquery>
//-----------------------------------------------------------------
if( ope.equals("add_xxxxx") )
{
String arr[] = { request_m.getParameter( "iid" ),
request_m.getParameter( "items" )
};
if( update( "insert into web_xxxxx( id, comment ) values(?,?) ", arr ) > 0 )
return "操作成功";
}
//-----------------------------------------------------------------
private int update( String sql, String[] arr )throws Exception
{
xxxxxx.database db = new xxxxxx.database();
db.getConn ( );
db.getPstmt( sql );
int i = 0;
for( String ech : arr )
{ i++;
db.pstmt.setString( i, ech );
}
return db.pstmt.executeUpdate();
}
//----------------------------------------------------------------
public class database
{
............
public PreparedStatement pstmt = null;
............
public void getPstmt( String sqlstr )throws Exception
{
pstmt = conn.prepareStatement(sqlstr);
}
............
............
}
我现在把它写成这样 http://localhost/webfrom1.aspx?id=1' <script> 就这个<script> 会引发异常, 在在程序里面也过滤了这个<> , 在用户名那输入 <script> 就拦截了, 不知道在地址栏为什么拦截不了
foreach (string strQuery in this.Request.QueryString)
{
if (Request.QueryString[strQuery].Trim().Equals("")) continue;
if (this.CheckKey(Request.QueryString[strQuery], sql, special))
{
flag = true;
error = new string[] { "QueryString", strQuery };
break;
}
}
这里也写了拦截地址栏的啊! 不知道为什么就读取不了 纳闷
客户端没必要检测,多此一举客户端的检测仅仅是为了让客户清楚应该输入什么,而不应该因为安全因而在客户端用js过滤。安全因素最终是要服务端来检测拦截的。