Security hardening from an attack-surface sweep of OpenBuild's own code. Fixes the exploitable items across three categories, leaving the already-defended surfaces untouched: two DoS Highs in the business-rules engine (unbounded FEEL parser/evaluator; no call-rule-set re-entry guard), a supply-chain-relevant CSRF hole on the settings controller (plus two smaller CSRF gaps), one cross-user XSS sink (the Docudesk document-template preview), and createFromTemplate DoS parity with the already-gated creation wizard.
Full enumeration lives in the change's attack-surface-map.md; rationale in design.md. The SSRF redirect fix (audit H2) was applied separately and is out of scope here.
Specs
- business-rules-engine — bound the FEEL parser/evaluator (max length, recursion depth, AST node count);
call-rule-set re-entry guard (depth + visited-slug); evaluate-payload size bound.
- settings-and-observability — enforce CSRF on
settings#create, settings#load, and preferences#setPreference.
- openbuild-template-catalogue —
createFromTemplate gains the creation wizard's rate limit + authorization gate.
- docudesk-document-templates — sanitize the document-template preview before render (DOMPurify).
- app-icon-management — sanitize author-supplied SVG before preview and persistence (DOMPurify SVG profile).
Branch
Work on this branch — do NOT start work on development and do NOT create a different branch.
- Base branch:
development
- Feature branch:
feature/1/harden-xss-dos-csrf
Before starting:
git fetch origin
git checkout feature/1/harden-xss-dos-csrf 2>/dev/null || \
git checkout -b feature/1/harden-xss-dos-csrf origin/development
Tasks
0. SSRF (audit H2) — folded in
1. DoS — bound the rule-evaluation stack
2. DoS — createFromTemplate parity
3. CSRF — remove unjustified NoCSRFRequired
4. XSS — sanitize the sinks
5. Wrap-up
Security hardening from an attack-surface sweep of OpenBuild's own code. Fixes the exploitable items across three categories, leaving the already-defended surfaces untouched: two DoS Highs in the business-rules engine (unbounded FEEL parser/evaluator; no
call-rule-setre-entry guard), a supply-chain-relevant CSRF hole on the settings controller (plus two smaller CSRF gaps), one cross-user XSS sink (the Docudesk document-template preview), andcreateFromTemplateDoS parity with the already-gated creation wizard.Full enumeration lives in the change's
attack-surface-map.md; rationale indesign.md. The SSRF redirect fix (audit H2) was applied separately and is out of scope here.Specs
call-rule-setre-entry guard (depth + visited-slug); evaluate-payload size bound.settings#create,settings#load, andpreferences#setPreference.createFromTemplategains the creation wizard's rate limit + authorization gate.Branch
Work on this branch — do NOT start work on
developmentand do NOT create a different branch.developmentfeature/1/harden-xss-dos-csrfBefore starting:
Tasks
0. SSRF (audit H2) — folded in
RemoteTemplateStoreService::fetch,allow_redirects => false)testFetchDisablesRedirectFollowing1. DoS — bound the rule-evaluation stack
FeelParser::parse)ExpressionEvaluator::evaluate)call-rule-setre-entry guard (depth + visited-slug,RuleEngineService::evaluate)RulesController::evaluate)call-rule-setrefusedRuleExecutionLogwrite2. DoS — createFromTemplate parity
#[UserRateLimit]+ wizard authorization gate (ApplicationsController::createFromTemplate)3. CSRF — remove unjustified NoCSRFRequired
#[NoCSRFRequired]fromSettingsController::createand::load@NoCSRFRequireddocblock fromPreferencesController::setPreference(keep@NoAdminRequired)4. XSS — sanitize the sinks
dompurifydependency (pin; confirm SBOM/CI picks it up)previewContentinDocumentTemplateAttachmentDialog.vue(full HTML profile)iconCatalogues.js::resolveAppIcon(SVG profile)<script>/onerrorneutralized; benign markup/SVG preserved5. Wrap-up
OpenSpec changeslist + statusin-progress)