Golang : Perform sanity checks on filename example




Problem:

Your Golang application accepts files uploaded by visitors. However, you want to sanitize the uploaded filenames for security purpose. You want to remove non-standard characters from a typical filename and also want to have the option to preserve paths. How to do that?

Solution:

This code example below should be able to perform sanity checks on most common uploaded filenames. Enjoy!

 package main

 import (
 "fmt"
 "strings"
 )

 var badCharacters = []string{
 "../",
 "<!--",
 "-->",
 "<",
 ">",
 "'",
 "\"",
 "&",
 "$",
 "#",
 "{", "}", "[", "]", "=",
 ";", "?", "%20", "%22",
 "%3c", // <
 "%253c", // <
 "%3e", // >
 "", // > -- fill in with % 0 e - without spaces in between
 "%28", // (
 "%29", // )
 "%2528", // (
 "%26", // &
 "%24", // $
 "%3f", // ?
 "%3b", // ;
 "%3d", // =
 }

 func RemoveBadCharacters(input string, dictionary []string) string {

 temp := input

 for _, badChar := range dictionary {
 temp = strings.Replace(temp, badChar, "", -1)
 }
 return temp
 }

 func SanitizeFilename(name string, relativePath bool) string {

 // default settings
 var badDictionary []string = badCharacters

 if name == "" {
 return name
 }

 // if relativePath is TRUE, we preserve the path in the filename
 // If FALSE and will cause upper path foldername to merge with filename
 // USE WITH CARE!!!

 if !relativePath {
 // add additional bad characters
 badDictionary = append(badCharacters, "./")
 badDictionary = append(badDictionary, "/")
 }

 // trim(remove)white space
 trimmed := strings.TrimSpace(name)

 // trim(remove) white space in between characters
 trimmed = strings.Replace(trimmed, " ", "", -1)

 // remove bad characters from filename
 trimmed = RemoveBadCharacters(trimmed, badDictionary)

 stripped := strings.Replace(trimmed, "\\", "", -1)

 return stripped
 }

 func main() {
 fmt.Println("Sanitize filename example")
 filename := "../foldername/你的crazy& ! <!-- $#@# fileN@me.z ip "

 fmt.Printf("BEFORE : [%v]\n", filename)

 fmt.Printf("AFTER(preserve path)  : [%v]\n", SanitizeFilename(filename, true))

 fmt.Printf("AFTER(without path) : [%v]\n", SanitizeFilename(filename, false))

 } 

Output:

Sanitize filename example

BEFORE : [../foldername/你的crazy& ! <!-- $#@# fileN@me.z ip ]

AFTER(preserve path) : [foldername/你的crazy!@fileN@me.zip]

AFTER(without path) : [foldername你的crazy!@fileN@me.zip]

References:

https://github.com/bcit-ci/CodeIgniter/blob/develop/system/core/Security.php

https://golang.org/pkg/strings/#Replace

https://golang.org/pkg/strings/#TrimSpace

https://www.socketloop.com/tutorials/golang-removes-punctuation-or-defined-delimiter-from-the-user-s-input

  See also : Golang : Upload file from web browser to server





By Adam Ng

IF you gain some knowledge or the information here solved your programming problem. Please consider donating to the less fortunate or some charities that you like. Apart from donation, planting trees, volunteering or reducing your carbon footprint will be great too.


Advertisement