ClearExtraCsrfCookies limits the amount of existing CSRF cookies by deleting an excess of cookies controlled through the option CSRFPerRequestLimit
(opts *options.Cookie, rw http.ResponseWriter, req *http.Request)
| 170 | // ClearExtraCsrfCookies limits the amount of existing CSRF cookies by deleting |
| 171 | // an excess of cookies controlled through the option CSRFPerRequestLimit |
| 172 | func ClearExtraCsrfCookies(opts *options.Cookie, rw http.ResponseWriter, req *http.Request) { |
| 173 | if !opts.CSRFPerRequest || opts.CSRFPerRequestLimit <= 0 { |
| 174 | return |
| 175 | } |
| 176 | |
| 177 | cookies := req.Cookies() |
| 178 | existingCsrfCookies := []*http.Cookie{} |
| 179 | startsWith := fmt.Sprintf("%v_", opts.Name) |
| 180 | |
| 181 | // determine how many csrf cookies we have |
| 182 | for _, cookie := range cookies { |
| 183 | if strings.HasPrefix(cookie.Name, startsWith) && strings.HasSuffix(cookie.Name, "_csrf") { |
| 184 | existingCsrfCookies = append(existingCsrfCookies, cookie) |
| 185 | } |
| 186 | } |
| 187 | |
| 188 | // short circuit return |
| 189 | if len(existingCsrfCookies) <= opts.CSRFPerRequestLimit { |
| 190 | return |
| 191 | } |
| 192 | |
| 193 | decodedCookies := []*csrf{} |
| 194 | for _, cookie := range existingCsrfCookies { |
| 195 | decodedCookie, err := decodeCSRFCookie(cookie, opts) |
| 196 | if err != nil { |
| 197 | continue |
| 198 | } |
| 199 | decodedCookies = append(decodedCookies, decodedCookie) |
| 200 | } |
| 201 | |
| 202 | // delete the X oldest cookies |
| 203 | slices.SortStableFunc(decodedCookies, func(a, b *csrf) int { |
| 204 | return a.clock().Compare(b.clock()) |
| 205 | }) |
| 206 | |
| 207 | for i := 0; i < len(decodedCookies)-opts.CSRFPerRequestLimit; i++ { |
| 208 | decodedCookies[i].ClearCookie(rw, req) |
| 209 | } |
| 210 | } |
| 211 | |
| 212 | // ClearCookie removes the CSRF cookie |
| 213 | func (c *csrf) ClearCookie(rw http.ResponseWriter, req *http.Request) { |
no test coverage detected