mirror of
https://github.com/penpot/penpot.git
synced 2026-08-16 09:49:05 +00:00
* ⬆️ Update root deps * 🐛 Harden outbound HTTP requests against SSRF and restrict unauthenticated asset access - Add app.util.ssrf URL/host validator that resolves hostnames and blocks loopback, link-local, site-local, cloud metadata, and operator-supplied CIDRs - Add app.media.sanitize image EOF truncator that strips trailing data after PNG IEND, JPEG EOI, GIF trailer, and WebP RIFF markers - Disable HTTP client auto-redirect; add req-with-redirects! helper that revalidates every redirect hop against the SSRF blocklist - Wire SSRF validation and EOF sanitization into media/download-image - Validate webhook URLs and OIDC profile picture URLs against SSRF - Restrict /assets/by-id to require authentication for non-public buckets (profile) while keeping public access for file-media-object, file-object-thumbnail, team-font-variant, and file-data-fragment - Add config knobs: ssrf-protection-enabled, ssrf-allowed-hosts, ssrf-extra-blocked-cidrs Signed-off-by: Andrey Antukh <niwi@niwi.nz> --------- Signed-off-by: Andrey Antukh <niwi@niwi.nz>
92 lines
3.0 KiB
Clojure
92 lines
3.0 KiB
Clojure
;; This Source Code Form is subject to the terms of the Mozilla Public
|
|
;; License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
;;
|
|
;; Copyright (c) KALEIDOS INC
|
|
|
|
(ns app.util.nio
|
|
"NIO helpers for working with files and byte arrays.
|
|
|
|
These are thin wrappers around java.nio that provide a
|
|
Clojure-idiomatic API. Candidates for porting to datoteka."
|
|
(:import
|
|
java.nio.ByteBuffer
|
|
java.nio.channels.FileChannel
|
|
java.nio.file.Files
|
|
java.nio.file.OpenOption
|
|
java.nio.file.Path
|
|
java.nio.file.StandardOpenOption))
|
|
|
|
(set! *warn-on-reflection* true)
|
|
|
|
;; ----------------------------------------------------------------
|
|
;; File operations (via java.nio.file.Files)
|
|
;; ----------------------------------------------------------------
|
|
|
|
(defn read-bytes
|
|
"Read all bytes from a file at `path`. Returns a byte array."
|
|
^bytes [^Path path]
|
|
(Files/readAllBytes path))
|
|
|
|
(defn write-bytes
|
|
"Write `data` (byte array) to a file at `path`, replacing existing
|
|
content. Returns `path`."
|
|
[^Path path ^bytes data]
|
|
(Files/write path data ^"[Ljava.nio.file.OpenOption;" (into-array OpenOption []))
|
|
path)
|
|
|
|
(defn append-bytes
|
|
"Append `data` (byte array) to the end of the file at `path`.
|
|
Creates the file if it does not exist. Returns `path`."
|
|
[^Path path ^bytes data]
|
|
(Files/write path data
|
|
^"[Ljava.nio.file.OpenOption;"
|
|
(into-array OpenOption
|
|
[StandardOpenOption/CREATE
|
|
StandardOpenOption/APPEND]))
|
|
path)
|
|
|
|
;; ----------------------------------------------------------------
|
|
;; FileChannel operations (internal API)
|
|
;; ----------------------------------------------------------------
|
|
|
|
(def ^:private read-write-opts
|
|
(into-array OpenOption
|
|
[StandardOpenOption/READ StandardOpenOption/WRITE]))
|
|
|
|
(defn open-channel
|
|
"Open a FileChannel for read/write on the given path."
|
|
^FileChannel [^Path path]
|
|
(FileChannel/open path read-write-opts))
|
|
|
|
(defn channel-size
|
|
"Return the size of the file backed by the channel."
|
|
^long [^FileChannel channel]
|
|
(.size channel))
|
|
|
|
(defn read-at
|
|
"Read `length` bytes from `channel` starting at `position` into a
|
|
new byte array. Returns the byte array.
|
|
Loops until the ByteBuffer is fully populated to guard against OS
|
|
partial reads, which would otherwise cause BufferUnderflowException
|
|
when copying from the buffer into the result array."
|
|
^bytes [^FileChannel channel ^long position ^long length]
|
|
(let [buf (ByteBuffer/allocate (int length))]
|
|
(.position channel position)
|
|
(loop []
|
|
(when (.hasRemaining buf)
|
|
(let [n (.read channel buf)]
|
|
(when (pos? n)
|
|
(recur)))))
|
|
(.flip buf)
|
|
(let [remaining (.remaining buf)
|
|
arr (byte-array remaining)]
|
|
(.get buf arr)
|
|
arr)))
|
|
|
|
(defn truncate
|
|
"Truncate the file to the given size. Returns the channel."
|
|
[^FileChannel channel ^long size]
|
|
(.truncate channel size)
|
|
channel)
|