mirror of
https://github.com/penpot/penpot.git
synced 2026-08-06 21:08:34 +00:00
🐛 Validate font-id team ownership in create-font-variant
Prevent cross-team font injection by checking that when a font-id already has variants, they belong to the same team. This closes a BOLA gap where a user with team edit permissions could create a font variant referencing a font-id from another team. AI-assisted-by: mimo-v2.5-pro
This commit is contained in:
parent
319a2185c9
commit
20a2c5fcbf
@ -95,6 +95,18 @@
|
||||
|
||||
(declare create-font-variant)
|
||||
|
||||
(defn- check-font-team-ownership!
|
||||
"When font-id already has variants belonging to a different team,
|
||||
raises :not-found to prevent cross-team font injection."
|
||||
[conn team-id font-id]
|
||||
(let [row (db/get* conn :team-font-variant
|
||||
{:font-id font-id}
|
||||
{::db/columns [:team-id]})]
|
||||
(when (and row (not= (:team-id row) team-id))
|
||||
(ex/raise :type :not-found
|
||||
:code :object-not-found
|
||||
:hint "font does not belong to this team"))))
|
||||
|
||||
(def ^:private schema:create-font-variant
|
||||
[:and
|
||||
[:map {:title "create-font-variant"}
|
||||
@ -168,8 +180,9 @@
|
||||
[:process-font/global]]
|
||||
::webhooks/event? true
|
||||
::sm/params schema:create-font-variant}
|
||||
[{:keys [::db/pool] :as cfg} {:keys [::rpc/profile-id team-id uploads] :as params}]
|
||||
[{:keys [::db/pool] :as cfg} {:keys [::rpc/profile-id team-id font-id uploads] :as params}]
|
||||
(teams/check-edition-permissions! pool profile-id team-id)
|
||||
(check-font-team-ownership! pool team-id font-id)
|
||||
(quotes/check! cfg {::quotes/id ::quotes/font-variants-per-team
|
||||
::quotes/profile-id profile-id
|
||||
::quotes/team-id team-id})
|
||||
|
||||
@ -922,3 +922,43 @@
|
||||
:name "Valid Font Name"}
|
||||
out (th/command! params)]
|
||||
(t/is (th/success? out))))))
|
||||
|
||||
(t/deftest create-font-variant-rejects-foreign-font-id
|
||||
;; N2-07: A user with edit permissions on their own team must not be
|
||||
;; able to create a font variant using a font-id that already belongs
|
||||
;; to another team (BOLA / CWE-639).
|
||||
(with-mocks [mock {:target 'app.rpc.quotes/check! :return nil}]
|
||||
(let [prof1 (th/create-profile* 1 {:is-active true})
|
||||
prof2 (th/create-profile* 2 {:is-active true})
|
||||
team1 (:default-team-id prof1)
|
||||
team2 (:default-team-id prof2)
|
||||
font-id (uuid/custom 10 999)
|
||||
data (-> (io/resource "backend_tests/test_files/font-1.ttf")
|
||||
(io/read*))]
|
||||
|
||||
;; prof1 creates a font variant in team1 with font-id
|
||||
(let [params {::th/type :create-font-variant
|
||||
::rpc/profile-id (:id prof1)
|
||||
:team-id team1
|
||||
:font-id font-id
|
||||
:font-family "SharedFont"
|
||||
:font-weight 400
|
||||
:font-style "normal"
|
||||
:data {"font/ttf" data}}
|
||||
out (th/command! params)]
|
||||
(t/is (nil? (:error out))))
|
||||
|
||||
;; prof2 tries to create a variant using the same font-id but
|
||||
;; in team2 — must be rejected because font-id belongs to team1
|
||||
(let [params {::th/type :create-font-variant
|
||||
::rpc/profile-id (:id prof2)
|
||||
:team-id team2
|
||||
:font-id font-id
|
||||
:font-family "SharedFont"
|
||||
:font-weight 700
|
||||
:font-style "normal"
|
||||
:data {"font/ttf" data}}
|
||||
out (th/command! params)]
|
||||
(t/is (some? (:error out)))
|
||||
(t/is (= :not-found (-> out :error ex-data :type)))
|
||||
(t/is (= :object-not-found (-> out :error ex-data :code)))))))
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user