From 04450e10866fc56890426525062fd5cdf56c4300 Mon Sep 17 00:00:00 2001 From: erdgeist Date: Fri, 17 Jul 2026 19:30:43 +0200 Subject: Allowlist aggregate order columns and template names Page.aggregate interpolated order_by into SQL unchecked while already allowlisting order_direction; the column is now normalized and checked against the sortable columns, falling back to pages.id. Its values arrive from editor-authored aggregate shortcodes, so this was editor-gated, but the asymmetry was wrong regardless. template_name and default_template_name now validate inclusion in Page.custom_templates -- names render as filesystem paths, so only names actually present in the template directory are acceptable. Validated only on change: legacy rows whose template file has since vanished stay saveable, and valid_template's render-time fallback to standard_template continues to cover them. Two tests that wrote fabricated template names through the front door now arrange their state correctly (update_column for the stale-name fallback test, a real template for the update-persists test). --- test/models/node_test.rb | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'test/models/node_test.rb') diff --git a/test/models/node_test.rb b/test/models/node_test.rb index c8e49e5..4401651 100644 --- a/test/models/node_test.rb +++ b/test/models/node_test.rb @@ -761,4 +761,13 @@ class NodeTest < ActiveSupport::TestCase assert_equal "Second", action.metadata.dig("title", "from") assert_equal "First", action.metadata.dig("title", "to") end + + test "default_template_name rejects values not present in the template directory" do + node = Node.root.children.build(:slug => "template_guard_test", + :default_template_name => "../../layouts/admin") + assert_not node.valid? + + node.default_template_name = "standard_template" + assert node.valid? + end end -- cgit v1.3