• docs/v322_new.md src/sbbs3/websrvr.cpp

    From Rob Swindell (on Debian Linux)@1:103/705 to Git commit to main/sbbs/master on Fri Jul 31 21:43:31 2026
    https://gitlab.synchro.net/main/sbbs/-/commit/72303693ef1b8dc2c11ff006
    Modified Files:
    docs/v322_new.md src/sbbs3/websrvr.cpp
    Log Message:
    websrvr: enforce download credits for unauthenticated file requests

    An anonymous request through the file-area virtual path
    (FileVPathPrefix) was authorized by user_can_download() alone, with no
    credit check, so every file in a directory with empty ARS downloaded
    free of charge regardless of its cost. The FTP server applies the
    credit gate to anonymous users, and issue #446 was closed with that
    being the intended policy.

    Both authorization paths now share check_file_download(), which applies
    the credit gate before the ARS check. Putting the two callers on one
    predicate is the point of the helper: the bypass existed because the
    anonymous branch and the authenticated one had drifted apart.

    The gate measures cost against user_available_credits() rather than
    user.cdt, so a user's free credits now count toward a download, as they
    already do on the Terminal and FTP servers, and as subtract_cdt()
    already assumed when charging: it spends free credits first.

    A refused anonymous request is logged at LOG_DEBUG. An insufficient
    credit refusal now reports NotEnoughCredits; both this and the existing authenticated failure log previously reported CantDownloadFromDir for
    it, naming the wrong cause.

    Fixes #1192

    Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
    --- SBBSecho 3.37-Linux
    * Origin: Vertrauen - [vert/cvs/bbs].synchro.net (1:103/705)
  • From Rob Swindell (on Debian Linux)@1:103/705 to Git commit to main/sbbs/master on Wed Sep 30 19:08:47 2026
    https://gitlab.synchro.net/main/sbbs/-/commit/aadcf82e0660f29d0b7afc10
    Modified Files:
    docs/v322_new.md src/sbbs3/websrvr.cpp
    Log Message:
    Web Server: log script errors, don't send them to the client

    Fixes #1203

    js_ErrorReporter() wrote every uncaught JavaScript error, with the script's absolute path and line number, into the HTTP response body as well as the
    log, and the request still completed with a 200 and the page's content
    type. That disclosed the server's layout to any visitor who could make a
    script throw, and any error message that interpolated request data (a query parameter, header or cookie) was a reflected script-injection vector in the BBS's own origin.

    Log the error only. A reported error (a warning does not count, nor does exit(), which reports nothing) marks the session, and exec_ssjs() then
    fails the request instead of sending what the script produced before
    failing, so the normal 500 error path answers it. An error after the
    script has already sent its headers can only be logged, as before.

    Verified on a scratch web server: a page that throws with a query
    parameter in the message returns 500 with an empty body and the error is
    in the log; a page that ends with exit() still returns 200.

    Co-Authored-By: Claude Fable 5.1 <[email protected]>
    --- SBBSecho 3.38-Linux
    * Origin: Vertrauen - [vert/cvs/bbs].synchro.net (1:103/705)