Harden security: SSRF guard on all outbound fetches, auth fixes
- Route image-validation, Matrix image-download, and wayback/archive.today fetches through safehttp so feed-controlled URLs can't reach loopback/ RFC1918/cloud-metadata IPs (incl. via redirects). - Cap feed body size with safehttp.LimitedBody (16 MiB) to prevent OOM. - Fail closed if matrix.pickle_key is unset/<16 chars; drop the hardcoded "pete_pickle_key" default that silently weakened E2EE-at-rest. - Gate !post behind a matrix.admins allowlist; empty = disabled (channel rooms are public, so empty must not mean anyone). - Reject /\host open-redirect bypass in post-login safeNext. - Allowlist http(s) schemes for the Matrix link href; escape JSON embedded in inline <script> (prefs/sources blobs).
This commit is contained in:
14
main.go
14
main.go
@@ -88,11 +88,25 @@ func main() {
|
||||
// Wire reaction handler
|
||||
mx.SetReactionHandler(poster.HandleReaction)
|
||||
|
||||
// Allowlist of users permitted to run in-room commands. The channel rooms
|
||||
// are public, so commands are gated to configured admins; an empty list
|
||||
// disables them entirely (fail closed) rather than allowing anyone.
|
||||
admins := make(map[id.UserID]bool, len(cfg.Matrix.Admins))
|
||||
for _, a := range cfg.Matrix.Admins {
|
||||
if a = strings.TrimSpace(a); a != "" {
|
||||
admins[id.UserID(a)] = true
|
||||
}
|
||||
}
|
||||
|
||||
// Wire !post command: force-publish next queued story for the room's channel.
|
||||
mx.SetMessageHandler(func(channel string, roomID id.RoomID, eventID id.EventID, sender id.UserID, body string) {
|
||||
if strings.TrimSpace(body) != "!post" {
|
||||
return
|
||||
}
|
||||
if !admins[sender] {
|
||||
slog.Warn("!post ignored: sender not in matrix.admins allowlist", "channel", channel, "sender", sender)
|
||||
return
|
||||
}
|
||||
slog.Info("!post requested", "channel", channel, "sender", sender)
|
||||
if queue.ForcePost(channel) {
|
||||
return
|
||||
|
||||
Reference in New Issue
Block a user