Compare commits

...

10 Commits

Author SHA1 Message Date
Andrea Spacca
5e7e3a1b39 v1.1.7 2020-05-09 12:00:53 +02:00
Andrea Spacca
42adceb4c6 Merge pull request #309 from cheeseandcereal/fix_arbitrary_reading
fix missing metadata security vuln
2020-05-09 11:59:37 +02:00
Adam Crowder
f909ad3ce2 fix missing metadata security vuln 2020-05-08 16:23:32 -07:00
Andrea Spacca
8a5c737140 UPDATE README.md 2020-05-03 15:28:59 +02:00
Andrea Spacca
b920eb842a Merge pull request #304 from tofuSCHNITZEL/master
Added EnvVar to all flags
2020-05-03 13:28:21 +02:00
Tobias Perschon
45e0967a37 Update cmd.go
added EnvVar to all flags
2020-04-24 10:32:31 +02:00
Andrea Spacca
28614c991d Merge pull request #297 from dutchcoders/ISSUE-296
ISSUE-296 add CORS
2020-04-07 15:31:41 +02:00
Andrea Spacca
ef28bcb28f ISSUE-296 add CORS 2020-04-04 14:29:33 +02:00
Andrea Spacca
2dd23bff3c Merge pull request #291 from dutchcoders/ISSUE-278
ISSUE 278
2020-03-24 08:34:02 +01:00
Andrea Spacca
663c59e754 ISSUE 278 2020-03-23 09:22:58 +01:00
6 changed files with 98 additions and 37 deletions

View File

