recommended fixes [1 of 2]

This commit is contained in:
Karmanyaah Malhotra 2022-10-07 16:16:20 -05:00
parent c2382d29a1
commit de2ca33700
4 changed files with 36 additions and 31 deletions

View file

@ -306,32 +306,31 @@ func sigHandlerConfigReload(config string) {
} }
func parseIPHostPrefix(host string) (prefixes []netip.Prefix, err error) { func parseIPHostPrefix(host string) (prefixes []netip.Prefix, err error) {
//try parsing as prefix //try parsing as prefix
prefix, err := netip.ParsePrefix(host) prefix, err := netip.ParsePrefix(host)
if err == nil { if err == nil {
prefixes = append(prefixes, prefix.Masked()) // masked and canonical for easy of debugging, shouldn't matter prefixes = append(prefixes, prefix.Masked()) // Masked returns the prefix in its canonical form, the same for every ip in the range. This exists for ease of debugging. For example, 10.1.2.3/16 is 10.1.0.0/16.
return prefixes, nil // success return prefixes, nil // success
} }
// not a prefix, parse as host or IP // not a prefix, parse as host or IP
// LookupHost forwards through if it's an IP // LookupHost forwards through if it's an IP
ips, err := net.LookupHost(host) ips, err := net.LookupHost(host)
if err == nil { if err == nil {
for _, i := range ips { for _, i := range ips {
ip, err := netip.ParseAddr(i) ip, err := netip.ParseAddr(i)
if err == nil { if err == nil {
prefix, err := ip.Prefix(ip.BitLen()) prefix, err := ip.Prefix(ip.BitLen())
if err != nil { if err != nil {
return prefixes, errors.New(fmt.Sprint("ip", ip, " successfully parsed as IP but unable to turn into prefix. THIS SHOULD NEVER HAPPEN. err:", err.Error())) return prefixes, errors.New(fmt.Sprint("ip", ip, " successfully parsed as IP but unable to turn into prefix. THIS SHOULD NEVER HAPPEN. err:", err.Error()))
} }
prefixes = append(prefixes, prefix.Masked()) //also masked canonical ip prefixes = append(prefixes, prefix.Masked()) //also masked canonical ip
} }
} }
} }
return return
} }
func reloadLogLevel(inputSource altsrc.InputSourceContext) { func reloadLogLevel(inputSource altsrc.InputSourceContext) {
newLevelStr, err := inputSource.String("log-level") newLevelStr, err := inputSource.String("log-level")
if err != nil { if err != nil {

View file

@ -456,6 +456,11 @@ func readMessages(rows *sql.Rows) ([]*message, error) {
return nil, err return nil, err
} }
} }
senderIP, err := netip.ParseAddr(sender)
if err != nil {
senderIP = netip.IPv4Unspecified() // if no IP stored in database, 0.0.0.0
}
var att *attachment var att *attachment
if attachmentName != "" && attachmentURL != "" { if attachmentName != "" && attachmentURL != "" {
att = &attachment{ att = &attachment{
@ -479,7 +484,7 @@ func readMessages(rows *sql.Rows) ([]*message, error) {
Icon: icon, Icon: icon,
Actions: actions, Actions: actions,
Attachment: att, Attachment: att,
Sender: netip.MustParseAddr(sender), // Must parse assuming database must be correct Sender: senderIP, // Must parse assuming database must be correct
Encoding: encoding, Encoding: encoding,
}) })
} }

View file

@ -643,8 +643,8 @@ func (s *Server) parsePublishParams(r *http.Request, v *visitor, m *message) (ca
return false, false, "", false, errHTTPBadRequestDelayTooLarge return false, false, "", false, errHTTPBadRequestDelayTooLarge
} }
m.Time = delay.Unix() m.Time = delay.Unix()
m.Sender = v.ip // Important for rate limiting
} }
m.Sender = v.ip // Important for rate limiting
actionsStr := readParam(r, "x-actions", "actions", "action") actionsStr := readParam(r, "x-actions", "actions", "action")
if actionsStr != "" { if actionsStr != "" {
m.Actions, err = parseActions(actionsStr) m.Actions, err = parseActions(actionsStr)
@ -1220,7 +1220,7 @@ func (s *Server) runFirebaseKeepaliver() {
if s.firebaseClient == nil { if s.firebaseClient == nil {
return return
} }
v := newVisitor(s.config, s.messageCache, netip.MustParseAddr("0.0.0.0")) // Background process, not a real visitor v := newVisitor(s.config, s.messageCache, netip.IPv4Unspecified()) // Background process, not a real visitor, uses IP 0.0.0.0
for { for {
select { select {
case <-time.After(s.config.FirebaseKeepaliveInterval): case <-time.After(s.config.FirebaseKeepaliveInterval):
@ -1287,7 +1287,7 @@ func (s *Server) sendDelayedMessage(v *visitor, m *message) error {
func (s *Server) limitRequests(next handleFunc) handleFunc { func (s *Server) limitRequests(next handleFunc) handleFunc {
return func(w http.ResponseWriter, r *http.Request, v *visitor) error { return func(w http.ResponseWriter, r *http.Request, v *visitor) error {
if util.ContainsContains(s.config.VisitorRequestExemptIPAddrs, v.ip) { if util.ContainsIP(s.config.VisitorRequestExemptIPAddrs, v.ip) {
return next(w, r, v) return next(w, r, v)
} else if err := v.RequestAllowed(); err != nil { } else if err := v.RequestAllowed(); err != nil {
return errHTTPTooManyRequestsLimitRequests return errHTTPTooManyRequestsLimitRequests
@ -1449,8 +1449,8 @@ func (s *Server) visitor(r *http.Request) *visitor {
ips := util.SplitNoEmpty(r.Header.Get("X-Forwarded-For"), ",") ips := util.SplitNoEmpty(r.Header.Get("X-Forwarded-For"), ",")
myip, err := netip.ParseAddr(strings.TrimSpace(util.LastString(ips, remoteAddr))) myip, err := netip.ParseAddr(strings.TrimSpace(util.LastString(ips, remoteAddr)))
if err != nil { if err != nil {
log.Error("Invalid IP Address Received from proxy in X-Forwarded-For header. This should NEVER happen, your proxy is seriously broken: ", ip, err) log.Error("invalid IP address %s received in X-Forwarded-For header: %s", ip, err.Error())
// fall back to regular remote address if x forwarded for is damaged // fall back to regular remote address if X-Forwarded-For is damaged
} else { } else {
ip = myip ip = myip
} }

View file

@ -7,6 +7,7 @@ import (
"fmt" "fmt"
"io" "io"
"math/rand" "math/rand"
"net/netip"
"os" "os"
"regexp" "regexp"
"strconv" "strconv"
@ -46,8 +47,8 @@ func Contains[T comparable](haystack []T, needle T) bool {
return false return false
} }
// ContainsContains returns true if any element of haystack .Contains(needle). // ContainsIP returns true if any one of the of prefixes contains the ip.
func ContainsContains[T interface{ Contains(U) bool }, U any](haystack []T, needle U) bool { func ContainsIP(haystack []netip.Prefix, needle netip.Addr) bool {
for _, s := range haystack { for _, s := range haystack {
if s.Contains(needle) { if s.Contains(needle) {
return true return true