CSRF 代币生成

发布于 2024-08-12 18:53:42 字数 756 浏览 5 评论 0原文

这是一个关于生成CSRF代币的问题。

通常我想根据与用户会话相关的唯一数据生成一个令牌,并使用密钥进行散列和加盐。

我的问题是关于在没有可用的唯一用户数据时生成令牌的问题。没有可用的会话,cookie 不是一个选项,IP 地址和类似性质的东西不可靠。

有什么原因导致我无法将要哈希的字符串也包含在请求中吗? 生成令牌并嵌入它的伪代码示例:

var $stringToHash = random()
var $csrfToken = hash($stringToHash + $mySecretKey)
<a href="http://foo.com?csrfToken={$csrfToken}&key={$stringToHash}">click me</a>

CSRF 令牌的服务器端验证示例

var $stringToHash = request.get('key')
var $isValidToken = hash($stringToHash + $mySecrtKey) == request.get('csrfToken')

每个请求中哈希中使用的字符串都不同。只要它包含在每个请求中,CSRF 令牌验证就可以继续进行。由于它对于每个请求都是新的并且仅嵌入在页面中,因此外部对令牌的访问将不可用。然后,令牌的安全性就落到了只有我自己知道的 $mySecretKey 上。

这是一种天真的做法吗?我是否错过了这不起作用的某些原因?

谢谢

This is a question about generating CSRF tokens.

Usually I'd like to generate a token based off of a unique piece of data associated with the user's session, and hashed and salted with a secret key.

My question is in regards to generating tokens when there is NO unique user data to use. No sessions are available, cookies are not an option, IP address and things of that nature are not reliable.

Is there any reason why I cannot include the string to hash as part of the request as well?
Example pseudocode to generate the token and embed it:

var $stringToHash = random()
var $csrfToken = hash($stringToHash + $mySecretKey)
<a href="http://foo.com?csrfToken={$csrfToken}&key={$stringToHash}">click me</a>

Example server-side validation of the CSRF token

var $stringToHash = request.get('key')
var $isValidToken = hash($stringToHash + $mySecrtKey) == request.get('csrfToken')

The string being used in the hash would be different on each request. As long as it was included in each request, the CSRF token validation could proceed. Since it is new on each request and only embedded in the page, outside access to the token would not be available. Security of the token then falls to the $mySecretKey being known only to me.

Is this a naive approach? Am I missing some reason why this cannot work?

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

猫卆 2024-08-19 18:53:42

是否有任何原因导致我无法将要哈希的字符串也包含在请求中?

CSRF 令牌有两个部分。嵌入表单中的令牌,以及其他地方的相应令牌,无论是在 cookie 中,还是存储在会话中或其他地方。这种对其他地方的使用会阻止页面自包含。

如果您在请求中包含要散列的字符串,则该请求是自包含的,因此攻击者只需复制表单即可,因为他们拥有令牌的两个部分,因此没有保护。

即使将其放在表单 URL 中也意味着它是自包含的,攻击者只需复制表单和提交 URL。

Is there any reason why I cannot include the string to hash as part of the request as well?

CSRF tokens have two parts. The token embedded in the form, and a corresponding token somewhere else, be it in a cookie, stored in a session or elsewhere. This use of elsewhere stops a page being self contained.

If you include the string to hash in the request, then the request is self contained, so copying the form is all an attacker needs to do, as they have both parts of the token, and thus there is no protection.

Even putting it in the form URL means that it's self contained, the attacker simply copies the form and the submission URL.

十二 2024-08-19 18:53:42

我认为最好的想法是基于 HMAC 进行哈希,即按照以下顺序使用某个密码加密哈希:用户名+用户 ID+时间戳。每个请求的哈希值必须不同,如果您不想在攻击中简单重放哈希值,则时间戳必须不同。

I think the best idea to make hash based on HMAC, i.e. make hash encrypted by some password this sequence: username+user_id+timestamp. Each request the hash must be different, timestamp must be if you don't want to get simple replay the hash in attack.

地狱即天堂 2024-08-19 18:53:42

CSRF 令牌旨在防止(无意的)数据修改,通常与 POST 请求一起应用。

因此,您必须为每个更改数据的请求(GET 或 POST 请求)包含 CSRF 令牌。

