host: reject malformed sx_content at write time (blog 33/33, 199 total)
Complete the malformed-post defence: instead of only degrading on read, refuse to store a post whose body won't parse, so bad content never enters the durable store in the first place. - host/blog-content-ok?: empty body is allowed, otherwise it must parse (parse-safe non-nil). - POST /new (form): missing title OR unparseable body -> 400 HTML page. - POST /posts (JSON): unparseable sx_content -> 400 "invalid sx_content". - PUT /posts/:slug (JSON): unparseable sx_content -> 400, existing post left intact. - 6 new blog tests: each write path rejects "<h1 broken)" with 400 and does not store / does not mutate. Verified live: malformed publish -> 400 + slug 404 (not stored); valid publish unaffected. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -124,6 +124,31 @@
|
||||
(dream-status (host-bl-wapp (host-bl-send "DELETE" "/posts/ghost" "Bearer good" "" "")))
|
||||
404)
|
||||
|
||||
;; -- write-time validation: malformed sx_content rejected, never stored --
|
||||
;; "%3Ch1+broken%29" decodes to "<h1 broken)" — a typo'd paren the parser rejects.
|
||||
(host-bl-test "form ingest malformed sx_content -> 400"
|
||||
(dream-status (host-bl-wapp (host-bl-send "POST" "/new" "Bearer good"
|
||||
"application/x-www-form-urlencoded"
|
||||
"title=Bad+Form&sx_content=%3Ch1+broken%29&status=published")))
|
||||
400)
|
||||
(host-bl-test "rejected form post was not stored"
|
||||
(dream-status (host-bl-wapp (host-bl-req "/bad-form/")))
|
||||
404)
|
||||
(host-bl-test "json create malformed sx_content -> 400"
|
||||
(dream-status (host-bl-wapp (host-bl-send "POST" "/posts" "Bearer good" "application/json"
|
||||
"{\"title\":\"Bad Json\",\"sx_content\":\"<h1 broken)\"}")))
|
||||
400)
|
||||
(host-bl-test "rejected json post was not stored"
|
||||
(dream-status (host-bl-wapp (host-bl-req "/bad-json/")))
|
||||
404)
|
||||
(host-bl-test "json update malformed sx_content -> 400"
|
||||
(dream-status (host-bl-wapp (host-bl-send "PUT" "/posts/my-first-post" "Bearer good"
|
||||
"application/json" "{\"sx_content\":\"<h1 broken)\"}")))
|
||||
400)
|
||||
(host-bl-test "rejected update left content intact"
|
||||
(contains? (dream-resp-body (host-bl-wapp (host-bl-req "/my-first-post/"))) "<h1>My First Post</h1>")
|
||||
true)
|
||||
|
||||
;; -- experimental unguarded create-only route (POST /new, no auth) --
|
||||
(define host-bl-oapp (host/make-app (list host/blog-open-create-routes host/blog-routes)))
|
||||
(host/blog-use-store! (persist/open))
|
||||
|
||||
Reference in New Issue
Block a user