Skip to content

Commit c3e72a9

Browse files
authored
Merge commit from fork
Input validation rules were applied to all user supplied input in postLocal method
2 parents fff52f8 + 1e2204f commit c3e72a9

File tree

3 files changed

+47
-10
lines changed

3 files changed

+47
-10
lines changed

Diff for: cmd/serve.go

+32-10
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,13 @@ import (
55
"encoding/base64"
66
"encoding/json"
77
"fmt"
8-
"io/ioutil"
8+
"io"
99
"log"
1010
"net"
1111
"net/http"
1212
"os"
1313
"path"
14-
"path/filepath"
14+
"regexp"
1515
"strconv"
1616
"strings"
1717
"time"
@@ -24,6 +24,7 @@ import (
2424
"github.com/MakeNowJust/heredoc/v2"
2525
"github.com/briandowns/spinner"
2626
"github.com/gerald1248/httpscerts"
27+
"github.com/go-playground/validator/v10"
2728
"github.com/spf13/cobra"
2829
"golang.org/x/net/websocket"
2930
)
@@ -40,6 +41,9 @@ var SSLFlag bool
4041
// LocalFlag can be set to false to emulate a remote environment
4142
var LocalFlag bool
4243

44+
// Valditor for input validation
45+
var validate *validator.Validate
46+
4347
func checkPortAvailability(port int) bool {
4448
address := fmt.Sprintf("localhost:%d", port)
4549
conn, err := net.Dial("tcp", address)
@@ -195,16 +199,28 @@ func init() {
195199
serveCmd.Flags().StringVarP(&ConfigFileFlag, "config", "c", "plenti.json", "use a custom sitewide configuration file")
196200
}
197201

202+
// Validate user supplied values
198203
type localChange struct {
199-
Action string
200-
Encoding string
201-
File string
202-
Contents string
204+
Action string `json:"action" validate:"required,oneof=create update delete"`
205+
Encoding string `json:"encoding" validate:"required,oneof=base64 text"`
206+
File string `json:"file" validate:"file-path"`
207+
Contents string `json:"contents" validate:"required"`
208+
}
209+
210+
// Custom validation for file path. Only allow files in the layouts and content directories.
211+
func FilePathValidation(fl validator.FieldLevel) bool {
212+
reFilePath := regexp.MustCompile(`^(content)[a-zA-Z0-9_\-\/]*(.json)$`)
213+
fmt.Println(fl.Field().String())
214+
return reFilePath.MatchString(fl.Field().String())
203215
}
204216

205217
func postLocal(w http.ResponseWriter, r *http.Request) {
218+
// Register custom rules to validator
219+
validate = validator.New()
220+
validate.RegisterValidation("file-path", FilePathValidation)
221+
206222
if r.Method == "POST" {
207-
b, err := ioutil.ReadAll(r.Body)
223+
b, err := io.ReadAll(r.Body)
208224
if err != nil {
209225
fmt.Printf("Could not read 'body' from local edit: %v", err)
210226
}
@@ -213,10 +229,16 @@ func postLocal(w http.ResponseWriter, r *http.Request) {
213229
if err != nil {
214230
fmt.Printf("Could not unmarshal JSON data: %v", err)
215231
}
232+
216233
var contents []byte
217-
currentDir, _ := os.Getwd()
218234
for _, change := range localChanges {
219-
change.File = filepath.Join(currentDir, filepath.Clean("/"+change.File))
235+
236+
// Validate user input, there is any error, return 400 Bad Request
237+
err := validate.Struct(change)
238+
if err != nil {
239+
http.Error(w, err.Error(), http.StatusBadRequest)
240+
return
241+
}
220242

221243
if change.Action == "create" || change.Action == "update" {
222244
contents = []byte(change.Contents)
@@ -267,7 +289,7 @@ func serveSSL(port int) {
267289
Handler: nil,
268290
ReadTimeout: 10 * time.Second,
269291
WriteTimeout: 10 * time.Second,
270-
ErrorLog: log.New(ioutil.Discard, "", 0),
292+
ErrorLog: log.New(io.Discard, "", 0),
271293
MaxHeaderBytes: 1 << 20,
272294
TLSConfig: cfg,
273295
}

Diff for: go.mod

+5
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,19 @@ require (
3030
github.com/cyphar/filepath-securejoin v0.2.4 // indirect
3131
github.com/emirpasic/gods v1.18.1 // indirect
3232
github.com/fatih/color v1.10.0 // indirect
33+
github.com/gabriel-vasile/mimetype v1.4.3 // indirect
3334
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect
3435
github.com/go-git/go-billy/v5 v5.5.0 // indirect
36+
github.com/go-playground/locales v0.14.1 // indirect
37+
github.com/go-playground/universal-translator v0.18.1 // indirect
38+
github.com/go-playground/validator/v10 v10.23.0 // indirect
3539
github.com/gobwas/glob v0.2.3 // indirect
3640
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
3741
github.com/inconshreveable/mousetrap v1.0.0 // indirect
3842
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
3943
github.com/juju/ansiterm v0.0.0-20180109212912-720a0952cc2a // indirect
4044
github.com/kevinburke/ssh_config v1.2.0 // indirect
45+
github.com/leodido/go-urn v1.4.0 // indirect
4146
github.com/lunixbochs/vtclean v1.0.0 // indirect
4247
github.com/matthewmueller/glob v0.0.3 // indirect
4348
github.com/mattn/go-colorable v0.1.8 // indirect

Diff for: go.sum

+10
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,8 @@ github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGE
7777
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
7878
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
7979
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
80+
github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0=
81+
github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk=
8082
github.com/gerald1248/httpscerts v0.0.0-20170315065746-2c461ceb29ee h1:peCFhBNAfjd8yznwEnOjqn8Aj6KDTorDKYTYnt6lCTY=
8183
github.com/gerald1248/httpscerts v0.0.0-20170315065746-2c461ceb29ee/go.mod h1:DXNa9ZIDTqZ0mipcmqLRVodihgtvR6PBX5rNtlcMYs0=
8284
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
@@ -94,6 +96,12 @@ github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9
9496
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
9597
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
9698
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
99+
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
100+
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
101+
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
102+
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
103+
github.com/go-playground/validator/v10 v10.23.0 h1:/PwmTwZhS0dPkav3cdK9kV1FsAmrL8sThn8IHr/sO+o=
104+
github.com/go-playground/validator/v10 v10.23.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM=
97105
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
98106
github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y=
99107
github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8=
@@ -171,6 +179,8 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
171179
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
172180
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
173181
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
182+
github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
183+
github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
174184
github.com/livebud/npm v0.0.5 h1:ehDCwZvm/EJ+x3tJfHbbgY7CHPWlG4vJNP3KNBB3mKQ=
175185
github.com/livebud/npm v0.0.5/go.mod h1:JxHp3/zoEtpmkYJw6J7uHqNTQNX6d2HaZ3FEeeL3EO4=
176186
github.com/lunixbochs/vtclean v0.0.0-20180621232353-2d01aacdc34a/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI=

0 commit comments

Comments
 (0)