From 0a22a7458338b43b70eeaccf892156a20c890ccc Mon Sep 17 00:00:00 2001 From: Evgeny Pisemsky Date: Sun, 16 Feb 2025 11:30:00 +0300 Subject: [PATCH] Secure raw url handler --- pastebin/data.scm | 7 +++++++ pastebin/httpserver.scm | 42 ++++++++++++++++++++++------------------- 2 files changed, 30 insertions(+), 19 deletions(-) diff --git a/pastebin/data.scm b/pastebin/data.scm index 0d4924c..353108f 100644 --- a/pastebin/data.scm +++ b/pastebin/data.scm @@ -3,11 +3,13 @@ (use-modules (srfi srfi-9) (srfi srfi-1) (ice-9 ftw) + (ice-9 regex) (ice-9 textual-ports)) (export pb-entry-id + pb-entry-id-valid? pb-entry-text pb-data-open pb-data-close @@ -27,6 +29,11 @@ (id pb-entry-id set-pb-entry-id!) (text pb-entry-text set-pb-entry-text!)) +(define (pb-entry-id-valid? id) + (and (= (string-length id) 5) + (string-match "[0-9A-Za-z]{5}" id) + #t)) + ;; input: dir: string ;; output: (define (pb-data-open dir) diff --git a/pastebin/httpserver.scm b/pastebin/httpserver.scm index 5bec9b3..cae872c 100644 --- a/pastebin/httpserver.scm +++ b/pastebin/httpserver.scm @@ -108,6 +108,28 @@ (values (build-response #:code 400) (lambda (port) 1)))) +(define (raw-handler pb-data-path pb-id) + (if (pb-entry-id-valid? pb-id) + (values (build-response + #:code 200 + #:headers '((content-type . (text/plain)))) + (lambda (port) + (call-with-input-file + ;; the file name + (call-with-dir-as-pb-data + pb-data-path + (lambda (p) (pb-get-file-path p pb-id))) + ;; the input port + (lambda (inport) + (let A ((inport' inport)) + (let ((bv (get-bytevector-n inport' 4096))) + (if (not (eof-object? bv)) + (begin + (put-bytevector port bv) + (A inport'))))))))) + (values (build-response #:code 404) + (lambda (port) 1)))) + (define (make-pastebin-handler data-path) (lambda (request request-body) (match (split-and-decode-uri-path (uri-path (request-uri request))) @@ -118,25 +140,7 @@ ;; URI: /raw/ -- return raw content of the paste (("raw" pb-id) - (values (build-response - #:code 200 - #:headers '((content-type . (text/plain)))) - - (lambda (port) - (call-with-input-file - ;; the file name - (call-with-dir-as-pb-data - data-path - (lambda (p) (pb-get-file-path p pb-id))) - - ;; the input port - (lambda (inport) - (let A ((inport' inport)) - (let ((bv (get-bytevector-n inport' 4096))) - (if (not (eof-object? bv)) - (begin - (put-bytevector port bv) - (A inport')))))))))) + (raw-handler data-path pb-id)) ;; URI: * -- everything else -- show the top 5 paste list (_