我的问题是关于
当没有时生成令牌
要使用的唯一用户数据。没有会话
可用,cookie 不是
选项、IP 地址和相关信息
自然是不可靠的。

然后只需为每个访问者创建一个唯一的用户 ID。
将该 ID 包含在 Cookie 或 URL 中(如果禁用了 Cookie)。

编辑:

考虑以下事件:

您已登录 Facebook 帐户,然后进入某个任意网站。

在该网站中,有一个您提交的表单,它会告诉您的浏览器向您的 Facebook 帐户发送 POST 请求。

该 POST 请求可能会更改您的密码或添加评论等,因为 Facebook 应用程序将您识别为注册用户。已登录的用户。 (除非有另一种阻止机制,例如 CAPTCHA )

CSRF token meant to prevent (unintentional) data modifications, which are usually applied with POST requests.

Thus, you must include CSRF token for each request that changes data (either GET or POST request).

My question is in regards to
generating tokens when there is NO
unique user data to use. No sessions
are available, cookies are not an
option, IP address and things of that
nature are not reliable.

Then simply create a unique user id for each visitor.
Include that id in a cookie or in the URLs (if cookies are disabled).

Edit:

Consider the following event:

You have logged-in to your facebook account and then entered to some arbitrary website.

In that website there's a form that you submit, which tells your browser to send a POST request to your facebook account.

That POST request may change your password or add a comment etc, because that the facebook application recognized you as a registered & logged-in user. (unless there's another blocking mechanism, like CAPTCHA )

亣腦蒛氧 2024-08-19 18:53:42

您只需要在 URL/表单和 cookie 中使用相同的“令牌”即可。这意味着您可以让您的页面通过 JavaScript 将令牌 cookie 设置为它想要的任何值(最好是一些随机值),然后在发送到您的服务器的所有请求中传递完全相同的值(作为 URI?param 或 form-)场地)。无需让您的服务器生成 cookie。

只要我们相信浏览器不允许来自某个域的页面编辑/读取其他域的 cookie,这就是安全的,并且这在今天被认为是非常安全的。

让您的服务器生成令牌将假定该令牌可以安全地传输到您的浏览器,而不会被任何 CSRF 尝试获取(为什么要冒风险?)。虽然您可以将更多逻辑放入服务器生成的令牌中,但为了防止 CSRF,没有必要。

(如果我错了请告诉我)

You simply just need the same "token" in the URL/form and in the cookie. This means that you could have your page setting the token cookie to whatever it wants to (preferably some random value) by JavaScript and then just pass the very same value in all requests that goes to your server (as a URI ?param or form-field). No need to have your server generating the cookie.

This is safe as long as we trust that the browser doesn't allow pages from a domain to edit/read cookies for other domains, and this is assumed to be quite secure today.

Having your server generating the token will assume that this token can be safely transmitted to your browser without being picked up by any CSRF attempts (why take the risk?). Though you could put more logic into a server generated token, but to prevent CSRF there is no need.

