【问题标题】:Who's Calling my HttpServletRequest?谁在调用我的 HttpServletRequest?
【发布时间】:2012-02-01 19:25:00
【问题描述】:

我有一个 jsp,其中包含一个 jquery 发布到我的 tomcat 服务器上的一个 servlet,它创建了一个 HttpServletRequest。我想确保只处理我的 jsp 对我的 servlet 的调用,并且忽略来自我的 jsp 以外的源的任何请求。 是否有保证的方法可以查看调用我的服务器的引用页面是什么?我已经读过使用request.getHeader("referer") 可以被欺骗所以我知道我不能依赖它。

【问题讨论】:

    标签: java jquery jsp servlets security


    【解决方案1】:

    只是一点语义。请求通常是从显示您的 JSP 的浏览器创建的。您无法阻止其他程序请求您的 JSP 并使用您提供给他们的任何信息再次请求。

    您可以阻止正在用户浏览器中查看的另一个网页执行对您网站的请求。这称为Cross-site request forgery。您可以缓解这种情况。

    因此,根据您要防止的情况,CSRF 解决方案可能对您有用。您可以从 Web 服务器中找到预制的解决方案。比如这里是Tomcat's

    【讨论】:

      【解决方案2】:

      生成一个唯一的字符串作为令牌,将其存储在会话中,并将其作为隐藏的输入值嵌入到 JSP 的 POST 形式中,最后检查 servlet 是否令牌有效。

      基本上:

      关于会话创建(例如在HttpSessionListener#sessionCreated()):

      Set<String> tokens = new HashSet<String>();
      event.getSession().setAttribute("tokens", tokens);
      

      关于 JSP 请求的预处理(例如,HttpServlet#doGet()):

      String token = UUID.randomUUID().toString();
      Set<String> tokens = (Set<String>) request.getSession().getAttribute("tokens");
      tokens.add(token);
      request.setAttribute("token", token);
      

      关于处理 JSP 本身:

      <input type="hidden" name="token" value="${token}" />
      

      关于表单提交的后处理(例如HttpServlet#doPost()):

      String token = request.getParameter("token");
      Set<String> tokens = (Set<String>) request.getSession().getAttribute("tokens");
      
      if (!tokens.remove(token)) {
          response.sendError(HttpServletResponse.SC_BAD_REQUEST);
          return;
      }
      
      // ...    
      

      我当然假设您的 jQuery.post() 函数是像在 $.post(form.action, form.serialize(), callback) 中那样以一种不显眼的方式编写的,因此它完全模拟了正常的同步请求(换句话说,您的表单在禁用 JS 的情况下工作得很好)。

      【讨论】:

      • 非常感谢您的回复。我必须承认我是 jquery 的新手,所以我不确定这种方法是否适用于我的问题。在我的jsp中,我有这样的东西 [code][/code]。因此,我不清楚如何按照您的描述传递令牌。谢谢。
      • 哦,您将 servlet 用作 Web 服务。这实际上不是您的问题中提到的“jQuery 帖子”。这只是一个 GET 请求。这究竟是什么时候被调用的?在页面加载期间只有一次?还是多次用户交互?
      • 很抱歉给您带来了困惑。它实际上是基于 javascript 计时器调用的(在循环中使用 setTimeout 方法)。每隔这么多秒,就会调用“$.getJSON...”来根据返回的 json 对象更新 jsp 上的状态。
      • 然后您可以将令牌作为 JS 变量进行维护,并将其作为请求参数发送(作为您拥有的“aMap”的另一个属性)。
      • 谢谢。有没有办法从“查看源代码”中隐藏 JS 变量?在jsp的java部分定义token并传给JS吧?
      【解决方案3】:

      您可以为您的 jsp 创建一个随机 cookie,然后将其附加到您的 POST 表单中,并且只接受具有正确 cookie 值的请求。

      【讨论】:

      • 这实际上比其他提到的解决方案更安全。点赞。
      • @Perception:请注意,HTTP 会话本身已经由“随机 cookie”支持。
      • @BalusC - 这通常是正确的(有些使用 URL 重写)。我的主要观点是,未经授权的客户端比嵌入在 HTML 页面中的令牌更难欺骗 cookie。
      • @Perception:如果有人知道如何欺骗会话 cookie,那么也很容易欺骗另一个 cookie。
      • @BalusC - 是的,但您只需执行“查看源代码”即可查看所有隐藏的输入字段。
      【解决方案4】:

      您可以向您的 JSP 呈现一个安全令牌,并将其包含在您对 Servlet 的 Ajax 调用中,您可以在其中验证它。这也不能保证 Ajax 调用是使用浏览器和您的 Javascript 进行的,但它至少需要有人在调用之前从 JSP 获取安全令牌。

      建议使用类似的概念来缓解CSRF

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-08-18
        • 2017-02-06
        • 2018-11-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-08-31
        相关资源
        最近更新 更多