Skip to content

Security hardening#1

Open
Michm0TheH00d wants to merge 6 commits into
Wasabules:mainfrom
Michm0TheH00d:security-hardening
Open

Security hardening#1
Michm0TheH00d wants to merge 6 commits into
Wasabules:mainfrom
Michm0TheH00d:security-hardening

Conversation

@Michm0TheH00d

Copy link
Copy Markdown

Summary

Type of change

  • Bug fix
  • New feature
  • Refactoring
  • Documentation

Checklist

  • go vet ./... passes
  • go test -race ./... passes
  • svelte-check --fail-on-warnings passes
  • New i18n keys added to all locale files (if applicable)

Security Hardening added 6 commits July 8, 2026 19:11
Syslog fields are attacker-controlled network input. Values beginning
with '=', '+', '-' or '@' are interpreted as formulas by Excel and
LibreOffice when the exported CSV is opened, enabling data exfiltration
or command execution via DDE on the analyst's workstation.

Neutralize hostname, app name, proc id and message fields by prefixing
a single quote when they start with a formula trigger character,
including triggers smuggled behind leading tab/CR characters.
Timestamp, severity/facility labels and protocol are app-generated;
source IP comes from the network stack, so these remain untouched.
The previous lexicographic comparison would report "1.10.0" as older
than "1.9.0", so the update check would silently stop working once a
double-digit version component is released. Compare components as
integers, falling back to string comparison only for non-numeric
components such as pre-release suffixes.
…ompares

DisableEncryption skipped password verification entirely when the
in-memory session password was empty — the state after an app restart
with a still-locked encrypted database. Any caller could then flip the
encryption flag off and desynchronize config state from the encrypted
on-disk database. Now, disabling (or changing the password) while
encryption is enabled requires a prior successful unlock, and the
password checks use crypto/subtle constant-time comparison.
Previously all three listeners (UDP, TCP, TLS) bound unconditionally to
all interfaces. On multi-homed hosts — e.g. an engineering laptop
attached to both an office network and a control-system network — this
exposes the syslog service on networks it was never meant to face.

Add an optional BindAddress to ServerConfig, validated as an IP
literal, and use net.JoinHostPort so IPv6 addresses work. Empty keeps
the previous listen-on-all behavior. Exposed in the server controls UI
with translations for all supported locales.
Each accepted connection spawns a handler goroutine with a 64 KiB scan
buffer and no upper bound, so a connection-flooding client could bind
unbounded memory and goroutines. Introduce a semaphore (512 slots shared
by TCP and TLS) acquired non-blockingly on accept; connections beyond
the limit are closed immediately and logged. Handlers release into the
semaphore instance they were admitted under, so a server restart cannot
cause cross-instance releases.
Any host on the local segment could deliver messages, trigger alert
rules, and flood the retention window with junk that displaces real
events. Add an optional allowlist of IP literals and CIDR ranges,
validated in ValidateServerConfig and compiled once at server start.
UDP datagrams from non-allowed sources are dropped; TCP/TLS connections
are closed on accept before consuming a connection slot.

An empty list preserves the previous allow-all behavior. The UI hint
documents explicitly that UDP source addresses are spoofable, so the
allowlist is network hygiene rather than authentication — mutual TLS
remains the mechanism for authenticated senders.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant