From a38e12f0912df0cfd69b47cddb985a8f79cfc209 Mon Sep 17 00:00:00 2001 From: evazion Date: Fri, 17 Oct 2014 13:00:08 -0500 Subject: [PATCH] Fix XSS in source link on post show page. This vulnerability allows someone to create a source link that appears to lead to Pixiv like normal, but that actually executes Javascript code when clicked. 1) Set the source of a post to javascript:"http://img1.pixiv.net/img/xss/";alert("xss"); 2) Wait for someone to click the source link in the Information sidebar. 3) Profit. The cause is that the regexes for detecting Pixiv URLs aren't anchored to the front of the string using \A. This allows non-http:// links to be created. --- app/helpers/posts_helper.rb | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/app/helpers/posts_helper.rb b/app/helpers/posts_helper.rb index bdfcfe803..2d2e130fc 100644 --- a/app/helpers/posts_helper.rb +++ b/app/helpers/posts_helper.rb @@ -18,18 +18,21 @@ module PostsHelper end def post_source_tag(post) - if post.source =~ %r!http://img\d+\.pixiv\.net/img/([^\/]+)/! + if post.source =~ %r!\Ahttp://img\d+\.pixiv\.net/img/([^\/]+)/!i text = "pixiv/#{wordbreakify($1)}".html_safe - source_link = link_to(text, post.normalized_source) source_search = "source:pixiv/#{$1}/" - elsif post.source =~ %r!http://i\d\.pixiv\.net/img\d+/img/([^\/]+)/! + elsif post.source =~ %r!\Ahttp://i\d\.pixiv\.net/img\d+/img/([^\/]+)/!i text = "pixiv/#{wordbreakify($1)}".html_safe - source_link = link_to(text, post.normalized_source) source_search = "source:pixiv/#{$1}/" - elsif post.source =~ %r{\Ahttps?://} - text = truncate(post.normalized_source.sub(/^https?:\/\/(?:www\.)?/, "")) - source_link = link_to(truncate(text, :length => 20), post.normalized_source) + elsif post.source =~ %r{\Ahttps?://}i + text = post.normalized_source.sub(/\Ahttps?:\/\/(?:www\.)?/i, "") + text = truncate(text, length: 20) source_search = "source:#{post.source.sub(/[^\/]*$/, "")}" + end + + # Only allow http:// and https:// links. Disallow javascript: links. + if post.normalized_source =~ %r!\Ahttps?://!i + source_link = link_to(text, post.normalized_source) else source_link = truncate(post.source, :length => 100) end