Skip to content

Content Security Policy (CSP) and injecting the script tag #601

@distributedlife

Description

@distributedlife

Hi,

for reference:

  • client_side_validations 4.2.0 from git://github.com/DavyJonesLocker/client_side_validations.git (at master)
  • client_side_validations-simple_form 3.1.0 from git://github.com/DavyJonesLocker/client_side_validations-simple_form.git (at master)
  • rails 4.2.0

We're introducing CSP into our project and we are trying to remove all unsafe_inline javascript. The act of injecting script tags into the document is undesirable for CSP and we're ways we can keep using this gem whilst implementing CSP.

<script>//<![CDATA[
if(window.ClientSideValidations===undefined)window.ClientSideValidations={};window.ClientSideValidations.disabled_validators=["uniqueness"];window.ClientSideValidations.number_format={"separator":".","delimiter":","};if(window.ClientSideValidations.patterns===undefined)window.ClientSideValidations.patterns = {};window.ClientSideValidations.patterns.numericality=/^(-|\+)?(?:\d+|\d{1,3}(?:\,\d{3})+)(?:\.\d*)?$/;if(window.ClientSideValidations.forms===undefined)window.ClientSideValidations.forms={};window.ClientSideValidations.forms['edit_patient_5'] = {"type":"SimpleForm::FormBuilder","error_class":"error","error_tag":"span","wrapper_error_class":"field_with_errors","wrapper_tag":"div","wrapper_class":null,"wrapper":"genie_form","validators":{"patient[last_name]":{"presence":[{"message":"Please fill in Last name"}]},"patient[dob]":{"presence":[{"message":"Please fill in DOB"}],"timeliness":[{"message":"translation missing: en.activerecord.errors.models.patient.attributes.dob.timeliness","on_or_before":{}}]},"patient[primary_phone_number]":{"presence":[{"message":"Please fill in Contact Phone"}]}}};
//]]></script>

I can see two options and would love some feedback on alternative approaches or the relative merits of either approach. All of this is based on my (potentially flawed) understanding of how these gems work (as we're using the simple-form flavour of your client_side_validations). My understanding is that the script generate happens server-side and is injected into the document that is sent to the client. That script is then used to show validation messages, control submit buttons, etc. Each script is specific to the form.

The options:

a) Use a rake task during the 'build' step to generate javascript files that can be included in our deploy package. The script insert then references the generated js file rather than inline. A deterministic method would need to be used for the filename.

b) We are using the twitter/secureheaders gem to setup our content security policy. This gem supports generating a nonce for inline javascript. To do this we would need to be able to influence the content_tag call to add in our nonce. This could be as simple as passing an options hash that is the second parameter of content_tag.

The desired output is something like:

<script nonce="/jRAxuLJsDXAxqhNBB7gg7h55KETtDQBXe4ZL+xIXwI=">
  //yada yada yada
</script>

I think a) looks towards a longer term support for CSP while b) is a solution that has minimal impact on this gem and no backward compatibility issues for projects that don't want to implement CSP.

We're happy to fork and PR the changes but we'd like some advice on how to approach it and gotchas we may not be aware of.

Thanks

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions