Skip to content

Commit 8f41d97

Browse files
committed
CSRF protection added
1 parent 06ae8d1 commit 8f41d97

File tree

7 files changed

+51
-8
lines changed

7 files changed

+51
-8
lines changed

CHANGELOG.md

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# Changelog
2+
3+
All notable changes to this project will be documented in this file.
4+
5+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7+
8+
## [Unreleased]
9+
### Added
10+
- CSRF protection for main form [@osminogin](https://github.com/osminogin)
11+
12+
### Changed
13+
- Licensed under Apache v2 license [@osminogin](https://github.com/osminogin).

go.mod

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ go 1.14
55
require (
66
github.com/go-pg/pg/v10 v10.0.0-beta.2
77
github.com/google/uuid v1.1.1
8+
github.com/gorilla/csrf v1.7.0
89
github.com/gorilla/mux v1.7.4
910
github.com/segmentio/encoding v0.1.14 // indirect
1011
github.com/spf13/viper v1.7.0

go.sum

+6
Original file line numberDiff line numberDiff line change
@@ -109,8 +109,12 @@ github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+
109109
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
110110
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
111111
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
112+
github.com/gorilla/csrf v1.7.0 h1:mMPjV5/3Zd460xCavIkppUdvnl5fPXMpv2uz2Zyg7/Y=
113+
github.com/gorilla/csrf v1.7.0/go.mod h1:+a/4tCmqhG6/w4oafeAZ9pEa3/NZOWYVbD9fV0FwIQA=
112114
github.com/gorilla/mux v1.7.4 h1:VuZ8uybHlWmqV03+zRzdwKL4tUnIp1MAQtp1mIFE1bc=
113115
github.com/gorilla/mux v1.7.4/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
116+
github.com/gorilla/securecookie v1.1.1 h1:miw7JPhV+b/lAHSXz4qd/nN9jRiAFV5FwjeKyCS8BvQ=
117+
github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4=
114118
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
115119
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
116120
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
@@ -184,6 +188,8 @@ github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181
184188
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
185189
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
186190
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
191+
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
192+
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
187193
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
188194
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
189195
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=

handlers.go

+6-3
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,15 @@ import (
2222
"net/http"
2323

2424
"github.com/google/uuid"
25+
"github.com/gorilla/csrf"
2526
"github.com/gorilla/mux"
2627
)
2728

28-
// frontPageHandler render home page.
29-
func frontPageHandler(w http.ResponseWriter, r *http.Request) {
30-
renderTemplate(w, "index.html", nil)
29+
// mainFormHandler renders main form.
30+
func mainFormHandler(w http.ResponseWriter, r *http.Request) {
31+
renderTemplate(w, "index.html", map[string]interface{}{
32+
csrf.TemplateTag: csrf.TemplateField(r),
33+
})
3134
}
3235

3336
// publicFileHandler get file from bindata or return not found error.

public/main.js

+2
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,13 @@ $(document).ready(function() {
2222
var text = form.find("textarea").val();
2323
var secret = sjcl.codec.base64url.fromBits(sjcl.random.randomWords(5));
2424
var encrypted = sjcl.encrypt(secret, text);
25+
let csrfToken = document.getElementsByName("csrf_token")[0].value;
2526

2627
$.ajax({
2728
url: form.attr("action"),
2829
method: "POST",
2930
data: {body: encrypted.toString()},
31+
headers: {"X-CSRF-Token": csrfToken},
3032
success: function(id) {
3133
var link = window.location.href.toString() + id + "#" + secret;
3234
$("#secret_link").text(link);

server.go

+21-4
Original file line numberDiff line numberDiff line change
@@ -17,24 +17,26 @@
1717
package tornote
1818

1919
import (
20+
"crypto/sha256"
2021
"fmt"
2122
"log"
2223
"net/http"
2324

2425
"github.com/go-pg/pg/v10"
2526
"github.com/go-pg/pg/v10/orm"
27+
"github.com/gorilla/csrf"
2628
"github.com/gorilla/mux"
2729
)
2830

2931
type server struct {
3032
// Listen port
3133
Port uint64
3234
// Secret used for encryption/decription
33-
Key string
35+
Key string
3436
// Data source name
3537
DSN string
3638
// PostgreSQL connection
37-
db *pg.DB
39+
db *pg.DB
3840
}
3941

4042
type Server interface {
@@ -76,12 +78,27 @@ func (s *server) createSchema() error {
7678
return nil
7779
}
7880

79-
// Running daemon process.
81+
// Generate hash from server secret key.
82+
func (s *server) getSecretHash() []byte {
83+
h := sha256.New()
84+
h.Write([]byte("hello world\n"))
85+
return h.Sum(nil)
86+
}
87+
88+
// Running server.
8089
func (s *server) Run() error {
8190
r := mux.NewRouter().StrictSlash(true)
8291

92+
// Setup middlewares
93+
csrfMiddleware := csrf.Protect(
94+
s.getSecretHash(),
95+
csrf.FieldName("csrf_token"),
96+
csrf.SameSite(csrf.SameSiteStrictMode),
97+
)
98+
r.Use(csrfMiddleware)
99+
83100
// HTTP handlers
84-
r.HandleFunc("/", frontPageHandler).Methods("GET")
101+
r.HandleFunc("/", mainFormHandler).Methods("GET")
85102
//r.PathPrefix("/favicon.ico").HandlerFunc(publicFileHandler).Methods("GET")
86103
r.PathPrefix("/public/").HandlerFunc(publicFileHandler).Methods("GET")
87104
r.Handle("/note", createNoteHandler(s)).Methods("POST")

templates/index.html

+2-1
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,10 @@
88
</div>
99
</noscript>
1010

11-
<!-- Submit form -->
11+
<!-- Main form -->
1212
<div id="main" class="hidden">
1313
<form id="note" action="/note" method="post">
14+
{{ .csrfField }}
1415
<div class="form-group">
1516
<label for="note">
1617
Write your note below

0 commit comments

Comments
 (0)