The before_save callback only gets called if, when the programmer calls save, there are no validation errors!
But, let's suppose there is a validation error with some other random field. Then the input doesn't get sanitized, and now the unsanitized value -- which potentially contains malicious JavaScript? code -- remains in memory in the model when the controller action is loaded.
Now on a typical form in Rails, the form is populated with the values from the models, which would include any invalid values (values that didn't pass the validations for their respective attributes), giving the user the opportunity to correct their mistakes and submit the form again.
Uh oh! That means the value they just submitted will be included in the source of the page (as the value of the HTML input field, most likely a text box) that is dynamically generated for the user.
Sounds to me like a recipe for a "type 1" or "reflected" cross-site scripting attack!
If unvalidated user-supplied data is included in the resulting page without HTML encoding, this will allow client-side code to be injected into the dynamic page.
Here is a patch which I think should fix this :-)
--- /home/tyler/code/examples/validation/vendor/plugins/acts_as_sanitized/lib/acts_as_sanitized.rb (revision 3064)
+++ /home/tyler/code/examples/validation/vendor/plugins/acts_as_sanitized/lib/acts_as_sanitized.rb (working copy..@@ -7,7 +7,7 @@
module ClassMethods
def acts_as_sanitized(options = {})
- before_save :sanitize_fields
+ before_validation :sanitize_fields
write_inheritable_attribute(:acts_as_sanitized_options, {
:fields => options[:fields],
I believe this makes one less susceptible to type-1 XSS attacks now, instead of preventing only type-1 XSS attacks.
Am I missing anything?