如何在特定会话中为特定浏览器跟踪网站

3

1. 如何在同一浏览器的下一个标签页中找到您的网站正在受到攻击? 2. 如何防止网站在第二个标签页中被打开?


1
我不相信有一种方法可以做到这一点。 浏览器出于明显的安全原因,不允许JS访问其他打开选项卡的信息。 - Carcigenicate
可能是不可能的,除非您以某种方式访问服务器的原始客户端连接,但即使如此,HTTP连接通常是无状态的,并且连接会立即关闭。 - xander
那银行网站如何禁止在下一个标签中复制URL呢? - Sunandan Bose
@Carcigenicate 有任何服务器端的解决方案吗? - Vikram Singh
@SunandanBose 银行网站通常只使用HTTPS,因此大多数情况下您甚至不能使用浏览器的“导航按钮”返回或刷新页面,否则会使会话失效。 - xander
显示剩余3条评论
1个回答

2
如果浏览器首次访问您的网站,则会在服务器端创建一个会话,从而将会话cookie发送到浏览器。您可以嵌入一个隐藏表单值在HTML中。此后的每个调用都必须包含此隐藏值。最好始终使用POST,以便隐藏值不包含在URL中。
如果用户打开第二个选项卡并想要打开您网站的URL,则不会包括隐藏参数,但会包含来自第一个选项卡的会话cookie。
因此,在服务器端,您知道已经存在一个会话,但是缺少隐藏值。因此,您可以发送完全不同的响应。
更新:这里是一个小例子。
在Web内容文件夹中有一个名为“protected”的子文件夹。所有包含的JSP文件只能在一个选项卡中打开。这里只有“MyJsp.jsp”。
在根目录中有两个JSP:当有人尝试在第二个选项卡中打开受保护的JSP时显示的“error.jsp”,以及重定向到“protected/MyJsp.jsp”的“index.jsp”。
还有一个servlet过滤器映射到“protected”文件夹。在执行此文件夹中的JSP之前,将调用此过滤器。
“protected/MyJsp.jsp”:
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
  <p>Hello,
    <c:choose>
    <c:when test="${not empty param.name}">
      <c:out value="${param.name}" />.
    </c:when>
    <c:otherwise>
      stranger.
    </c:otherwise>
    </c:choose>
  </p>
  <form method="post">
    <label>Please enter your name</label>
    <input id="name" name="name" type="text"/>
    <input id="marker" name="marker" type="hidden" 
        value="<c:out value="${sessionScope.marker}"/>"/>
    <button type="submit">OK</button>
  </form>
</body>
</html>

这个JSP正在请求一个名称。表单提交通过POST调用相同的JSP。隐藏字段填充了来自会话的值。

index.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!--include the library-->
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<c:redirect url="protected/MyJsp.jsp"/>

Servlet过滤器:
@WebFilter("/protected/*")
public class OneTabFilter implements Filter {

  private static final String MARKER_NAME = "marker";
  private static final String MARKER_VALUE = "4711*0815";

  public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
    final HttpServletRequest req = (HttpServletRequest) request; 
    final HttpServletResponse rsp = (HttpServletResponse) response;
    HttpSession session = req.getSession(false);
    if(session == null) {
      session = req.getSession(true);
      // Put the marker value into session so it is usable in JSP files.
      session.setAttribute(MARKER_NAME, MARKER_VALUE);
      // pass the request along the filter chain
      chain.doFilter(request, response);
    } else {
      if(MARKER_VALUE.equals(req.getParameter(MARKER_NAME))) {
        // pass the request along the filter chain
        chain.doFilter(request, response);
      } else {
        // Redirect to the error page.
        // The error page itself is not affected by this filter.
        rsp.sendRedirect(req.getServletContext().getContextPath() + "/error.jsp");
      }
    }
  }

  // ...
}

自己动手试试吧!


但是,如果我们从服务器开始处理每个页面,那么这不会使我们的网站变慢吗?因为它必须进行两次服务器调用,一次是确保其有效性,另一次是获取详细信息。 - Sunandan Bose
它不会使请求的数量增加。为了处理每个调用的额外隐藏参数,会有一些最小的性能损失。对于每个请求,服务器都必须检查是否存在该参数。就是这样。 - vanje
也许可以通过一个Servlet过滤器来实现这个检查。 - vanje
@Sunandan Bose:我在我的回答中加入了一个例子。 - vanje

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接