forked from technoweenie/mephisto
-
Notifications
You must be signed in to change notification settings - Fork 18
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Security: Fix XSS attack against new comment form
WARNING: If you're one of the first people testing this commit, please use a backup database. How to reproduce: Create a new comment, and set all fields to <script>alert("Pwned")</script>. Submit it. You will see a JavaScript alert dialog, which is bad. What's happening: Untrusted fields in Comment objects are sanitized immediately before they're written to the database for the first time. But if validation fails, it leaves the application with an unsanitized comment object. When the "can't submit comment" error is displayed, this unsanitized comment object can be passed straight throught to Liquid, which assumes that all HTML tags have been escaped. (This may look like "self XSS" attack only, but hostile pages can trigger it by tricking you into submitting a comment form back to your own site, preloaded with malicious data.) How we fix it: We make HTML escaping the responsibility of CommentDrop, not the Comment model. This means that we need to unescape several existing fields in the database. Possible issues: This means that we're storing dangerous, untrusted data in our database, and that we need to rely on the proper use of 'h' and 'CGI.escapeHTML'. In the case of 'h', we're already using SafeERB, so insecure admin templates will be caught automatically, and dangerous data should never be sent to the user. In the case of Liquid, we need to carefully examine our CommentDrop class to make sure that we're not passing any unescaped data through to the Liquid templates. But this is a pretty manageable "proof obligation"--and remember that the old "sanitize on create" code actually suffered from XSS attacks, because it was too easy to do the sanitization in the wrong place.
- Loading branch information
Showing
5 changed files
with
55 additions
and
19 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
# We were storing these fields in the database "pre-escaped", which (oddly | ||
# enough) actually increased the number of security problems in our | ||
# application, because we didn't escape the fields until after the record | ||
# was validated, so error pages tended to vulnerable to XSS attacks. So | ||
# let's just rely on SafeERB and our CommentDrop to make sure we escape on | ||
# output. | ||
class UnescapeCommentFields < ActiveRecord::Migration | ||
class Content < ActiveRecord::Base | ||
end | ||
|
||
class Comment < Content | ||
end | ||
|
||
# Taken from the old sanitize_attributes method in Content. | ||
ATTRIBUTES = | ||
[:author, :author_url, :author_email, :author_ip, :user_agent, :referrer] | ||
|
||
def self.up | ||
Comment.find(:all).each do |c| | ||
ATTRIBUTES.each do |a| | ||
c.send("#{a}=", CGI::unescapeHTML(c.send(a).to_s)) if c.send(a) | ||
end | ||
c.save! | ||
end | ||
end | ||
|
||
def self.down | ||
Comment.find(:all).each do |c| | ||
ATTRIBUTES.each do |a| | ||
c.send("#{a}=", CGI::escapeHTML(c.send(a).to_s)) if c.send(a) | ||
end | ||
c.save! | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
b7cb822
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To undo the migration in this patch, run:
rake db:migrate:down VERSION=20081219130711