> ngx.time isn't a random number. Yes, I'm going to set up the random numbers using math.random()
> Which request header? A custom request header with a name similar to X-CSRF-Token, or as specified by the user's configuration Zexuan Luo <[email protected]> 于2021年12月1日周三 下午2:01写道: > LGTM, only a few questions: > > > Random is a random number like ngx.time(). > > ngx.time isn't a random number. > > > core.response.set_header("Set-Cookie", > {"csrf_token="..csrf_token..";path=/"}) > > We need to use add_header to prevent overriding existing Cookie. And > maybe we use a more specialized field name, like apisix_csrf_token? > > > - Whether the request header contains a CSRF token; (This relies on the > user reading the token from the cookie and carrying it to the request > header, as we can explain in the plugin's usage documentation) > > Which request header? > > Baoyuan <[email protected]> 于2021年11月30日周二 下午9:22写道: > > > > Based on the previous discussion, I am designing a plugin for APISIX to > > protect the API from CSRF attacks. The following are the specific > > implementation details and some sample codes. > > > > 1. *Configuration* > > > > > > - key: User-set secret key, used to generate csrf token > > - expires: token expiration time > > > > 2. *Details* > > > > *2.1 generate token* > > > > Generating a token requires random, expires, and key. > > > > Expires and key need to be obtained from the plugin's configuration. > > > > Random is a random number like ngx.time(). > > > > First, random, expires, and the key is subjected to sha256 operations to > > obtain a signature, then the token is obtained by performing base64 > > operations on the signature and random and expires. > > ``` > > local sign = { > > random = random, > > expires = expires, > > key = key, > > } > > > > sha256:update(core.json.encode(sign)) > > > > local digest = sha256:final() > > local token = { > > random = random, > > expires = expires, > > digest = digest, > > > > } > > > > local cookie = ngx_encode_base64(core.json.encode(token)) > > > > ``` > > > > *2.2 Send to the client* > > > > In the header_filter, add a Set-Cookie to the response header if it is a > > GET request, with the token generated above. > > > > ``` > > > > core.response.set_header("Set-Cookie", > > {"csrf_token="..csrf_token..";path=/"}) > > > > ``` > > > > *2.3 Checking CSRF token* > > > > Check the following in the request with the plugin enabled: > > > > > > - Whether or not it carries a cookie containing a CSRF token; > > - Whether the request header contains a CSRF token; (This relies on > the > > user reading the token from the cookie and carrying it to the request > > header, as we can explain in the plugin's usage documentation) > > - Check that the contents of the two tokens are the same; > > - Deconstruct the token base64 and check for expiration by expires; > > - Recalculate the signature using the random and expires obtained by > > untangling the token, plus the key obtained from the configuration, > and > > compare the two signatures for consistency; > > > > If all checks pass, the request is passed. Otherwise, 401 is returned to > > the client to intercept the request. > > > > This is basic security based on the inability to generate a token that > > matches the signature without the user's secret key. > > > > About this design and process, any thoughts or suggestions? > > > > Zexuan Luo <[email protected]> 于2021年11月11日周四 下午2:31写道: > > > > > I suggest you read through the definition of Double > > > Submit Cookie: > > > > https://github.com/OWASP/CheatSheetSeries/blob/5a1044e38778b42a19c6adbb4dfef7a0fb071099/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.md#double-submit-cookie > > > , > > > especially the drawback part. > > > > > > And we need to share more details about how does the plugin generate > > > the random token and how does the client interact with the server. To > > > avoid vulnerability in this plugin, we need to review it closer. > > > > > > Baoyuan <[email protected]> 于2021年11月11日周四 上午11:36写道: > > > > > > > > Thank you very much, Zexuan Luo. I thought about it like this > > > > > > > > > how to let the client know & set the token? > > > > > > > > I think I can use Set-Cookie to pass it to the client, the client > reads > > > the > > > > content of the token from the cookie and sets it in the request > header. > > > > I found that in the server rendering web page structure, it is > usually > > > > placed in the web page DOM so that the client can be easily carried, > But > > > > for the restful API structure, I think this method can be done. > > > > > > > > > what token does the client set? It can't just echo back the > encrypted > > > > csrf token > > > > > > > > At present, I really think about it this way, which is to return the > > > > encrypted csrf token, I don't understand the problem too much. > > > > > > > > > > > > > > > > Zexuan Luo <[email protected]> 于2021年11月10日周三 上午10:18写道: > > > > > > > > > I have read through the definition of Double > > > > > Submit Cookie: > > > > > > > > > https://github.com/OWASP/CheatSheetSeries/blob/5a1044e38778b42a19c6adbb4dfef7a0fb071099/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.md#double-submit-cookie > > > > > > > > > > > the CSRF plugin sets a cookie to the client in each request, > > > > > which contains the encrypted csrf token, and the client sets it on > the > > > > > request header in subsequent requests > > > > > > > > > > The OWASP guide has listed some drawbacks of csrf token without > > > encryption. > > > > > The proposal mentions that the client will set the encrypted csrf > > > > > token in subsequent requests, then there will be two questions: > > > > > 1. how to let the client know & set the token? > > > > > 2. what token does the client set? It can't just echo back the > > > > > encrypted csrf token > > > > > > > > > > Baoyuan <[email protected]> 于2021年11月9日周二 下午9:36写道: > > > > > > > > > > > > Hi Community, I have an idea to design a CSRF plugin for APISIX, > the > > > > > > purpose is to avoid the danger of routing attacks from CSRF. > > > > > > > > > > > > Taking into account the stateless nature of APISIX, I plan to use > > > Double > > > > > > Submit Cookie to verify CSRF attacks. > > > > > > > > > > > > Simply put, the CSRF plugin sets a cookie to the client in each > > > request, > > > > > > which contains the encrypted csrf token, and the client sets it > on > > > the > > > > > > request header in subsequent requests. CSRF plugin compares and > > > verifies > > > > > > the request header with the cookie to prevent CSRF attacks. > > > > > > > > > > > > The CSRF plugin has two configuration items: key and expires. > The key > > > > > > requires the user to provide a secret key, and the plugin will > > > generate > > > > > an > > > > > > encrypted cookie based on HMAC the token with this secret key. > The > > > > > expires > > > > > > refers to the cookie expiration time, this is an option, if the > user > > > does > > > > > > not provide, the plugin will provide an appropriate default > value. > > > > > > > > > > > > The plugin works at the route level. Users can turn on the > plugin on > > > the > > > > > > desired route to avoid CSRF attacks on the route as much as > possible. > > > > > > > > > > > > Any ideas or suggestions for these? > > > > > > > > > > > > > > > > > > Best Regards! > > > > > > > > > > > > Yuan Bao<[email protected]> > > > > > > > > >
