防sql注入的网站登录系统设计与实现

|-------------------------------|---|---|---|--------|---|--------|---|
| 课程名称 ||| 网络安全 |||||
| 大作业名称 ||| 防sql注入的网站登录系统设计与实现 |||||
| 姓名 || || 学号 | | 班级 | |
| | 1. 结合mysql数据库设计一个web登录页面 2. 密码需密文存放(可以采用hash方式,建议用sha1或md5加盐) 3. 采用服务器端的验证码(防止bp爆破)或token方式 4. 对同一ip地址登录错误超过3次,暂停5分钟(防止bp爆破,sqlmap爆破) 5. 能够防住简单注入和宽字节注入(需有测试的案例) 6. 能够基本防住手动注入和sqlmap攻击(需有测试的案例) 7. 能够防止sql注入原因分析 8. 课程心得体会、建议。 |||||||
| | SQL注入详解(全网最全,万字长文)-CSDN博客 1. 结合mysql数据库设计一个web登录页面 1. 密码需密文存放(可以采用hash方式,建议用sha1或md5加盐) String newPwdMD5 = DigestUtils.md5DigestAsHex (newPwd.getBytes(StandardCharsets.UTF_8 )); 1. 采用服务器端的验证码(防止bp爆破)或token方式 public class GenerateCaptchaServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException, IOException { int width = 150; int height = 50; BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB ); Graphics2D g2d = image.createGraphics(); g2d.setColor(Color.WHITE ); g2d.fillRect(0, 0, width, height); g2d.setFont(new Font("Arial", Font.BOLD , 30)); Random random = new Random(); int captchaValue = random.nextInt(9000) + 1000; String captcha = String.valueOf (captchaValue); g2d.setColor(Color.BLACK ); g2d.drawString(captcha, 20, 35); request.getSession().setAttribute("captcha", captcha); response.setContentType("image/png"); ImageIO.write (image, "png", response.getOutputStream()); } } if (!enteredCaptcha.equals(storedCaptcha)) { session.setAttribute("msg", "验证码错误"); incrementErrorCount(ipAddress, request, response); return; } 1. 对同一ip地址登录错误超过3次,暂停5分钟(防止bp爆破,sqlmap爆破) 在登录的时候先检查IP有没有被停用,然后接着就是检测验证码,账户,密码,只要错误就调用incrementErrorCount。 IpErrorCounts是一个HashMap用于记录相应ip的错误次数。 pausedIps用于记录停用时间 private void incrementErrorCount(String ipAddress, HttpServletRequest request, HttpServletResponse response) throws IOException { Integer errorCount = ipErrorCounts .getOrDefault(ipAddress, 0); errorCount++; ipErrorCounts .put(ipAddress, errorCount); // 如果错误次数超过 3 次,暂停 IP if (errorCount > 3) { pausedIps .put(ipAddress, new Date()); } response.sendRedirect(request.getContextPath() + "/goat.jsp"); } // 获取 IP 地址 String ipAddress = request.getRemoteAddr(); // 检查 IP 是否被暂停(这里的pausedlps是一个HashMap) if (pausedIps .containsKey(ipAddress)) { Date pauseStartTime = pausedIps .get(ipAddress); Date currentTime = new Date(); long timeDiff = currentTime.getTime() - pauseStartTime.getTime(); long fiveMinutesInMillis = 5 * 60 * 1000; if (timeDiff < fiveMinutesInMillis) { HttpSession session = request.getSession(); session.setAttribute("msg", "你的 IP 因多次登录失败被暂停,请 5 分钟后再试。"); response.sendRedirect(request.getContextPath() + "/goat.jsp"); return; } else { pausedIps .remove(ipAddress); } } 1. 能够防住简单注入和宽字节注入(需有测试的案例) 其实sql注入说白了,就是需要到达数据库那个层面才能发挥作用,我直接正则限制输入再加上输入不符合就直接阻止事件的发生,干掉。 const emailRegex = /^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+/; const ******numberRegex****** = /\^\\d+/; loginBtn .click(function (event) { let username = userName .val(); let pwd = passWord .val(); let captcha = captchaInput .val(); if (username === "" || pwd === "" || captcha === "") { error .text("存在未填写的信息,请输入"); event.preventDefault(); return false; } else if(!emailRegex .test(username)){ error .text("邮箱格式错误"); event.preventDefault(); } else if(!numberRegex .test(pwd)){ error .text("密码格式错误"); event.preventDefault(); } }); 宽字节注入: 攻击者输入用户名 admin%df' or 1=1-- 和任意密码,当应用程序将这个用户名拼接到 SQL 查询中时,由于数据库连接使用了宽字节字符编码(如 GBK),%df'会被解释为一个汉字,从而绕过了单引号的过滤。 1. 能够基本防住手动注入和sqlmap攻击(需有测试的案例) 手工注入: 在知道邮箱(账户)的情况下可以使用 第一张图片解析(个人理解): 我这里先假设我前端没有用正则会是什么情况 点击登录后的数据库语句 select * from reader where email = 'taotao@qq.com'#' select * from reader where email = 'taotao@qq.com'#' and pwd='...' 第一张图片: 在数据库中#代表的是注释,#后面的就不用管了 这里可以讨论一下以上两种登录方式: 第一种是先根据用户名来找到一个对象,然后在判断密码是否正确的,这种就能防止现在这种情况的注入。 但是第二种是直接查,这种密码是多少都可以,只要邮箱正确就行,明显防止不了。当然如果在后面又加了判断密码也可以防止,但是这样的话,相较于第一种代码量增加,还浪费了资源(查了两个字段,为了防止注入,还要复制第一种写法后面的代码,多了判断) 第二种图片: 有同学自己可能写了一下,感觉不行,觉得密码不对过不了,觉得是从左到右先or然后在and,那就错了 select * from reader where email = 'taotao@qq.com'or'1'='1' and pwd='...' 在数据库中,and的优先级比or高,所以语句可以这样表示: select * from reader where (email = 'taotao@qq.com')or('1'='1' and pwd='...') 是先and然后在or,一目了然 当然如果直接正则限制输入,那这种注入都到不了数据库那一层面,直接限制到了前端,请求都发不过去。 Sqlmap攻击: sqlmap基础知识_sqlmap简介-CSDN博客 最直接的方法直接不使用关系型数据库,用Nosql。(开玩笑) 在查询了相关资料后,了解到这种注入方式居然可以直接绕过前端的检测,牛的,那这直接打破我的认知,又要思考了。。。。。那就加后端检测吧。查资料(应该在后端服务器端进行严格的输入验证和 SQL 注入防范措施,如使用参数化查询、输入过滤和转义等技术,以确保数据库的安全。)。 那就直接在后端也搞正则检测。 这个没有进行实操过,当然也不太清楚怎么去实操,没了解过。 1. 能够防止sql注入原因分析 Sql注入无非就是写一段sql代码来插入到一些sql语句当中,利用#、'等符号来实现一些不可思议的作用,所以对于输入的检测、过滤是必要的。 前端我是用的正则表达式来判断输入的东西,并且不符合就阻止事件的发生(请求),而且我后端是先根据输入的东西找到一个对象,再去判断其他的。当然post请求也发挥着作用,毕竟如果是get请求url就直接显示相关信息了。 |||||||

相关推荐
小胖胖吖2 分钟前
docker compose一键部署容器监控 CAdvisor+InfluxDB+Granfana
运维·docker·容器
微刻时光4 分钟前
Docker镜像命令汇总笔记
linux·运维·笔记·ubuntu·docker·容器·centos
华为云PaaS服务小智5 分钟前
搭建Serverless社交媒体分析平台,Dataxet运维成本降低50%
运维·serverless·媒体
iQM756 分钟前
为什么MySQL不建议使用delete删除数据
数据库·mysql
大吱佬7 分钟前
CentOS快速配置网络&&Docker快速部署
linux·服务器·tcp/ip
Xerale16 分钟前
Laravel Admin 中的 “Array to String Conversion“ 问题及其解决方法
前端·数据库·笔记·php·laravel
FANGhelloworld22 分钟前
TCP网络通信——多线程
linux·服务器·网络·信息与通信·tcp
丶21361 小时前
【SQL】深入探索SQL调优:提升数据库性能的全面指南
数据库·sql·性能优化
盒马盒马1 小时前
Redis:分布式 - 哨兵
数据库·redis·分布式
好好学习的人1 小时前
SQL第15课——插入数据
数据库·sql·oracle