CSRF対策
CSRF対策で重要なのはユーザーが意図しない動作をブロックすることだと考えました。一般的なCSRF対策としてはCSRFトークンを利用したものがありますが、実装がうまくいきませんでした。色々試行錯誤してる中で、そもそもバックエンドとフロントエンドが独立したSPAでこれが適しているのかどうかという疑問も同時に持ちました。同じような問題の解決方法がMPAに限定されたものばかりだったためです。
https://echo.labstack.com/docs/middleware/csrf
そこで調べているとバックエンドとフロントエンドが独立したSPAでは上の実装が困難であることを見つけ、下記ページで紹介されていた「固有のヘッダの有無を検証する」を試しました。
https://kimuson.dev/blog/フロントエンド/csrf_spa/
実装
「固有のヘッダの有無を検証する」middlewareの実装。
middlewareの実装は試行錯誤していた時に見ていたechoのcsrf.go
を参考にしました。
https://github.com/labstack/echo/blob/master/middleware/csrf.go
func tokenCheck(next echo.HandlerFunc) echo.HandlerFunc {
return func(c echo.Context) error {
var tokenErr error
if slices.Contains(
[]string{http.MethodGet, http.MethodHead, http.MethodOptions, http.MethodTrace},
c.Request().Method) {
return next(c)
}
csrf_token := getCSRFTokenFromHeader(c)
if reflect.ValueOf(csrf_token).IsValid() != true {
return tokenErr
}
return next(c)
}
}
func getCSRFTokenFromHeader(c echo.Context) string {
token := c.Request().Header.Get(<TOKEN>)
return token
}
func main() {
e.Use(tokenCheck)
}
これで固有ヘッダ「TOKEN」が含まれているリクエストは通し、それ以外のものはエラーを出すようなミドルウェアの実装ができました。
有効性
今回初めてCSRF攻撃についてちゃんと調べたので、正直正しい理解かは分かりませんが、自分なりに今回の対策の有効性を考えました。
「CSRF対策で重要なのはユーザーが意図しない動作をブロックすること」は今回の対策で出来ていると思います。固有ヘッダを付随しなければ、リクエストを弾けるからです。
そしてリンク先を読む感じでは、ヘッダが設定された攻撃の場合には、攻撃を「CORS設定」によって防げると考えています。