My client asked more editing features for a form field, like making text bold, italic, etc …
So I’m thinking about implementing an html-editor for a Rails form field.
Does anyone have experience with this, and which html-editor do you recommend?
Thanks for your help,
Hi @acandael_acanda, if I’m understanding your question, your client needs to be able to submit HTML to you through a form. There are a few good HTML editors available. Basecamp uses wysihtml5. I am using Ace right now, which has been packaged for Rails in this gem: https://github.com/codykrieger/ace-rails-ap.
If you are going to be displaying back the client’s submitted input (particularly if anyone who isn’t the original submitter can look at HTML that a user created), you need to be very concerned about script injection. I’m sure other folks here might have some useful ideas, but at a bare minimum I would use loofah and loofah-activerecord to enforce some santization against XSS attacks.
Your worst case scenario here is that a user submits malicious input containing an XSS attack, and then an administrator views the page and gets their account hijacked, so make sure you are scrubbing user input.
Hope this helps.
Hi Geoff, thanks for the advice. The form will only be edited by admin users, so I don’t think script injection is a big concern, unless of course someone would hack an admin account.
The application is for a university research-group
The form field where I want to implement a html-editor is called ‘reference’ and is a reference to a scientific publication. Because the reference needs to adhere to scientific reference notiation (title needs to be italic etc …) the client asked me for html-editing functionality. The form looks like this:
<%= form_for [:admin, @publication] do |f| %>
<%= f.label :title %>
<%= f.text_field :title %>
<%= f.label :reference %>
<%= f.text_area :reference %>
<%= f.label :research_project %>
<%= f.collection_select :research_project_id, ResearchProject.all, :id, :title, prompt: true %>
<% if @publication.new_record? %>
<%= f.submit "Add Publication" %>
<% else %>
<%= f.submit "Update Publication" %>
<% end %>
<%= link_to 'Cancel', admin_publications_path %>
<% end %>
After some investigation, I decided to use the Froala Editor . It’s an editor based jQuery and Font-Awesome. It was really easy to setup, thanks to the wysiwyg-rails gem . It was literaly implemented in 5 minutes.
To implement the editor on my form-field, I just needed to include this jQuery:
// Set custom buttons with separator between them. Also include the name
// of the buttons defined in customButtons.
buttons: ['bold', 'italic']
The only thing I have to figure out right now is to make the html tags that where inserted by the editor, get interpreted on the page, and not literaly printed as is the case right now.
Is there a way to make Rails encode the html and not literally print it out?
that was too easy
<p><%= raw @publication.reference %></p>
So Geoff, if I use the Loofa Gem, how would I sanitize my :reference textarea form field?
Thanks for your help,
Loofah::Scrubber: GitHub - flavorjones/loofah: HTML/XML manipulation and sanitization based on Nokogiri
This is one of the few scenarios where a model
before_save callback is warranted, since you never want to save un-sanitized input. I would write a test where you attempt to save
reference with HTML that includes a
<script> tag, then confirm it didn’t get saved intact. Loofah does much more complicated scrubbing than this, but that simple test will confirm that Loofah is interacting with and scrubbing your field.
Aaaand right on schedule, Rails 4.2 is going to include Loofah for out of the box HTML santization:
Thanks Geof for the information, but what’s not fully clear to me is how to use the scrub! method on a form input field. Should I apply the scrub! method somehow on the form input field itself in the View, or should should I implement it in the Controller and parse the input from the params hash? As you see, not fully clear to me yet
I’d use the scrubbing in your model as a
before_save callback, since you will never want to save a model without sanitized HTML.
I installed the loofah gem. I couldn’t install the loofah-activerecord gem, it doesn’t seem too work for Rails 4 applications.
In my Publication model, I defined a before_save callback:
and I defined this private method on my Publication model:
class Publication < ActiveRecord::Base
I wrote a integration test:
scenario 'admin should not be able to add publication with script input' do
fill_in 'Title', with: "new publication"
fill_in 'Reference', with: "<script>alert('hello there');</script>"
click_button 'Add Publication'
expect((Publication.last).reference).not_to eq("<script>alert('hello there');</script>")
But when I run this test I get a failure:
1) Admin interacts with publications admin should not be able to add publication with script input
Failure/Error: expect((Publication.last).reference).not_to eq("<script>alert('hello there');</script>")
expected: value != "<script>alert('hello there');</script>"
got: "<script>alert('hello there');</script>"
(compared using ==)
# ./spec/features/admin_handles_publications_spec.rb:48:in `block (2 levels) in <top (required)>'
Finished in 0.68114 seconds
1 example, 1 failure
rspec ./spec/features/admin_handles_publications_spec.rb:43 # Admin interacts with publications admin should not be able to add publication with script input
I’m not sure if I’m implementing the scrub method the right way in my model. Not quite sure how I should pass it the reference fragment
Not absolutely sure what’s wrong here, but I think in your test you should be ensuring that you’re looking consistently at escaped/unescaped values.