防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就直接显示相关信息了。 |||||||

相关推荐
天赐学c语言1 分钟前
Linux - 应用层自定义协议与序列/反序列化
linux·服务器·网络·c++
jarreyer6 分钟前
CentOS 7 无法使用 yum 安装软件
linux·运维·centos
hzhsec8 分钟前
MSF-CobaltStrike实现内网socks代理转发上线
服务器·网络·安全·网络安全
不想看见40422 分钟前
Qt 项目中实现良好封装(模块化设计)的详细流程指南
数据库·系统架构
脆皮的饭桶26 分钟前
结合使用,实现IPVS的高可用性、利用VRRP Script 实现全能高可用
运维·服务器·网络
mygljx29 分钟前
MySQL 数据库连接池爆满问题排查与解决
android·数据库·mysql
Jeremy爱编码32 分钟前
软考数据库
数据库
Bdygsl2 小时前
MySQL(1)—— 基本概念和操作
数据库·mysql
zongzizz2 小时前
Oracle 11g 两节点rac在机房断电重启后PL/SQL和客户端连接数据库报错ORA-12541
数据库·oracle
RisunJan2 小时前
Linux命令-md5sum(计算和校验文件报文摘要的工具程序)
linux·运维