From 0bbe9b17dfc5c81e1ed1f4f055e51d84b90ae3cd Mon Sep 17 00:00:00 2001 From: Jonathan David Page Date: Sun, 28 Feb 2021 15:12:15 -0500 Subject: [PATCH] Use salt when generating ids from ips --- add-comment/add_comment.go | 1 + example-config.toml | 12 ++++++++++++ shared/shared.go | 28 ++++++++++++++++++++++++++++ 3 files changed, 41 insertions(+) diff --git a/add-comment/add_comment.go b/add-comment/add_comment.go index 036594c..df9cd36 100644 --- a/add-comment/add_comment.go +++ b/add-comment/add_comment.go @@ -167,6 +167,7 @@ func getId(ip string) string { ip = strings.ReplaceAll(ip, "_", ":") // Use real IP address, not sanitized h := sha256.New() h.Write([]byte(ip)) + h.Write(shared.GetIPSalt()) // First 8 chars return fmt.Sprintf("%x", h.Sum(nil))[:8] } diff --git a/example-config.toml b/example-config.toml index 62ab4e5..bded244 100644 --- a/example-config.toml +++ b/example-config.toml @@ -7,6 +7,18 @@ data = "/home/username/.local/share/gemlikes" # It must be accessible to the user that the CGI script runs under. # Directories will be created as needed, don't create them yourself. +# Where to store IP salt: +ip_salt = "auto" # default +#ip_salt = "disabled" # disable IP salting (old behavior) +#ip_salt = "/usr/local/etc/gemlikes/ip_salt" # use existing salt +# If unset, the default is "auto", which places the salt in the data directory, +# generating it the first time if needed. "disabled" restores the old behavior, +# which can potentially expose IP addresses to sufficiently-motivated attackers. +# Specifying an absolute path uses the contents of the given file as a salt, +# which must already exist. This allows multiple instances of gemlikes (e.g. in +# a shared environment) to present identical identifiers for the same IP. The +# path should be somewhere the server won't serve. + # The list of directories where files exist that can be liked and commented on: dirs = ["/var/gemini", "/var/gemini/my_gemlog"] # IMPORTANT: There can't be any files with same name in any of these directories, diff --git a/shared/shared.go b/shared/shared.go index 217e9e1..636d9d5 100644 --- a/shared/shared.go +++ b/shared/shared.go @@ -2,8 +2,11 @@ package shared import ( + "crypto/rand" "errors" "fmt" + "io" + "io/ioutil" "net/url" "os" "path/filepath" @@ -176,6 +179,31 @@ func GetTmpDir() string { return filepath.Join(getDataDir(), "tmp") } +func GetIPSalt() []byte { + config, _ := toml.LoadFile(GetConfigPath()) + ipSalt := "auto" + if key := config.Get("ip_salt"); key != nil { + ipSalt = key.(string) + } + + ipSaltPath := ipSalt + switch ipSalt { + case "disabled": + return nil + case "auto": + ipSaltPath = filepath.Join(getDataDir(), "ip_salt") + f, err := os.OpenFile(ipSaltPath, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0o666) + if err == nil { + // First time, create random data + defer f.Close() + io.CopyN(f, rand.Reader, 16) + } + } + + salt, _ := ioutil.ReadFile(ipSaltPath) + return salt +} + func getConfigDir() string { e, _ := os.Executable() return filepath.Dir(e)