闭关修炼(二十五)基础web安全
作者:互联网
不是特别难,主要是积累经验
赶紧学springboot去了,好拖延啊。捂脸
文章目录
常见的攻击有哪些?
SQL注入,XSS,CSRF(和表单重复提交是一个类型)
最基本的WEB安全防范:密码设为英文+数字+特殊符号,访问白名单
表单重复提交
表单重复提交十分常见,
表单重复提交主要原因是网络延迟
简单的处理办法是前端使用token
但是无法防止模拟http请求
先模拟问题发生
写一个form.jsp
<html>
<head>
<title>$form$</title>
</head>
<form action="${pageContext.request.contextPath}/DoFormServlet" method="post">
用户名:<input type="text" name="userName">
<input type="submit" value="提交" id="submit">
</form>
<body>
</body>
</html>
写个servlet用于调用
@WebServlet("/DoFormServlet")
public class DoFormServlet extends HttpServlet {
@SneakyThrows
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
String username = req.getParameter("userName");
Thread.sleep(3000);
System.out.println("插入数据..");
resp.getWriter().println("success");
}
}
启动页面
输入123提交,Thread.sleep(3000);延迟了3秒,模拟网络延迟,页面不会立即进行跳转,这时就可以多次点击点击提交按钮,造成表单重复提交
后台打印
前端解决方法
提交后,按钮变灰,多一个标识判断,这种做法可以,但是有局限性,不能防止刷新重新加载的重复提交
<html>
<head>
<title>form</title>
</head>
<script type="text/javascript">
let submitFlag = false // 没有点击为false
function isNoSubmit() {
// 还没提交返回true
if (!submitFlag) {
submitFlag = true
return true
}
// 提交了返回false
return false
}
</script>
<form action="${pageContext.request.contextPath}/DoFormServlet"
method="post"
onsubmit="return isNoSubmit()">
用户名:<input type="text" name="userName"/>
<input type="submit" value="提交" id="submit"/>
</form>
<body>
</body>
</html>
使用token来解决
token身份令牌,证明有效期和身份
思路:
请求一个Sevlet生成token存放在session中,转发到form.jsp,此时jsp携带一个token并附着表单进行提交,到DoFormServlet,判断token是否有效,DoFormServlet判断步骤如下:
-
如果从session中获取到的token,和表单发来的一致,说明是第一次的发来请求,处理业务完毕后删除sessiom的token,表示这个token已失效。
-
如果seesion中没有这个token,说明token已经被用过了。
-
如果传来的token为空或者和session的token不一致,说明被恶意伪造了token
写ToFromServlet生成token并作转发
@WebServlet("/ToFromServlet")
public class ToFromServlet extends HttpServlet {
@SneakyThrows
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String token = UUID.randomUUID().toString();
System.out.println("生成Token:"+token);
req.getSession().setAttribute("sessionToken", token);
req.getRequestDispatcher("form.jsp").forward(req, resp);
}
}
修改form.jsp,添加一个hidden域
<html>
<head>
<title>form</title>
</head>
<script type="text/javascript">
let submitFlag = false // 没有点击为false
function isNoSubmit() {
// 还没提交返回true
if (!submitFlag) {
submitFlag = true
return true
}
// 提交了返回false
return false
}
</script>
<form action="${pageContext.request.contextPath}/DoFormServlet"
method="post"
onsubmit="return isNoSubmit()">
<input type="hidden" value="${sessionToken}" name="sessionToken">
用户名:<input type="text" name="userName"/>
<input type="submit" value="提交" id="submit"/>
</form>
<body>
</body>
</html>
最后在doFormServlet添加session判断
@WebServlet("/DoFormServlet")
public class DoFormServlet extends HttpServlet {
@SneakyThrows
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
if (!isFlag(req,resp)){
resp.getWriter().println("fail");
System.out.println("已经提交了...");
return;
}
req.setCharacterEncoding("utf-8");
String username = req.getParameter("userName");
Thread.sleep(3000);
System.out.println("插入数据..");
resp.getWriter().println("success");
}
public boolean isFlag(HttpServletRequest req, HttpServletResponse resp){
String sessionToken = req.getParameter("sessionToken");
String sessionToken1 = (String) req.getSession().getAttribute("sessionToken");
if(StringUtils.isNullOrEmpty(sessionToken)){
System.out.println("sessionToken为null");
return false;
}
if (StringUtils.isNullOrEmpty(sessionToken1)){
System.out.println("sessionToken1为null");
return false;
}
if(!sessionToken1.equals(sessionToken)){
System.out.println("伪造token");
return false;
}
req.getSession().removeAttribute("sessionToken");
return true;
}
}
访问/ToFromServlet即可
测试,后台打印:
接口如何防止模拟http请求
带上token,保证唯一性,难以伪造。但是生成token方式可以破解的,还是可以模拟请求,这时如何解决呢?
使用验证码,证明自己不是机器人
token+验证码完整解决防止模拟请求
使用Filter防止XSS攻击
什么是XSS攻击?
XSS也叫脚本注入
XXSS攻击常发生在:有个表单在页面中,当提交时,参数提交,让数据展示在页面时,突然弹窗或者页面发生了跳转
如我注入的内容是location.href,当你访问一个页面立马跳转到钓鱼网站了,用户登陆界面完全一样。(我全防去出去了啊)
模拟XSS攻击
我们写脚本进行注入
一点提交就弹窗
想想如果这个脚本是在留言区/评论区的话,别的用户点进来就被弹窗。
XSS页面跳转也写进来
<script>alert('攻击成功');window.location.href='http://www.baidu.com';</script>"
别人在一个页面访问好端端,然后突然跳转到了登陆界面,界面一模一样,这就是钓鱼网站攻击,也是XSS的一种
如何防范?
原理是XSS的标签被html解析了,我们转义标签即可。
继承HttpServletRequest重写getParameter方法
public class XssHttpServletRequest extends HttpServletRequestWrapper {
HttpServletRequest request;
public XssHttpServletRequest(HttpServletRequest request) {
super(request);
this.request = request;
}
@Override
public String getParameter(String name) {
String value = request.getParameter(name);
if (!StringUtils.isEmpty(value)){
value = StringEscapeUtils.escapeHtml4(value);
}
return value;
}
}
写Filter,将我们的XssHttpServletRequest传过去,这样getParameter会转义字符
@WebFilter(filterName = "XSSFilter", urlPatterns = { "/*" })
public class XSSFilter implements Filter {
public void init(FilterConfig filterConfig) throws ServletException {
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
XssHttpServletRequest xssHttpServletRequest = new XssHttpServletRequest(req);
chain.doFilter(xssHttpServletRequest, response);
}
public void destroy() {
}
}
再次测试,这样<>就被转义了,破坏了标签
SQL注入
没啥好讲的了,
有那么几种办法防范:
1、PreparedStatement
2、使用正则表达式过滤传入的参数
3、字符串过滤
4、检查是否包函非法字符
然后他啪的一下就站起来了啊,很快啊,然后上来就是一个端口扫描,一个密码暴力破解,一个大杀四方。我全都防出去,防出去了,啊。防出去了以后自然是传统以点到为止,我大意了啊,没有闪。
后面开个新专栏吧,闭关修炼专栏这都到25了都。
标签:web,false,闭关,req,token,提交,二十五,return,public 来源: https://blog.csdn.net/qq_19841133/article/details/113246913