Live data from Hacker News

A modern approach to preventing CSRF in Go

alexedwards.net

11–20 of 104 posts

Re: A modern approach to preventing CSRF in Go

#12
post #6

Are CSRF attacks that common nowadays though? Even if your app is used by the 5% of browsers that don’t set the Origin header the chances of that being exploited are even more miniscule. Besides, most webdevs reach for token-based auth libraries before even knowing how to set a cookie header.

Also cant you just spoof the origin header?

Re: A modern approach to preventing CSRF in Go

#13
post #12
post #6

Are CSRF attacks that common nowadays though? Even if your app is used by the 5% of browsers that don’t set the Origin header the chances of that being exploited are even more miniscule. Besides, most webdevs reach for token-based auth libraries before even knowing how to set a cookie header.

Also cant you just spoof the origin header?

You can if you want to deliberately CORF yourself for some reason - it's there to protect you, but spoofing it doesn't give you any special access you wouldn't otherwise have.

The point is that arbitrary user's browsers out in the world won't spoof the Origin header, which is protecting them from CORF attacks.

Re: A modern approach to preventing CSRF in Go

#14

I would never rely on headers such as "Sec-Fetch-Site"; having security rely on client generated (correct) responses is just poor security modelling (don't trust the client). I'll stick to time bounded HMAC cookies, then you're not relying on client properly implementing any headers and it will work with any browser that supports cookies. And having TLS v1.3 should be a requirement; no HTTPS, no session, no auth, no…

I don't understand why your post is flagged. You are 100% right. The point of CSRF protection is that -you can't trust the client-. This new header can just be set in curl, If I understand correctly. Unlimited form submissions here I come!

Re: A modern approach to preventing CSRF in Go

#15
On a side note Alex books are a breath of fresh air for someone who is learning. They are always updated to the latest version of Go and if there is something new the old code base is updated and the new concepts introduced while you are being notified and send the new version of the book.

I never seen that before, all the other learning sources that I have are just abandoned, often there will be something that brakes and you have to spend good amount of time to figure out how to fix it, which can just discourage you to go on.

Kudos to Alex that is how it should be done.

Re: A modern approach to preventing CSRF in Go

#17

I would never rely on headers such as "Sec-Fetch-Site"; having security rely on client generated (correct) responses is just poor security modelling (don't trust the client). I'll stick to time bounded HMAC cookies, then you're not relying on client properly implementing any headers and it will work with any browser that supports cookies. And having TLS v1.3 should be a requirement; no HTTPS, no session, no auth, no…

I don't understand why your post is flagged. You are 100% right. The point of CSRF protection is that -you can't trust the client-. This new header can just be set in curl, If I understand correctly. Unlimited form submissions here I come!

CSRF protects the user by not allowing random pages on the web using resources from a target website, without the user being aware of this. It only makes sense when serving people using browsers. It is not a defense against curl or skiddies.

Re: A modern approach to preventing CSRF in Go

#18
The code he provides doesn't compile and needs to be changed like so:

  --- main_before.go      2025-10-15 09:56:16.467115934 +0200
  +++ main.go     2025-10-15 09:52:14.798134654 +0200
  @@ -13,8 +13,10 @@
  
          slog.Info("starting server on :4000")
  
  +       csrfProt := http.NewCrossOriginProtection()
  +
          // Wrap the mux with the http.NewCrossOriginProtection middleware.
  -       err := http.ListenAndServe(":4000", http.NewCrossOriginProtection(mux))
  +       err := http.ListenAndServe(":4000", csrfProt.Handler(mux))
          if err != nil {
                  slog.Error(err.Error())
                  os.Exit(1)

Re: A modern approach to preventing CSRF in Go

#19

I would never rely on headers such as "Sec-Fetch-Site"; having security rely on client generated (correct) responses is just poor security modelling (don't trust the client). I'll stick to time bounded HMAC cookies, then you're not relying on client properly implementing any headers and it will work with any browser that supports cookies. And having TLS v1.3 should be a requirement; no HTTPS, no session, no auth, no…

CSRF is about preventing other websites from making requests to your page using the credentials (including cookies) stored in the browser. Cookies can't prevent CSRF, in fact they are the problem to be solved.

Re: A modern approach to preventing CSRF in Go

#20

I would never rely on headers such as "Sec-Fetch-Site"; having security rely on client generated (correct) responses is just poor security modelling (don't trust the client). I'll stick to time bounded HMAC cookies, then you're not relying on client properly implementing any headers and it will work with any browser that supports cookies. And having TLS v1.3 should be a requirement; no HTTPS, no session, no auth, no…

No, in CSRF the browser is not the adversary, it is a confused deputy, and it’s perfectly reasonable to collaborate with it against the attacker (which is another site).

You might want to read https://words.filippo.io/csrf.

Post reply on HN