packages feed

hledger-web 1.52.2 → 1.52.3

raw patch · 7 files changed

+108/−16 lines, 7 filesdep ~aesondep ~hledgerdep ~hledger-libPVP ok

version bump matches the API change (PVP)

Dependency ranges changed: aeson, hledger, hledger-lib

API changes (from Hackage documentation)

Files

CHANGES.md view
@@ -23,6 +23,38 @@ See also the hledger changelog.  +# 1.52.3 2026-08-27++Fixes++- Another XSS (cross-site scripting) vulnerability has been fixed, in+  the add transaction form's error message. Any web page visited while+  hledger-web was running could use it to run javascript in+  hledger-web's origin, and from there read the whole journal, or+  alter it. All hledger-web users should upgrade. See also:+  GHSA-vq7r-8w52-jv84.  (Arthur Cinader, Simon Michael, [#2700])++- A newline submitted in a transaction's description, code or account+  name is no longer written into the journal file. This removes the+  possibility of the user inserting an include directive, which could+  expose system files readable by the hledger-web server. See also:+  GHSA-vq7r-8w52-jv84.  [#2704]++  Note: as with #2698 in 1.52.2, these fixes were backported from+  AI-assisted fixes in hledger 2, under the security exception in+  https://hledger.org/AI.html; they have been reviewed and tested.++- hledger-web's official binaries, and builds from the hledger source+  tree, now use aeson 2.3, avoiding a denial of service bug in that+  library. (With older aeson and /add enabled, hledger-web is+  vulnerable to HTTP requests which can trigger memory/CPU exhaustion.)+  aeson 2.3 is not yet in stackage, so hledger-web installed from+  hackage will normally still use the older aeson.+  (<https://haskell.github.io/security-advisories/advisory/HSEC-2026-0007.html>)++[#2700]: https://github.com/simonmichael/hledger/issues/2700+[#2704]: https://github.com/simonmichael/hledger/issues/2704+ # 1.52.2 2026-08-24  Fixes
Hledger/Web/Handler/AddR.hs view
@@ -11,6 +11,7 @@   ) where  import Data.Aeson.Types (Result(..))+import Data.List (intersperse) import Data.Text qualified as T import Network.HTTP.Types.Status (status400) import Text.Blaze.Html (preEscapedToHtml)@@ -22,6 +23,27 @@ import Hledger.Web.WebOptions (WebOpts(..)) import Hledger.Web.Widget.AddForm (addForm) +-- | Replace newlines with spaces in the transaction fields which are written+-- to the journal file verbatim: the description, the code, and the posting+-- account names. A newline in one of these would split the rendered entry+-- across lines, letting arbitrary journal directives (eg an include) be+-- written into the file. The journal format can't represent a newline in+-- these fields anyway - their parsers stop at end of line - and the CSV+-- reader collapses them likewise, so nothing that could round trip is lost.+-- Comments are left alone: they are rendered as one ";" line per line, so+-- newlines in them are safe.+transactionCollapseNewlines :: Transaction -> Transaction+transactionCollapseNewlines t = t+  { tdescription = collapse $ tdescription t+  , tcode        = collapse $ tcode t+  , tpostings    = map collapseacct $ tpostings t+  }+  where+    collapse = T.map (\c -> if c == '\n' || c == '\r' then ' ' else c)+    -- Account names are also normalised to single spaces, since two spaces+    -- would end the account name when the entry is read back.+    collapseacct p = p{paccount = T.unwords . T.words $ paccount p}+ getAddR :: Handler () getAddR = do   checkServerSideUiEnabled@@ -36,7 +58,7 @@   ((res, view), enctype) <- runFormPost $ addForm j today   case res of     FormSuccess (t,f) -> do-      let t' = txnTieKnot t+      let t' = txnTieKnot $ transactionCollapseNewlines t       liftIO $ do         ensureJournalFileExists f         appendToJournalFileOrStdout f (showTransaction t')@@ -44,7 +66,11 @@       redirect JournalR     FormMissing -> showForm view enctype     FormFailure errs -> do-      mapM_ (setMessage . preEscapedToHtml . T.replace "\n" "<br>") errs+      -- Escape each error, then join the lines with <br>. An unbalanced+      -- transaction's error embeds an excerpt of the submitted entry (account+      -- names, amounts), so it must be escaped; only the <br> we insert is+      -- raw. (Cf EditR, which uses toHtml.)+      mapM_ (setMessage . mconcat . intersperse (preEscapedToHtml ("<br>" :: T.Text)) . map toHtml . T.lines) errs       showForm view enctype   where     showForm view enctype =@@ -66,5 +92,5 @@   case r of     Error err -> sendStatusJSON status400 ("could not parse json: " ++ err ::String)     Success t -> do-      void $ liftIO $ journalAddTransaction j (cliopts_ opts) t+      void $ liftIO $ journalAddTransaction j (cliopts_ opts) $ transactionCollapseNewlines t       sendResponseCreated TransactionsR
Hledger/Web/Test.hs view
@@ -145,6 +145,40 @@       bodyContains "id=\"transaction-2-1\""       bodyContains "id=\"transaction-2-2\"" +  -- Submitting an unbalanced transaction produces an error message that+  -- echoes the entry (account names, amounts). Those values must be rendered+  -- as text, not raw html. Note this echo happens on the FormFailure path,+  -- which yesod does not gate with the CSRF token, so no token is sent here -+  -- the vector is reachable cross-origin.+  aj <- fmap (either error' id) . runExceptT . journalFinalise iopts "add.journal" "" =<<+          readJournal'' (T.pack $ unlines  -- PARTIAL: readJournal'' should not fail+            ["2025-01-01 opening"+            ,"    assets:bank:checking   100"+            ,"    equity:opening"])+  runTests "hledger-web add form" [("allow","add")] aj $ do++    yit "escapes submitted values in an add-form error message" $ do+      get JournalR+      statusIs 200+      -- Payloads in the two fields that reach the excerpt: the account name,+      -- and the (unvalidated) description. Distinct payloads so that escaping+      -- one field but not the other is caught. The entry parses but does not+      -- balance, so its excerpt - which includes both fields - is echoed.+      -- (Date and amount are validated and cannot carry raw html into it.)+      request $ do+        setMethod "POST"+        setUrl AddR+        addPostParam "_formid" "identify-add"+        addPostParam "date" "2025-02-02"+        addPostParam "description" "d<img src=x onerror=alert(1)>"+        addPostParam "account" "a<img src=x onerror=alert(2)>"+        addPostParam "amount" "5"+        addPostParam "account" "equity:opening"+        addPostParam "amount" "-3"+      bodyContains "d&lt;img src=x onerror=alert(1)&gt;"   -- description, escaped+      bodyContains "a&lt;img src=x onerror=alert(2)&gt;"   -- account, escaped+      bodyNotContains "<img src=x onerror"                 -- neither as raw html+   -- #2127   -- XXX I'm pretty sure this test lies, ie does not match production behaviour.   -- (test with curl -s http://localhost:5000/journal | rg '(href)="[\w/].*?"' -o )
hledger-web.1 view
@@ -1,5 +1,5 @@ -.TH "HLEDGER\-WEB" "1" "March 2026" "hledger-web-1.52.1 " "hledger User Manuals"+.TH "HLEDGER\-WEB" "1" "August 2026" "hledger-web-1.52.3 " "hledger User Manuals"   @@ -17,7 +17,7 @@ .PD \f[CR]hledger web [OPTS] [QUERY]\f[R] .SH DESCRIPTION-This manual is for hledger\(aqs web interface, version 1.52.1.+This manual is for hledger\(aqs web interface, version 1.52.3. See also the hledger manual for common concepts and file formats. .PP hledger is a robust, user\-friendly, cross\-platform set of programs for
hledger-web.cabal view
@@ -5,7 +5,7 @@ -- see: https://github.com/sol/hpack  name:           hledger-web-version:        1.52.2+version:        1.52.3 synopsis:       Web user interface for the hledger accounting system description:    A simple web user interface for the hledger accounting system,                 providing a more modern UI than the command-line or terminal interfaces.@@ -28,7 +28,7 @@ license-file:   LICENSE build-type:     Simple tested-with:-    ghc==9.6.7, ghc==9.8.4, ghc==9.10.2, ghc==9.12.2+    ghc==9.6.7, ghc==9.8.4, ghc==9.10.2, ghc==9.12.4 extra-source-files:     CHANGES.md     README.md@@ -154,10 +154,10 @@   hs-source-dirs:       ./   ghc-options: -Wall -Wno-incomplete-uni-patterns -Wno-missing-signatures -Wno-orphans -Wno-type-defaults -Wno-unused-do-bind -threaded-  cpp-options: -DVERSION="1.52.2"+  cpp-options: -DVERSION="1.52.3"   build-depends:       Decimal >=0.5.1-    , aeson >=1 && <2.3+    , aeson >=1 && <2.4     , base >=4.18 && <4.23     , base64     , blaze-html@@ -176,8 +176,8 @@     , filepath     , githash >=0.1.6.2     , hjsmin-    , hledger >=1.52.2 && <1.53-    , hledger-lib >=1.52.2 && <1.53+    , hledger >=1.52.3 && <1.53+    , hledger-lib >=1.52.3 && <1.53     , hspec     , http-client     , http-conduit@@ -222,7 +222,7 @@   hs-source-dirs:       app   ghc-options: -Wall -Wno-incomplete-uni-patterns -Wno-missing-signatures -Wno-orphans -Wno-type-defaults -Wno-unused-do-bind -threaded-  cpp-options: -DVERSION="1.52.2"+  cpp-options: -DVERSION="1.52.3"   build-depends:       base >=4.18 && <4.23     , hledger-web@@ -242,7 +242,7 @@   hs-source-dirs:       test   ghc-options: -Wall -Wno-incomplete-uni-patterns -Wno-missing-signatures -Wno-orphans -Wno-type-defaults -Wno-unused-do-bind -threaded-  cpp-options: -DVERSION="1.52.2"+  cpp-options: -DVERSION="1.52.3"   build-depends:       base >=4.18 && <4.23     , hledger-web
hledger-web.info view
@@ -18,7 +18,7 @@ or 'hledger web [OPTS] [QUERY]' -   This manual is for hledger's web interface, version 1.52.1.  See also+   This manual is for hledger's web interface, version 1.52.3.  See also the hledger manual for common concepts and file formats.     hledger is a robust, user-friendly, cross-platform set of programs
hledger-web.txt view
@@ -11,7 +11,7 @@      hledger web [OPTS] [QUERY]  DESCRIPTION-     This manual is for hledger's web interface, version 1.52.1.  See  also  the+     This manual is for hledger's web interface, version 1.52.3.  See  also  the      hledger manual for common concepts and file formats.       hledger  is  a  robust,  user-friendly,  cross-platform set of programs for@@ -470,4 +470,4 @@ SEE ALSO      hledger(1), hledger-ui(1), hledger-web(1), ledger(1) -hledger-web-1.52.1                 March 2026                     HLEDGER-WEB(1)+hledger-web-1.52.3                 August 2026                    HLEDGER-WEB(1)