@@ -76,40 +76,43 @@ https://transfer.sh/1lDau/test.txt --> https://transfer.sh/inline/1lDau/test.txt
Parameter | Description | Value | Env Parameter | Description | Value | Env
--- | --- | --- | --- --- | --- | --- | ---
listener | port to use for http (:80) | | listener | port to use for http (:80) | | LISTENER |
profile-listener | port to use for profiler (:6060)| | profile-listener | port to use for profiler (:6060) | | PROFILE_LISTENER |
force-https | redirect to https | false | force-https | redirect to https | false | FORCE_HTTPS
tls-listener | port to use for https (:443) | | tls-listener | port to use for https (:443) | | TLS_LISTENER |
tls-listener-only | flag to enable tls listener only | | tls-listener-only | flag to enable tls listener only | | TLS_LISTENER_ONLY |
tls-cert-file | path to tls certificate | | tls-cert-file | path to tls certificate | | TLS_CERT_FILE |
tls-private-key | path to tls private key | | tls-private-key | path to tls private key | | TLS_PRIVATE_KEY |
http-auth-user | user for basic http auth on upload | | http-auth-user | user for basic http auth on upload | | HTTP_AUTH_USER |
http-auth-pass | pass for basic http auth on upload | | http-auth-pass | pass for basic http auth on upload | | HTTP_AUTH_PASS |
ip-whitelist | comma separated list of ips allowed to connect to the service | | ip-whitelist | comma separated list of ips allowed to connect to the service | | IP_WHITELIST |
ip-blacklist | comma separated list of ips not allowed to connect to the service | | ip-blacklist | comma separated list of ips not allowed to connect to the service | | IP_BLACKLIST |
temp-path | path to temp folder | system temp | temp-path | path to temp folder | system temp | TEMP_PATH |
web-path | path to static web files (for development or custom front end) | | web-path | path to static web files (for development or custom front end) | | WEB_PATH |
proxy-path | path prefix when service is run behind a proxy | | proxy-path | path prefix when service is run behind a proxy | | PROXY_PATH |
ga-key | google analytics key for the front end | | ga-key | google analytics key for the front end | | GA_KEY |
uservoice-key | user voice key for the front end | | uservoice-key | user voice key for the front end | | USERVOICE_KEY |
provider | which storage provider to use | (s3, gdrive or local) | provider | which storage provider to use | (s3, gdrive or local) | PROVIDER |
aws-access-key | aws access key | | AWS_ACCESS_KEY aws-access-key | aws access key | | AWS_ACCESS_KEY |
aws-secret-key | aws access key | | AWS_SECRET_KEY aws-secret-key | aws access key | | AWS_SECRET_KEY |
bucket | aws bucket | | BUCKET bucket | aws bucket | | BUCKET |
s3-endpoint | Custom S3 endpoint. | | s3-endpoint | Custom S3 endpoint. | | S3_ENDPOINT |
s3-region | region of the s3 bucket | eu-west-1 | S3_REGION s3-region | region of the s3 bucket | eu-west-1 | S3_REGION |
s3-no-multipart | disables s3 multipart upload | false | | s3-no-multipart | disables s3 multipart upload | false | S3_NO_MULTIPART |
s3-path-style | Forces path style URLs, required for Minio. | false | | s3-path-style | Forces path style URLs, required for Minio. | false | S3_PATH_STYLE |
basedir | path storage for local/gdrive provider| | basedir | path storage for local/gdrive provider | | BASEDIR |
gdrive-client-json-filepath | path to oauth client json config for gdrive provider| | gdrive-client-json-filepath | path to oauth client json config for gdrive provider | | GDRIVE_CLIENT_JSON_FILEPATH |
gdrive-local-config-path | path to store local transfer.sh config cache for gdrive provider| | gdrive-local-config-path | path to store local transfer.sh config cache for gdrive provider| | GDRIVE_LOCAL_CONFIG_PATH |
gdrive-chunk-size | chunk size for gdrive upload in megabytes, must be lower than available memory (8 MB) | | gdrive-chunk-size | chunk size for gdrive upload in megabytes, must be lower than available memory (8 MB) | | GDRIVE_CHUNK_SIZE |
lets-encrypt-hosts | hosts to use for lets encrypt certificates (comma seperated) | | lets-encrypt-hosts | hosts to use for lets encrypt certificates (comma seperated) | | HOSTS |
log | path to log file| | log | path to log file| | LOG |
cors-domains | comma separated list of domains for CORS, setting it enable CORS | | CORS_DOMAINS |
clamav-host | host for clamav feature | | CLAMAV_HOST |
rate-limit | request per minute | | RATE_LIMIT |
If you want to use TLS using lets encrypt certificates, set lets-encrypt-hosts to your domain, set tls-listener to :443 and enable force-https. If you want to use TLS using lets encrypt certificates, set lets-encrypt-hosts to your domain, set tls-listener to :443 and enable force-https.
If you want to use TLS using your own certificates, set tls-listener to :443, force-https, tls-cert=file and tls-private-key. If you want to use TLS using your own certificates, set tls-listener to :443, force-https, tls-cert-file and tls-private-key.
## Development ## Development

View File