(If I'm wrong here please let me know)

彡翼 2024-08-19 18:53:42

CSRF 令牌有多种实现。关键是这个csrf token是在客户端生成的还是服务器端生成的。因为这两种场景的实现以及令牌的熵也发生了巨大的变化。

对于服务器端,SecureRandom 是首选方式,但在您的情况下,您希望在识别任何用户之前生成 CSRF 令牌,window.crypto 提供了此功能,您可以在其中生成一个无法猜测的字符串以用于 CSRF 令牌。

There are multiple implementation of CSRF token. The key thing is whether this csrf token is generated on the client side or server side. Because the implementation changes drastically for these two scenarios and the entropy of the token as well.

For server side, SecureRandom is the preferred way but in your case you want to generate the CSRF token before any user is identified, window.crypto provides this functionality where you can generate a unguessable enough string to be used for CSRF token.

妞丶爷亲个 2024-08-19 18:53:42

借助 CSRF 令牌,我们可以确保传入请求经过身份验证(知道用户而不是黑客)

请注意,我需要以下方法,但谷歌即使在 stackoverflow 上也无法帮助我,我没有得到下面提到的代码,但在收集后stackoverflow 的答案让我很开心。因此,这对于进一步搜索/特别是对于初学者很有用

我在下面描述了 Spring MVC 和 Spring Interceptor

注意 - 我已经使用谷歌缓存在缓存中存储盐以进行重新验证

下面的依赖项需要添加 下方的pom.xml

    <!-- https://mvnrepository.com/artifact/com.google.guava/guava -->
    <dependency>
        <groupId>com.google.guava</groupId>
        <artifactId>guava</artifactId>
        <version>28.0-jre</version>
    </dependency>

HandlerInterceptorAdapter 实现


    package com.august.security;

    import java.security.SecureRandom;
    import java.util.Enumeration;
    import java.util.LinkedList;
    import java.util.List;
    import java.util.concurrent.TimeUnit;

    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.servlet.http.HttpSession;

    import org.apache.commons.lang3.RandomStringUtils;
    import org.springframework.web.servlet.ModelAndView;
    import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

    import com.google.common.cache.Cache;
    import com.google.common.cache.CacheBuilder;

    public class CsrfSecurity extends HandlerInterceptorAdapter {
        List<String> urlList= new LinkedList<>();
        private static final String CSRF_TAG = "CSRF-CHECK";

        @SuppressWarnings("unchecked")
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handleer)
                throws Exception {
            System.out.println("Inside Pre Handler");

            String reqUrl = request.getRequestURI().toString();
            System.out.println("Request URL : " + reqUrl);
            String ipAddress = request.getHeader("X-FORWARDED-FOR");
            if (ipAddress == null) {
                ipAddress = request.getRemoteAddr();
            }
            //local host url http://localhost:8080/august/
            if (request.getRequestURI().contains("/august/")) {
                System.out.println("pre handler return true");
                //it will return and next executed postHandelr method
                //because of on above url my webApplication page working
                return true;
            }
            if (ignoreUrl().contains(request.getRequestURI())) {
                System.out.println("inside ignore uri");
                return true;
            } else {
                System.out.println("CSRF Security intercepter preHandle method started.......");
                String salt = request.getParameter("csrfPreventionSalt");
                HttpSession sessionAttribute = request.getSession();
                Cache<String, Boolean> csrfPreventionSalt = (Cache<String, Boolean>) sessionAttribute
                        .getAttribute("csrfPreventionSalt");
                if (csrfPreventionSalt == null) {
                    System.out.println("Salt not matched session expired..");
                    parameterValuesPrint(request, "saltCacheNotFound");
                    response.sendRedirect("error");
                    return false;
                } else if (salt == null) {
                    parameterValuesPrint(request, "noSaltValue");
                    System.out.println("Potential CSRF detected !! inform ASAP");
                    response.sendRedirect("error");
                    return false;
                } else if (csrfPreventionSalt.getIfPresent(salt) == null) {
                    System.out.println("saltValueMisMatch");
                    System.out.println("Potential CSRF detected !! inform ASAP");
                    response.sendRedirect("error");
                } else {
                    request.setAttribute("csrfPreventionSalt", csrfPreventionSalt);
                }
                return true;
            }

        }

        @SuppressWarnings("unchecked")
        @Override
        public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
                ModelAndView modelAndView) {
            System.out.println("Inside post Handler");
            System.out.println("CSRF Security key generator method started");
            try {
                //localhost url http://localhost:8080/august/
                //api is my controller path so no need to genrate token for api
                if (request.getRequestURI().contains("/august/api/")) {
                    System.out.println("No need to genrate salt for api");
                } else {
                    HttpSession sessionAttribute = request.getSession();
                    Cache<String, Boolean> csrfPreventionSaltCache = (Cache<String, Boolean>) sessionAttribute
                            .getAttribute("csrfPreventionSalt");
                    System.out.println("csrfPreventionSaltCache ::: " + csrfPreventionSaltCache);
                    if (csrfPreventionSaltCache == null) {
                        csrfPreventionSaltCache = CacheBuilder.newBuilder().maximumSize(5000)
                                .expireAfterWrite(20, TimeUnit.MINUTES).build();
                        request.getSession().setAttribute("csrfPreventionSaltCache", csrfPreventionSaltCache);
                    }

                    String salt = RandomStringUtils.random(20, 0, 0, true, true, null, new SecureRandom());
                    System.out.println("csrfPreventionSalt genrated ::: " + salt);
                    csrfPreventionSaltCache.put(salt, Boolean.TRUE);
                    if (modelAndView != null) {
                        System.out.println("Model and view not null and salt is added in modelAndView");
                        modelAndView.addObject("csrfPreventionSalt", salt);
                    }
                }
            } catch (Exception ex) {
                System.out.println(ex.getMessage());
                ex.printStackTrace();
            }
        }

        @Override
        public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
                throws Exception {
            System.out.println("afterCompletion : ");
            if (ex != null) {
                System.out.println("exception : " + ex.getMessage());
                ex.printStackTrace();
            }
        }

        private List<String> ignoreUrl() {
            if(urlList == null) {
                urlList.add("/august/error");
                //add here your ignored url.
            }
            return urlList;
        }

        private void parameterValuesPrint(HttpServletRequest request, String err) {
            StringBuilder reqParamAndValue = new StringBuilder();
            Enumeration<?> params = request.getParameterNames();
            while (params.hasMoreElements()) {
                Object objOri = params.nextElement();
                String param = (String) objOri;
                String value = request.getParameter(param);
                reqParamAndValue = reqParamAndValue.append(param + "=" + value + ",");
            }
            System.out.println(CSRF_TAG + " " + err + "RequestedURL : " + request.getRequestURL());
        }
    }

