Java应用程序中的SQL注入

在本文中,我们将讨论什么是SQL注入攻击。 以及它如何影响任何Web应用程序使用后端数据库。 在这里,我专注于Java Web应用程序。 开放Web应用程序安全项目(OWAP)列出了SQL注入是Web应用程序的主要漏洞攻击。 黑客将Web请求中的SQL代码注入Web应用程序并控制了后端数据库,即使后端数据库未直接连接到Internet也是如此。 我们将看到如何解决和防止Java Web Application中的SQL注入。

为此,我们需要1个工具。 这些工具是完全开源的。 SQL Map – SqlMap是一种开源渗透测试工具,可自动执行检测和利用SQL Injection的过程。 我们可以从这里得到。

SQL注入

SQL注入是通过Web应用程序提取数据库信息的技术。
场景:

我们有一台数据库服务器[MySQL]和Web应用程序服务器[Tomcat]。 考虑数据库服务器未连接到Internet。 但它与应用程序服务器连接。 现在我们将看到使用Web应用程序如何使用sql-injection方法提取信息。

在查看sql注入之前,我们创建了小型Web应用程序。 它包含单个jsp页面,像这样

<form action='userCheck'>

<input type='text' name='user' value=''/>

<input type='submit' value='Submit'/>

</form>

在userCheck中,Servlet接收用户输入字段并连接到数据库服务器,并根据用户输入触发sql查询,并接收ResultSet并将其迭代打印到网页中。
userCheck servlet

