There's so much good content here, but it's also very surprising how much of it is truly a "roll-your-own and hope you get it right" approach.<p>If you have to write explicit code in each of your postbacks to check a CSRF token, it's going to happen that not all your posts will end up being protected. If you have to hand-build SQL queries, it's going to happen that you'll have injection vulnerabilities. If you are manually generating and signing cookies, and having to write explicit code to sign them and check signatures... These are all features that should be done in a core library which makes sure these things happen all the time, not just when you remember to, what, copy/paste the code into each of your functions to do it?<p>There's the overall structure of the code, which seems like it would quickly devolve into chaos. Looking at Section 4.4 there's a 'login' function which handles rendering the GET as well as processing the POST just by if/else on r.Method. You wouldn't want to actually structure a code-base like this, right? Later on, they do show a 'Beego' based router, which seems a bit more sane, but I'm really not a fan of 'showing the wrong way first' as a learning tool.<p>The particular techniques being used seem very home-grown and not particularly best practice. To prevent double-submit they add a hidden field with token=MD5(time.Now) and also save it to "a session cookie on the server side"? Not quite sure what that means, but I think it's trying to say save the token on the back-end linked to the session, and then verify a POST, from that page, on that session, has that token. And then presumably clean up the storage... The majority of which is not actually coded in the example, making it just a high level roadmap of what you could do, not a practical working starting point. But anyway, if your goal is to prevent multiple POSTs per GET, and you already have a transactional session state for the user, then you do it with a server-side counter, not a hidden field, and certainly not a "obfuscated" MD5(time.Now). Even if you have no session state, then the simple answer is to create session state, not to create another token which does exactly the same thing as session state, but in a completely insecure manor.<p>So overall I have a ton of respect for the work that was put into this document, it tries to cover a lot of material and is very easy to read. But I think the details also matter and 1) I can't believe this is idiomatic Go for how to actually route and manage requests, and 2) the entire proposed tool-set for actual secure processing of Sessions, SQL, CSRF, XSS, etc. seems to be totally home-grown and not at all production ready.