下面是使用 spring 上下文注册的拦截器


package com.august.configuration;

    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.ComponentScan;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.servlet.ViewResolver;
    import org.springframework.web.servlet.config.annotation.EnableWebMvc;
    import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
    import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
    import org.springframework.web.servlet.view.InternalResourceViewResolver;

    import com.august.security.CsrfSecurity;

    @Configuration
    @EnableWebMvc
    @ComponentScan(basePackages="com.august")
    public class SpringConfiguration extends WebMvcConfigurerAdapter  {

        @Bean
        public ViewResolver viewResolver() {
            InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
            //viewResolver.setViewClass(JstlView.class);
            viewResolver.setPrefix("/WEB-INF/views/");
            viewResolver.setSuffix(".jsp");
            return viewResolver;

        }

        @Bean
        public CsrfSecurity csrfSecurity() {
            return new CsrfSecurity();
        }
        @Override
        public void addInterceptors(InterceptorRegistry registry) {
            registry.addInterceptor(new CsrfSecurity());
        }
    }

下面是我的控制器


    package com.august.v1.appcontroller;

    import javax.servlet.http.HttpSession;

    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;


    @Controller
    public class HomeController {

        @Autowired 
        HttpSession httpSession;

        @RequestMapping("/")
        public String index(Model model) {
            httpSession.invalidate();
            System.out.println("Home page loaded");
            return "index";
        }
    }

下面是我的 index.jsp jsp 页面


    <%@ page language="java" contentType="text/html; charset=ISO-8859-1"
        pageEncoding="ISO-8859-1" isELIgnored="false"%>
         //don't forget to add isELIgnored="false" on old(version) jsp page because of i 
         //have wasted 1 hour for this
    <!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=ISO-8859-1">
    <title>ADS Home</title>
    </head>
    <body>
    <h1>${csrfPreventionSalt}</h1>
    <input type="hidden" name="csrfPreventionSalt" value=${csrfPreventionSalt}>
    </body>
    </html>

用于了解 CSRF - CSRF解释

With the help of CSRF token we can sure incoming request is authenticated (know user not hacker)

Please note i have required below approach but google can't help me even on stackoverflow i did't get mentioned code below but after collection of stackoverflow answer i have made my day. So it's useful for further searching/ specially for beginners

I have described below Spring MVC with Spring Interceptor

Note - I have used google cache to store salt in cache for re verification

below dependency need to add pom.xml

    <!-- https://mvnrepository.com/artifact/com.google.guava/guava -->
    <dependency>
        <groupId>com.google.guava</groupId>
        <artifactId>guava</artifactId>
        <version>28.0-jre</version>
    </dependency>

