• sql注入


    在web项目中,有一个原则是永远不要相信从用户端传过来的不做处理的数据。

    比如后端有个登陆接口;

    @RequestMapping("/user/login")
        public String login(String name, String password)  {
            String sql="select * from tp_user where name="+name+" and password ="+password;
            //执行sql 得到user
            User user = dao.excute(sql);
            //session或者分发token
            //.....
            return user==null?"登陆失败":"登陆成功";
        }

    这是一个很常见的登陆接口,用户会从表单里填入用户名和密码 后端根据用户名和密码去数据库查询 如果有该用户存在就登陆成功。这个逻辑乍一看没问题,但是如果前端填入的数据是这样的

    @RequestMapping("/user/login")
        public String login(String name, String password)  {
            name="admin or 1=1 -- ";
            password="1234";
            String sql="select * from tp_user where name="+name+" and password ="+password;

    User user = dao.excute(sql);
            return user==null?"登陆失败":"登陆成功";
     }

    需要注意的是 此刻拼接而成的sql语句为

    select * from tp_user where name=admin or 1=1 -- and password=1234

    在sql语言里,--表示注释 会注释掉后面的语句,实际这句话为

    select * from tp_user where name=admin or 1=1

    这条语句只要表里有数据那就是百分百成功的,这只是伪装了登陆,如果用户传入的是“;drop table xx” 那么执行这条语句的后果可想而知。

    针对sql注入,前端解决的方式则为数据格式正则校验,不允许使用特殊符号等等,后端则为预编译和参数化。

    预编译的解释为 先预编译sql语句,使他的语义固定,即查询则为查询不允许执行其他操作,参数化则是将传过的值转义作为参数,比如上面的语句

            name="admin or 1=1 -- ";
            password="1234";
            String sql="select * from tp_user where name="+name+" and password ="+password;
            //未参数化
            // "select * from tp_user where name=admin or 1=1 -- and password=1234"
            //参数化后则为
            //  "select * from tp_user where name= 'admin or 1=1 --' and 'password=1234'"

    常见的持久层框架mybatis和hibernate中都有避免参数直接拼接语句的方法,比如mybatis中的#{}则是在任何参数上加一个' '。将传入的数据始终当成一个字符串。hibernate自写语句也有对应的占位符 通过修改占位符来参数化避免此问题。

    sql注入说起来应该算是一种优点,是数据库保证有权限的用户有100%的掌控。在开发项目中应该对用户的数据进行校验实行白名单制(符合白名单正则的语句才可以执行) 或者使用持久层框架封装好的api。一定要对数据进行校验,不然可能会导致一些未知的错误(击穿,注入。。)。

    不和别人一样,不复制只真正理解
  • 相关阅读:
    验证码图片不刷新解决方法
    表单验证
    Thinkphp显示系统常量信息的方法(php的用法)
    原生sql语句执行
    Python中的模块(2)
    Python 正则表达式中级
    正则表达式 和 原生字符串 r
    collections模块
    时间模块
    random模块
  • 原文地址:https://www.cnblogs.com/Vinlen/p/13596014.html
Copyright © 2020-2023  润新知