Compare commits

..

3 Commits

Author SHA1 Message Date
Glenn Thompson 9042e78ae8 Merge branch 'main' into glenneth/cl-streamer-standalone 2026-04-07 09:14:44 +01:00
Brian O'Reilly b3790bcb25 fix: prevent debugger accumulation from vulnerability scanner probes
Bogus requests (e.g. /wp-login.php, /.env) from external scanners were
signalling FILE-TO-SERVE-DOES-NOT-EXIST and REQUEST-NOT-FOUND conditions
that dropped into the debugger when Swank/Slynk was connected. Enough
accumulated sessions would lock up the runtime.

Three defence-in-depth changes:
- Static file handler now probe-files before calling serve-file
- start-server reads ASTEROID_DEBUG env var to set radiance:*debugger*
- Override radiance:render-error-page for proper 404/403/500 responses

🅯 Brian O'Reilly <fade@deepsky.com>, 2026
2026-04-06 12:25:41 -04:00
Brian O'Reilly 0a2ac0c409 docker port maps leak to external interface...
Unless they are explicitly bound to loopback, which I thought was the
default, but it is not. likely related to the interface between
bridges and ip tables in the Linux kernel, but anyhow, get literal
about the portmap interface address to prevent exposing the database
to the entire internet. With thanks to the friendly heads up email
from the German Federal Republic via Hetzner.
2026-03-13 17:21:22 -04:00
2 changed files with 51 additions and 8 deletions

View File

@ -1055,8 +1055,11 @@
;; Serve regular static file
(t
(serve-file (merge-pathnames (format nil "static/~a" path)
(asdf:system-source-directory :asteroid))))))
(let ((file-path (merge-pathnames (format nil "static/~a" path)
(asdf:system-source-directory :asteroid))))
(if (probe-file file-path)
(serve-file file-path)
(error 'radiance:request-not-found))))))
;; Status check functions
(defun check-stream-status ()
@ -1491,14 +1494,30 @@
;; RADIANCE server management functions
(defun start-server (&key (port *server-port*))
"Start the Asteroid Radio RADIANCE server"
"Start the Asteroid Radio RADIANCE server.
Reads ASTEROID_DEBUG from the environment to control Radiance's debugger policy:
nil (or unset) - never invoke debugger (production default)
if-swank-connected - invoke only when Swank/Slynk is connected
t - always invoke debugger"
(format t "Starting Asteroid Radio RADIANCE server on port ~a~%" port)
(compile-styles) ; Generate CSS file using LASS
;; Ensure RADIANCE environment is properly set before startup
;; (unless (radiance:environment)
;; (setf (radiance:environment) "asteroid"))
;; Set debugger policy from environment to prevent stray conditions from
;; accumulating debugger sessions (e.g. vulnerability scanners hitting bogus paths)
(let ((debug-env (uiop:getenv "ASTEROID_DEBUG")))
(setf radiance:*debugger*
(cond
((or (null debug-env)
(string-equal debug-env "nil")
(string-equal debug-env ""))
nil)
((string-equal debug-env "t")
t)
((string-equal debug-env "if-swank-connected")
:if-swank-connected)
(t nil)))
(format t "Debugger policy: ~a~%" radiance:*debugger*))
(radiance:startup)
;; Start listener statistics polling

View File

@ -202,3 +202,27 @@
(error 'authorization-error
:message message
:required-role required-role))
;;; Override Radiance's default render-error-page to return proper HTTP
;;; status codes instead of a blanket 500 for conditions like
;;; request-not-found and file-to-serve-does-not-exist. This prevents
;;; vulnerability scanners from generating misleading 500 responses and
;;; gives us control over error presentation.
(defun radiance:render-error-page (condition)
(cond
((typep condition 'radiance:request-not-found)
(setf (radiance:return-code radiance:*response*) 404)
(setf (radiance:content-type radiance:*response*) "text/plain")
"Not Found")
((typep condition 'radiance:file-to-serve-does-not-exist)
(setf (radiance:return-code radiance:*response*) 404)
(setf (radiance:content-type radiance:*response*) "text/plain")
"Not Found")
((typep condition 'radiance:request-denied)
(setf (radiance:return-code radiance:*response*) 403)
(setf (radiance:content-type radiance:*response*) "text/plain")
"Forbidden")
(t
(setf (radiance:return-code radiance:*response*) 500)
(setf (radiance:content-type radiance:*response*) "text/plain")
"Internal Server Error")))