below HandlerInterceptorAdapter implemention


    package com.august.security;

    import java.security.SecureRandom;
    import java.util.Enumeration;
    import java.util.LinkedList;
    import java.util.List;
    import java.util.concurrent.TimeUnit;

    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.servlet.http.HttpSession;

    import org.apache.commons.lang3.RandomStringUtils;
    import org.springframework.web.servlet.ModelAndView;
    import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

    import com.google.common.cache.Cache;
    import com.google.common.cache.CacheBuilder;

    public class CsrfSecurity extends HandlerInterceptorAdapter {
        List<String> urlList= new LinkedList<>();
        private static final String CSRF_TAG = "CSRF-CHECK";

        @SuppressWarnings("unchecked")
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handleer)
                throws Exception {
            System.out.println("Inside Pre Handler");

            String reqUrl = request.getRequestURI().toString();
            System.out.println("Request URL : " + reqUrl);
            String ipAddress = request.getHeader("X-FORWARDED-FOR");
            if (ipAddress == null) {
                ipAddress = request.getRemoteAddr();
            }
            //local host url http://localhost:8080/august/
            if (request.getRequestURI().contains("/august/")) {
                System.out.println("pre handler return true");
                //it will return and next executed postHandelr method
                //because of on above url my webApplication page working
                return true;
            }
            if (ignoreUrl().contains(request.getRequestURI())) {
                System.out.println("inside ignore uri");
                return true;
            } else {
                System.out.println("CSRF Security intercepter preHandle method started.......");
                String salt = request.getParameter("csrfPreventionSalt");
                HttpSession sessionAttribute = request.getSession();
                Cache<String, Boolean> csrfPreventionSalt = (Cache<String, Boolean>) sessionAttribute
                        .getAttribute("csrfPreventionSalt");
                if (csrfPreventionSalt == null) {
                    System.out.println("Salt not matched session expired..");
                    parameterValuesPrint(request, "saltCacheNotFound");
                    response.sendRedirect("error");
                    return false;
                } else if (salt == null) {
                    parameterValuesPrint(request, "noSaltValue");
                    System.out.println("Potential CSRF detected !! inform ASAP");
                    response.sendRedirect("error");
                    return false;
                } else if (csrfPreventionSalt.getIfPresent(salt) == null) {
                    System.out.println("saltValueMisMatch");
                    System.out.println("Potential CSRF detected !! inform ASAP");
                    response.sendRedirect("error");
                } else {
                    request.setAttribute("csrfPreventionSalt", csrfPreventionSalt);
                }
                return true;
            }

        }

        @SuppressWarnings("unchecked")
        @Override
        public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
                ModelAndView modelAndView) {
            System.out.println("Inside post Handler");
            System.out.println("CSRF Security key generator method started");
            try {
                //localhost url http://localhost:8080/august/
                //api is my controller path so no need to genrate token for api
                if (request.getRequestURI().contains("/august/api/")) {
                    System.out.println("No need to genrate salt for api");
                } else {
                    HttpSession sessionAttribute = request.getSession();
                    Cache<String, Boolean> csrfPreventionSaltCache = (Cache<String, Boolean>) sessionAttribute
                            .getAttribute("csrfPreventionSalt");
                    System.out.println("csrfPreventionSaltCache ::: " + csrfPreventionSaltCache);
                    if (csrfPreventionSaltCache == null) {
                        csrfPreventionSaltCache = CacheBuilder.newBuilder().maximumSize(5000)
                                .expireAfterWrite(20, TimeUnit.MINUTES).build();
                        request.getSession().setAttribute("csrfPreventionSaltCache", csrfPreventionSaltCache);
                    }

                    String salt = RandomStringUtils.random(20, 0, 0, true, true, null, new SecureRandom());
                    System.out.println("csrfPreventionSalt genrated ::: " + salt);
                    csrfPreventionSaltCache.put(salt, Boolean.TRUE);
                    if (modelAndView != null) {
                        System.out.println("Model and view not null and salt is added in modelAndView");
                        modelAndView.addObject("csrfPreventionSalt", salt);
                    }
                }
            } catch (Exception ex) {
                System.out.println(ex.getMessage());
                ex.printStackTrace();
            }
        }

        @Override
        public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
                throws Exception {
            System.out.println("afterCompletion : ");
            if (ex != null) {
                System.out.println("exception : " + ex.getMessage());
                ex.printStackTrace();
            }
        }

        private List<String> ignoreUrl() {
            if(urlList == null) {
                urlList.add("/august/error");
                //add here your ignored url.
            }
            return urlList;
        }

        private void parameterValuesPrint(HttpServletRequest request, String err) {
            StringBuilder reqParamAndValue = new StringBuilder();
            Enumeration<?> params = request.getParameterNames();
            while (params.hasMoreElements()) {
                Object objOri = params.nextElement();
                String param = (String) objOri;
                String value = request.getParameter(param);
                reqParamAndValue = reqParamAndValue.append(param + "=" + value + ",");
            }
            System.out.println(CSRF_TAG + " " + err + "RequestedURL : " + request.getRequestURL());
        }
    }