@@ -12,7 +12,7 @@ import (
"google.golang.org/api/googleapi" "google.golang.org/api/googleapi"
) )
var Version = "1.1.4" var Version = "1.1.7"
var helpTemplate = `NAME: var helpTemplate = `NAME:
{{.Name}} - {{.Usage}} {{.Name}} - {{.Usage}}
@@ -37,6 +37,7 @@ var globalFlags = []cli.Flag{
Name: "listener", Name: "listener",
Usage: "127.0.0.1:8080", Usage: "127.0.0.1:8080",
Value: "127.0.0.1:8080", Value: "127.0.0.1:8080",
EnvVar: "LISTENER",
}, },
// redirect to https? // redirect to https?
// hostnames // hostnames
@@ -44,57 +45,69 @@ var globalFlags = []cli.Flag{
Name: "profile-listener", Name: "profile-listener",
Usage: "127.0.0.1:6060", Usage: "127.0.0.1:6060",
Value: "", Value: "",
EnvVar: "PROFILE_LISTENER",
}, },
cli.BoolFlag{ cli.BoolFlag{
Name: "force-https", Name: "force-https",
Usage: "", Usage: "",
EnvVar: "FORCE_HTTPS",
}, },
cli.StringFlag{ cli.StringFlag{
Name: "tls-listener", Name: "tls-listener",
Usage: "127.0.0.1:8443", Usage: "127.0.0.1:8443",
Value: "", Value: "",
EnvVar: "TLS_LISTENER",
}, },
cli.BoolFlag{ cli.BoolFlag{
Name: "tls-listener-only", Name: "tls-listener-only",
Usage: "", Usage: "",
EnvVar: "TLS_LISTENER_ONLY",
}, },
cli.StringFlag{ cli.StringFlag{
Name: "tls-cert-file", Name: "tls-cert-file",
Value: "", Value: "",
EnvVar: "TLS_CERT_FILE",
}, },
cli.StringFlag{ cli.StringFlag{
Name: "tls-private-key", Name: "tls-private-key",
Value: "", Value: "",
EnvVar: "TLS_PRIVATE_KEY",
}, },
cli.StringFlag{ cli.StringFlag{
Name: "temp-path", Name: "temp-path",
Usage: "path to temp files", Usage: "path to temp files",
Value: os.TempDir(), Value: os.TempDir(),
EnvVar: "TEMP_PATH",
}, },
cli.StringFlag{ cli.StringFlag{
Name: "web-path", Name: "web-path",
Usage: "path to static web files", Usage: "path to static web files",
Value: "", Value: "",
EnvVar: "WEB_PATH",
}, },
cli.StringFlag{ cli.StringFlag{
Name: "proxy-path", Name: "proxy-path",
Usage: "path prefix when service is run behind a proxy", Usage: "path prefix when service is run behind a proxy",
Value: "", Value: "",
EnvVar: "PROXY_PATH",
}, },
cli.StringFlag{ cli.StringFlag{
Name: "ga-key", Name: "ga-key",
Usage: "key for google analytics (front end)", Usage: "key for google analytics (front end)",
Value: "", Value: "",
EnvVar: "GA_KEY",
}, },
cli.StringFlag{ cli.StringFlag{
Name: "uservoice-key", Name: "uservoice-key",
Usage: "key for user voice (front end)", Usage: "key for user voice (front end)",
Value: "", Value: "",
EnvVar: "USERVOICE_KEY",
}, },
cli.StringFlag{ cli.StringFlag{
Name: "provider", Name: "provider",
Usage: "s3|gdrive|local", Usage: "s3|gdrive|local",
Value: "", Value: "",
EnvVar: "PROVIDER",
}, },
cli.StringFlag{ cli.StringFlag{
Name: "s3-endpoint", Name: "s3-endpoint",
@@ -129,31 +142,36 @@ var globalFlags = []cli.Flag{
cli.BoolFlag{ cli.BoolFlag{
Name: "s3-no-multipart", Name: "s3-no-multipart",
Usage: "Disables S3 Multipart Puts", Usage: "Disables S3 Multipart Puts",
EnvVar: "S3_NO_MULTIPART",
}, },
cli.BoolFlag{ cli.BoolFlag{
Name: "s3-path-style", Name: "s3-path-style",
Usage: "Forces path style URLs, required for Minio.", Usage: "Forces path style URLs, required for Minio.",
EnvVar: "S3_PATH_STYLE",
}, },
cli.StringFlag{ cli.StringFlag{
Name: "gdrive-client-json-filepath", Name: "gdrive-client-json-filepath",
Usage: "", Usage: "",
Value: "", Value: "",
EnvVar: "GDRIVE_CLIENT_JSON_FILEPATH",
}, },
cli.StringFlag{ cli.StringFlag{
Name: "gdrive-local-config-path", Name: "gdrive-local-config-path",
Usage: "", Usage: "",
Value: "", Value: "",
EnvVar: "GDRIVE_LOCAL_CONFIG_PATH",
}, },
cli.IntFlag{ cli.IntFlag{
Name: "gdrive-chunk-size", Name: "gdrive-chunk-size",
Usage: "", Usage: "",
Value: googleapi.DefaultUploadChunkSize / 1024 / 1024, Value: googleapi.DefaultUploadChunkSize / 1024 / 1024,
EnvVar: "GDRIVE_CHUNK_SIZE",
}, },
cli.IntFlag{ cli.IntFlag{
Name: "rate-limit", Name: "rate-limit",
Usage: "requests per minute", Usage: "requests per minute",
Value: 0, Value: 0,
EnvVar: "", EnvVar: "RATE_LIMIT",
}, },
cli.StringFlag{ cli.StringFlag{
Name: "lets-encrypt-hosts", Name: "lets-encrypt-hosts",
@@ -165,11 +183,13 @@ var globalFlags = []cli.Flag{
Name: "log", Name: "log",
Usage: "/var/log/transfersh.log", Usage: "/var/log/transfersh.log",
Value: "", Value: "",
EnvVar: "LOG",
}, },
cli.StringFlag{ cli.StringFlag{
Name: "basedir", Name: "basedir",
Usage: "path to storage", Usage: "path to storage",
Value: "", Value: "",
EnvVar: "BASEDIR",
}, },
cli.StringFlag{ cli.StringFlag{
Name: "clamav-host", Name: "clamav-host",
@@ -186,26 +206,37 @@ var globalFlags = []cli.Flag{
cli.BoolFlag{ cli.BoolFlag{
Name: "profiler", Name: "profiler",
Usage: "enable profiling", Usage: "enable profiling",
EnvVar: "PROFILER",
}, },
cli.StringFlag{ cli.StringFlag{
Name: "http-auth-user", Name: "http-auth-user",
Usage: "user for http basic auth", Usage: "user for http basic auth",
Value: "", Value: "",
EnvVar: "HTTP_AUTH_USER",
}, },
cli.StringFlag{ cli.StringFlag{
Name: "http-auth-pass", Name: "http-auth-pass",
Usage: "pass for http basic auth", Usage: "pass for http basic auth",
Value: "", Value: "",
EnvVar: "HTTP_AUTH_PASS",
}, },
cli.StringFlag{ cli.StringFlag{
Name: "ip-whitelist", Name: "ip-whitelist",
Usage: "comma separated list of ips allowed to connect to the service", Usage: "comma separated list of ips allowed to connect to the service",
Value: "", Value: "",
EnvVar: "IP_WHITELIST",
}, },
cli.StringFlag{ cli.StringFlag{
Name: "ip-blacklist", Name: "ip-blacklist",
Usage: "comma separated list of ips not allowed to connect to the service", Usage: "comma separated list of ips not allowed to connect to the service",
Value: "", Value: "",
EnvVar: "IP_BLACKLIST",
},
cli.StringFlag{
Name: "cors-domains",
Usage: "comma separated list of domains allowed for CORS requests",
Value: "",
EnvVar: "CORS_DOMAINS",
}, },
} }
@@ -245,6 +276,10 @@ func New() *Cmd {
options = append(options, server.Listener(v)) options = append(options, server.Listener(v))
} }
if v := c.String("cors-domains"); v != "" {
options = append(options, server.CorsDomains(v))
}
if v := c.String("tls-listener"); v == "" { if v := c.String("tls-listener"); v == "" {
} else if c.Bool("tls-listener-only") { } else if c.Bool("tls-listener-only") {
options = append(options, server.TLSListener(v, true)) options = append(options, server.TLSListener(v, true))

1
go.mod
View File

@@ -16,6 +16,7 @@ require (
github.com/garyburd/redigo v1.6.0 // indirect github.com/garyburd/redigo v1.6.0 // indirect
github.com/golang/gddo v0.0.0-20200310004957-95ce5a452273 github.com/golang/gddo v0.0.0-20200310004957-95ce5a452273
github.com/golang/protobuf v1.3.5 // indirect github.com/golang/protobuf v1.3.5 // indirect
github.com/gorilla/handlers v1.4.2
github.com/gorilla/mux v1.7.4 github.com/gorilla/mux v1.7.4
github.com/gorilla/securecookie v1.1.1 // indirect github.com/gorilla/securecookie v1.1.1 // indirect
github.com/hashicorp/golang-lru v0.5.3 // indirect github.com/hashicorp/golang-lru v0.5.3 // indirect

2
go.sum
View File

@@ -127,6 +127,8 @@ github.com/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
github.com/googleapis/gax-go/v2 v2.0.5 h1:sjZBwGj9Jlw33ImPtvFviGYvseOtDM7hkSKB7+Tv3SM= github.com/googleapis/gax-go/v2 v2.0.5 h1:sjZBwGj9Jlw33ImPtvFviGYvseOtDM7hkSKB7+Tv3SM=
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
github.com/gorilla/handlers v1.4.2 h1:0QniY0USkHQ1RGCLfKxeNHK9bkDHGRYGNDFBCS+YARg=
github.com/gorilla/handlers v1.4.2/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ=
github.com/gorilla/mux v1.7.3 h1:gnP5JzjVOuiZD07fKKToCAOjS0yOpj/qPETTXCCS6hw= github.com/gorilla/mux v1.7.3 h1:gnP5JzjVOuiZD07fKKToCAOjS0yOpj/qPETTXCCS6hw=
github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
github.com/gorilla/mux v1.7.4 h1:VuZ8uybHlWmqV03+zRzdwKL4tUnIp1MAQtp1mIFE1bc= github.com/gorilla/mux v1.7.4 h1:VuZ8uybHlWmqV03+zRzdwKL4tUnIp1MAQtp1mIFE1bc=

View File

@@ -614,9 +614,7 @@ func (s *Server) CheckMetadata(token, filename string, increaseDownload bool) (M
var metadata Metadata var metadata Metadata
r, _, err := s.storage.Get(token, fmt.Sprintf("%s.metadata", filename)) r, _, err := s.storage.Get(token, fmt.Sprintf("%s.metadata", filename))
if s.storage.IsNotExist(err) { if err != nil {
return metadata, nil
} else if err != nil {
return metadata, err return metadata, err
} }

View File

@@ -26,6 +26,7 @@ package server
import ( import (
"errors" "errors"
gorillaHandlers "github.com/gorilla/handlers"
"log" "log"
"math/rand" "math/rand"
"mime" "mime"
@@ -85,6 +86,13 @@ func Listener(s string) OptionFn {
} }
func CorsDomains(s string) OptionFn {
return func(srvr *Server) {
srvr.CorsDomains = s
}
}
func GoogleAnalytics(gaKey string) OptionFn { func GoogleAnalytics(gaKey string) OptionFn {
return func(srvr *Server) { return func(srvr *Server) {
srvr.gaKey = gaKey srvr.gaKey = gaKey
@@ -275,6 +283,7 @@ type Server struct {
TLSListenerOnly bool TLSListenerOnly bool
CorsDomains string
ListenerString string ListenerString string
TLSListenerString string TLSListenerString string
ProfileListenerString string ProfileListenerString string
@@ -413,11 +422,24 @@ func (s *Server) Run() {
s.logger.Printf("Transfer.sh server started.\nusing temp folder: %s\nusing storage provider: %s", s.tempPath, s.storage.Type()) s.logger.Printf("Transfer.sh server started.\nusing temp folder: %s\nusing storage provider: %s", s.tempPath, s.storage.Type())
var cors func(http.Handler) http.Handler
if len(s.CorsDomains) > 0 {
cors = gorillaHandlers.CORS(
gorillaHandlers.AllowedHeaders([]string{"*"}),
gorillaHandlers.AllowedOrigins(strings.Split(s.CorsDomains, ",")),
gorillaHandlers.AllowedMethods([]string{"GET", "HEAD", "POST", "PUT", "DELETE", "OPTIONS"}),
)
} else {
cors = func(h http.Handler) http.Handler {
return h
}
}
h := handlers.PanicHandler( h := handlers.PanicHandler(
IPFilterHandler( IPFilterHandler(
handlers.LogHandler( handlers.LogHandler(
LoveHandler( LoveHandler(
s.RedirectHandler(r)), s.RedirectHandler(cors(r))),
handlers.NewLogOptions(s.logger.Printf, "_default_"), handlers.NewLogOptions(s.logger.Printf, "_default_"),
), ),
s.ipFilterOptions, s.ipFilterOptions,