我用这句话来验证:
select * from usertab where id=" '+id+' "and pwd=" '+pwd+' ";
但是某些书上说,如果在密码框输入这个串:
" 'or''1'='1' "
服务器就得到这样的一句话:
select * from usertab where id='+id+'and pwd=''or  '1'='1'
结果就通过了。
精英们有何高见?如何防冶?

解决方案 »

  1.   

    算是sql的漏洞吧~~N年前就有了。
         一般叫做sql的注入式攻击。
    防范的方法很多。
    1不采用这样的写法,通过占位符执行sql。
    2用正则屏蔽特殊符号。
    3尽量不要用url传递参数。
     等等
      

  2.   

    1不采用这样的写法,通过占位符执行sql。 能给个例子吗?
    2用正则屏蔽特殊符号。 能给个例子吗?
    3 谢谢!
      

  3.   

    关键在于不要使用“拼凑式”的组成sql语句!!在jsp中,是采用PreparedStatement(睁大眼睛看清楚这个单词是怎么写的!)
    prestmt = conn.prepareStatement(sql);(再睁大眼睛看清楚它是怎么赋值的,特别注意单词的不一样,一个PreparedStatement,一个是
    prepareStatement)
    ------------------------------------------------------------------------------
    <%@ page contentType="text/html; charset=UTF-8" %>
    <%@ page import = "java.io.*" %>  
    <%@ page import="java.sql.*"%> 
    <%@ page import = "java.util.*"%>
    <html>   
    <body background="LoginBackgroundTile.gif"> 
    <%! 
        String url="jdbc:mysql://192.168.0.10:3306/maintainplatform"; 
        String user="root"; 
        String password="root";
        Connection conn;
        String sql;
        ResultSet rs;
        String userId ;
        String userPassword;
        PreparedStatement prestmt;
    %>
    <%
      userId = request.getParameter("userId");
      userPassword = request.getParameter("userPassword");
      out.println(userId);
      out.println(userPassword);
      sql = "select * from usertable where UserId = ? and Password = ? ";
      int count = 0;
    try
    {
    Class.forName("org.gjt.mm.mysql.Driver").newInstance();  
    conn= DriverManager.getConnection(url,user,password);  
    prestmt = conn.prepareStatement(sql);
    prestmt.setString(1,userId);
    prestmt.setString(2,userPassword);
    rs = prestmt.executeQuery();
     while(rs.next()) 
    {   
       count++;
    }
    %>   
    <% if (count > 0)
    {
       out.print("验证成功!");
       session.setAttribute("username",userId); 
        %>
       <% response.sendRedirect("a/Connectmysql.jsp"); %>
        <%
     }
       else
         {%>
    <center><font color = "red"><%out.println("用户名或密码错误");%></font>
      <a href = "login.jsp"><font color = "red">try it again</font></a></center>
        <% }
         }
    catch (SQLException ex) {
                System.out.println("SQLException: " + ex.getMessage());
                System.out.println("SQLState: " + ex.getSQLState());
                System.out.println("VendorError: " + ex.getErrorCode());
                 }
    %>   <br>
    <%rs.close();   
    prestmt.close();   
    conn.close();   
    %>   
    </body>   
    </html> 
    --------------------------------------------------------------------------
    作为对比,以下是不安全的的写法
    <%@ page contentType="text/html; charset=UTF-8" %>
    <%@ page import = "java.io.*" %>  
    <%@ page import="java.sql.*"%> 
    <html>   
    <body> 
    <%! 
        String url="jdbc:mysql://192.168.0.10:3306/maintainplatform"; 
        String user="root"; 
        String password="root";
        Connection conn;
        Statement stmt;
        String sql;
        ResultSet rs;
        String userId ;
        String userPassword;
    %>
    <%
      userId = request.getParameter("userId");
      userPassword = request.getParameter("userPassword");
      out.println(userId);
      out.println(userPassword);
      String sql ="select * from usertable where UserId ='" + userId + "'and  Password ="+"'" + userPassword +"'";
      int count = 0;
    try
    {
    Class.forName("org.gjt.mm.mysql.Driver").newInstance();  
    conn= DriverManager.getConnection(url,user,password);  
    stmt=conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);
    rs=stmt.executeQuery(sql);  
    }
    catch (SQLException ex) {
                System.out.println("SQLException: " + ex.getMessage());
                System.out.println("SQLState: " + ex.getSQLState());
                System.out.println("VendorError: " + ex.getErrorCode());
            }
     while(rs.next()) 
    {   
       count++;
    }
    %>   
    <% if (count > 0)
    {
       out.print("验证成功!");
       session.setAttribute("username",userId); 
        %>
       <a href = "a/index.jsp" >验证成功,点击进入首页</a>
        <%
     }
       else
         {
    out.println("用户名或密码错误");%>
    <a href = "login.jsp">try it again</a>
        <% }
    %>   <br>
    <%rs.close();   
    stmt.close();   
    conn.close();   
    %>   
    </body>   
    </html>