Below is Interceptor registration with spring context


package com.august.configuration;

    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.ComponentScan;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.servlet.ViewResolver;
    import org.springframework.web.servlet.config.annotation.EnableWebMvc;
    import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
    import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
    import org.springframework.web.servlet.view.InternalResourceViewResolver;

    import com.august.security.CsrfSecurity;

    @Configuration
    @EnableWebMvc
    @ComponentScan(basePackages="com.august")
    public class SpringConfiguration extends WebMvcConfigurerAdapter  {

        @Bean
        public ViewResolver viewResolver() {
            InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
            //viewResolver.setViewClass(JstlView.class);
            viewResolver.setPrefix("/WEB-INF/views/");
            viewResolver.setSuffix(".jsp");
            return viewResolver;

        }

        @Bean
        public CsrfSecurity csrfSecurity() {
            return new CsrfSecurity();
        }
        @Override
        public void addInterceptors(InterceptorRegistry registry) {
            registry.addInterceptor(new CsrfSecurity());
        }
    }

below is my controller


    package com.august.v1.appcontroller;

    import javax.servlet.http.HttpSession;

    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;


    @Controller
    public class HomeController {

        @Autowired 
        HttpSession httpSession;

        @RequestMapping("/")
        public String index(Model model) {
            httpSession.invalidate();
            System.out.println("Home page loaded");
            return "index";
        }
    }

below is my index.jsp jsp page


    <%@ page language="java" contentType="text/html; charset=ISO-8859-1"
        pageEncoding="ISO-8859-1" isELIgnored="false"%>
         //don't forget to add isELIgnored="false" on old(version) jsp page because of i 
         //have wasted 1 hour for this
    <!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=ISO-8859-1">
    <title>ADS Home</title>
    </head>
    <body>
    <h1>${csrfPreventionSalt}</h1>
    <input type="hidden" name="csrfPreventionSalt" value=${csrfPreventionSalt}>
    </body>
    </html>

For Understanding about CSRF - CSRF explanation

不交电费瞎发啥光 2024-08-19 18:53:42

我想说你的方法是有效的,因为CSRF攻击是攻击者利用受害者的浏览器伪造登录状态,为什么他们可以这样做?因为在大多数服务器端,会话检查是基于cookie中的SessionID,而cookie是一段数据,会自动附加到发送到服务器的HTTP请求中。

因此,防御CSRF有两个关键因素:

  1. 生成挑战令牌,并要求客户端以非cookie方式将其传递给服务器,无论是URL参数还是POST形式都可以。
  2. 确保令牌安全,就像您对 SessionID 所做的那样,例如使用 SSL。

我建议阅读 CSRF 预防备忘单

I wanna say your approach works, because CSRF attack is the attacker utilizing victim's browser to forge a logged-in status, why can they do so? because on most server side the session check is based on a SessionID in cookie, and cookie is a piece of data will be automatically attached to a HTTP request sent to server.

Therefore, there are two key factors for defending CSRF

  1. Generate a challenge token, and require client to pass it to server in a non-cookie way, either URL param or POST form is ok.
  2. Keep the token safe as what you did to the SessionID, for instance, using SSL.

I recommend reading CSRF Prevention Cheat Sheet

幻想少年梦 2024-08-19 18:53:42

CSRF 利用用户的会话,因此,如果您没有会话,就没有 CSRF。

CSRF utilizes the user's session, so, if you don't have one, there is no CSRF.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文