protected void processRequest(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
        response.setContentType('text/html;charset=UTF-8');
        PrintWriter out = response.getWriter();
        try {

            String user = request.getParameter('user');
            Connection conn = null;
            String url = 'jdbc:mysql://192.168.2.128:3306/';
            String dbName = 'anvayaV2';
            String driver = 'com.mysql.jdbc.Driver';
            String userName = 'root';
            String password = '';
            try {
                Class.forName(driver).newInstance();
                conn = DriverManager.getConnection(url + dbName, userName, password);

                Statement st = conn.createStatement();
                String query = 'SELECT * FROM  User where userId='' + user + ''';
                out.println('Query : ' + query);
                System.out.printf(query);
                ResultSet res = st.executeQuery(query);

                out.println('Results');
                while (res.next()) {
                    String s = res.getString('username');
                    out.println('\t\t' + s);
                }
                conn.close();

            } catch (Exception e) {
                e.printStackTrace();
            }
        } finally {
            out.close();
        }

当我们执行上面的代码时。 在正常的输入执行中,如下所示

当我们使用“ ramki”之类的正常值时,请点击“提交”按钮,然后像这样输出

在正常行为中,它是完全正确的。 当我在输入框中输入一些特殊字符或某些sql语句时会发生什么?

当我们单击提交按钮时,它将显示我的表格中的所有行,如下所示

这是我应用程序中的一个重大安全漏洞。 发生了什么……是一种SQL注入。

让我们看看发生什么了。

当我在输入框中输入正常值时,我的servlet接收并替换sql查询并执行它。

SELECT * FROM User where userId='ramki'

是正确的,我们得到了正确的输出。

当我放入sdfssd'或'1'='1时会发生什么

SELECT * FROM用户,其中userId =' sdfssd'或'1'='1 '

它的手段

SELECT * FROM User where userId ='sdfssd' or '1'='1'

像这样。 因此,我们的查询已更改。 现在新查询有2个条件。 第二条件始终为真。 第一个条件可能是正确的,也可能不是。 但是这两个条件与或逻辑相连。 因此where子句对于所有行始终为true。 结果是它们带来了表中的所有行。

这称为盲SQL注入。 如果您想了解更多有关SQL注入的详细信息,请点击此处

现在我们可以直接在输入框中输入sql语句

喜欢

ramki'UNION SELECT * FROM mysql.`user` u —

然后

SELECT * FROM User where userId =' ramki'UNION SELECT * FROM MySQL.`user` u — '

然后它的意思

SELECT * FROM User where userId ='ramki' UNION SELECT * FROM mysql.`user` u --'

在这里,他们不会使用*,因为它与第一个表不匹配。 因此,他们找到了多少列,然后将联合表与第二个表一起使用。他们想要的用户特定列。 结果,获取mysql数据库用户信息通过我们的Web应用程序公开。

sqlmap

它配备了强大的检测引擎,针对最终渗透测试仪的众多细分功能以及从数据库指纹识别到从数据库获取数据的广泛转换

在您的系统中安装sqlmap或使用BackTrack Linux

在这里,我使用了回溯Linux,因为它已经预先安装了许多应用程序,例如sqlmap。

在回溯中,sqlmap位于/ pentest / web / scanner / sqlmap中

sqlmap命令

检索所有数据库

./sqlmap.py -u http://localhost:8080/SQLInject/userCheck?user=ramki --dbs

检索所有表

./sqlmap.py -u http://localhost:8080/SQLInject/userCheck?user=ramki -D test --tables

从特定表中检索所有列

./sqlmap.py -u http://localhost:8080/SQLInject/userCheck?user=ramki -D test -T User --columns

转储特定表中所有值的列

./sqlmap.py -u http://localhost:8080/SQLInject/userCheck?user=ramki -D test -T User --dump

转储特定表中某些值的列

./sqlmap.py -u http://localhost:8080/SQLInject/userCheck?user=ramki -D test -T User -C userId,password --dump

观看视频以获取完整的演示(高清观看):

http://www.youtube.com/watch?feature=player_embedded&v=C5PQ86nWMkM

如何防止SQL注入

  • 在替代查询之前,我们需要进行验证。 删除ir可以避免使用特殊字符(如单引号),关键字(如select,Union)等。
  • 与占位符一起使用准备好的语句
PreparedStatement  preparedStatement=conn.prepareStatement('SELECT * FROM  usercheck where username=?') ;
preparedStatement.setString(1, user);

setXXX()方法进行所有验证并转义特殊字符

现在,如果使用相同的盲注SQL注入

sdfssd'或'1'='1然后

SELECT * FROM User where userId='sdfssd\' or \'1\'=\'1'

在这里,所有特殊字符都被转义。当我们使用JPA类的ORM工具(例如Hibernate,EclipseLink,TopLink)时,也可能出现sqlinjection。

为了防止SQL注入,我们需要使用NamedQuery代替普通的Query。 因为NamedQuery在内部使用PreparedStement,但是普通查询在Java中使用norma Stement。

JPA中的普通查询

String q='SELECT r FROM  User r where r.userId=''+user+''';
Query query=em.createQuery(q);
List users=query.getResultList();

所以不要使用普通查询,而是使用命名查询

Query query=em.createNamedQuery('User.findByUserId');
query.setParameter('userId', user);
List users=query.getResultList();


您可以从GitHub (或) Google代码下载演示代码

参考:Ramki Java Blog博客上,请我们的JCG合作伙伴 Rama Krishnan 注意Java应用程序中的SQLInjection

翻译自: https://www.javacodegeeks.com/2012/11/sql-injection-in-java-application.html

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
package com.tarena.dingdang.filter; 02 03 import java.io.IOException; 04 import java.util.Enumeration; 05 06 import javax.servlet.Filter; 07 import javax.servlet.FilterChain; 08 import javax.servlet.FilterConfig; 09 import javax.servlet.ServletException; 10 import javax.servlet.ServletRequest; 11 import javax.servlet.ServletResponse; 12 import javax.servlet.http.HttpServletRequest; 13 14 public class AntiSqlInjectionfilter implements Filter { 15 16 public void destroy() { 17 // TODO Auto-generated method stub 18 } 19 20 public void init(FilterConfig arg0) throws ServletException { 21 // TODO Auto-generated method stub 22 } 23 24 public void doFilter(ServletRequest args0, ServletResponse args1, 25 FilterChain chain) throws IOException, ServletException { 26 HttpServletRequest req=(HttpServletRequest)args0; 27 HttpServletRequest res=(HttpServletRequest)args1; 28 //获得所有请求参数名 29 Enumeration params = req.getParameterNames(); 30 String sql = ""; 31 while (params.hasMoreElements()) { 32 //得到参数名 33 String name = params.nextElement().toString(); 34 //System.out.println("name===========================" + name + "--"); 35 //得到参数对应值 36 String[] value = req.getParameterValues(name); 37 for (int i = 0; i < value.length; i++) { 38 sql = sql + value[i]; 39 } 40 } 41 //System.out.println("============================SQL"+sql); 42 //有sql关键字,跳转到error.html 43 if (sqlValidate(sql)) { 44 throw new IOException("您发送请求的参数含有非法字符"); 45 //String ip = req.getRemoteAddr(); 46 } else { 47 chain.doFilter(args0,args1); 48 } 49 } 50 51 //效验

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值