From 9f58989703644b10870e358298645ba1d10b953d Mon Sep 17 00:00:00 2001 From: Nick Colley Date: Tue, 31 Jul 2018 17:02:40 +0100 Subject: [PATCH] Add guidance for how to pass HTML to components To see what led to this decision see: - [an incident involving multiple components](https://github.com/alphagov/govuk_publishing_components/pull/305) - [a potential vulnerability with the govspeak component](https://github.com/alphagov/govuk_publishing_components/pull/356). --- docs/component_conventions.md | 70 +++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/docs/component_conventions.md b/docs/component_conventions.md index 5465ce9247..55033ee5eb 100644 --- a/docs/component_conventions.md +++ b/docs/component_conventions.md @@ -201,3 +201,73 @@ Code can be called and referred to in the template as follows: <%= card_helper.heading_tag %> ``` + +## Passing HTML to a component +We try avoid the risk of Cross Site Scripting (XSS) attacks, we can make sure to only sanitise HTML when the component is used, rather than doing so on the application's behalf. + +This means avoiding use of 'raw' or 'html_safe' within a component's view. + +There are a few methods to achieve this: + +### Single slots for nested children + +Similar to HTML, there may be a clear slot where nested children should appear in a component. + +For a panel component, you may expect anything nested within it to appear +at the bottom of the component. + +Do not: + +```erb +<%= render 'panel', content: "Your reference number
HDJ2123F" %> +``` + +Do: + +```erb +<%= render 'panel' do %> + Your reference number +
+ HDJ2123F +<% end %> +``` + +### Multiple slots + +If you have multiple slots where HTML may go, you could consider passing them as arguments. + +Note: If you can avoid a requirement for HTML this may be better. In the following example you may consider +title: { level: 1, text: 'Application complete' }. + +Do not: + +```erb +<%= render 'panel', { title: '

Application complete

' } do %> + Your reference number +
+ HDJ2123F +<% end %> +``` + +Do: + +```erb +<% panelTitle = capture do %> +

Application complete

+<% end %> +<%= render 'panel', { title: panelTitle } do %> + Your reference number +
+ HDJ2123F +<% end %> +``` + +or (if the data is passed from a presenter / controller) + +```erb +<%= render 'panel', { title: presentedPanelTitle.html_safe } do %> + Your reference number +
+ HDJ2123F +<% end %> +```