commit 696a2baa68b8315698ec3ea73e5e6138fe6b3518
Author: selfhoster1312 <selfhoster1312@kl.netlib.re>
Date: Sat Dec 06 20:14:58 2025 +0000
diff --git a/bridge/config/config.go b/bridge/config/config.go
index 37f37c7..3a1dff2 100644
--- a/bridge/config/config.go
+++ b/bridge/config/config.go
@@ -76 +77 @@ import (
"io/ioutil"
"os"
"path/filepath"
+ "regexp"
"strings"
"sync"
"time"
@@ -28514 +28616 @@ type Config interface {
GetString(key string) (string, bool)
GetStringSlice(key string) ([]string, bool)
GetStringSlice2D(key string) ([][]string, bool)
+ IsFilenameBlacklisted(filename string) bool
}
type config struct {
sync.RWMutex
- logger *logrus.Entry
- v *viper.Viper
- cv *BridgeValues
+ logger *logrus.Entry
+ v *viper.Viper
+ cv *BridgeValues
+ MediaDownloadBlackListRegexes *[]*regexp.Regexp
}
// NewConfig instantiates a new configuration based on the specified configuration file path.
@@ -3196 +32212 @@ func NewConfig(rootLogger *logrus.Logger, cfgfile string) Config {
if mycfg.cv.General.MediaDownloadSize == 0 {
mycfg.cv.General.MediaDownloadSize = 1000000
}
+
+ // Precompile MediaBlackList regexes so we make sure they're correct,
+ // and they don't have to be compiled on every file attachment, because
+ // that's a slow operation.
+ mycfg.compileMediaDownloadBlackListRegexes()
+
viper.WatchConfig()
viper.OnConfigChange(func(e fsnotify.Event) {
logger.Println("Config file changed:", e.Name)
@@ -4226 +43144 @@ func (c *config) GetStringSlice2D(key string) ([][]string, bool) {
return result, true
}
+// IsFilenameBlackListed checks if a given file name matches the
+// configured blacklist. This is useful to filter potentially-harmful
+// files that could be served over HTTP (eg. `.html` with XSS).
+func (c *config) IsFilenameBlacklisted(filename string) bool {
+ c.RLock()
+ defer c.RUnlock()
+
+ for _, re := range *c.MediaDownloadBlackListRegexes {
+ if re.MatchString(filename) {
+ return true
+ }
+ }
+
+ return false
+}
+
+func (c *config) compileMediaDownloadBlackListRegexes() {
+ regexes := []*regexp.Regexp{}
+
+ // TODO: apparently c.cv.General does not get updated when config reloads
+ // see https://github.com/matterbridge-org/matterbridge/issues/57
+ // for _, regex := range c.cv.General.MediaDownloadBlackList {
+ for _, regex := range c.v.GetStringSlice("general.MediaDownloadBlackList") {
+ c.logger.Debugf("Found blacklist regex %s", regex)
+
+ re, err := regexp.Compile(regex)
+ if err != nil {
+ c.logger.Errorf("incorrect regexp %s for MediaDownloadBlackList", regex)
+ continue
+ }
+
+ regexes = append(regexes, re)
+ }
+
+ c.MediaDownloadBlackListRegexes = ®exes
+ c.logger.Debug("Successfully applied new `MediaDownloadBlackList` regexes")
+}
+
func GetIconURL(msg *Message, iconURL string) string {
info := strings.Split(msg.Account, ".")
protocol := info[0]