diff options
author | rhenium <rhenium@rhe.jp> | 2014-10-06 08:53:22 +0900 |
---|---|---|
committer | rhenium <rhenium@rhe.jp> | 2014-10-06 08:53:22 +0900 |
commit | 5d32ae79c63074de3ab11296e4ebbe7d42f37d3b (patch) | |
tree | d697c5868f0e28efa1360da05782f5b1ef884a26 | |
parent | 3d1a4777e35618ae56a5e1e4d0d48451ed71c6d7 (diff) | |
download | aclog-5d32ae79c63074de3ab11296e4ebbe7d42f37d3b.tar.gz |
web: introduce Content Security Policy (CSP)
-rw-r--r-- | app/assets/javascripts/layouts.js.erb | 15 | ||||
-rw-r--r-- | app/assets/javascripts/tweets.js.erb (renamed from app/assets/javascripts/tweets.js) | 3 | ||||
-rw-r--r-- | app/controllers/application_controller.rb | 1 | ||||
-rw-r--r-- | app/controllers/concerns/security_headers.rb | 19 | ||||
-rw-r--r-- | app/helpers/application_helper.rb | 3 | ||||
-rw-r--r-- | app/views/layouts/_base.html.haml | 1 | ||||
-rw-r--r-- | app/views/tweets/_tweet_stats.html.haml | 4 |
7 files changed, 37 insertions, 9 deletions
diff --git a/app/assets/javascripts/layouts.js.erb b/app/assets/javascripts/layouts.js.erb index fd9b044..f7943dd 100644 --- a/app/assets/javascripts/layouts.js.erb +++ b/app/assets/javascripts/layouts.js.erb @@ -11,12 +11,15 @@ $(function() { if (previousText.length > 0) { $.getJSON("/i/user_jump_suggest.json", { head: previousText }, function(json) { + var menu = $("#user-jump-dropdown .dropdown-menu"); json.forEach(function(s) { - $("#user-jump-dropdown .dropdown-menu") - .append($("<li />").addClass("user-jump-suggestion") - .append($("<a />").attr("href", "/" + s.screen_name).attr("title", s.name + " (@" + s.screen_name + ")") - .append($("<img />").addClass("twitter-icon").attr("src", s.profile_image_url).attr("alt", "@" + s.screen_name).attr("onerror", "this.src = '<%= image_path("profile_image_missing.png") %>'")) - .append($("<span />").text("@" + s.screen_name)))); + var img = $("<img />").addClass("twitter-icon").attr("src", s.profile_image_url).attr("alt", "@" + s.screen_name); + img.on("error", function() { this.src = '<%= image_path("profile_image_missing.png") %>'; }); + + menu.append($("<li />").addClass("user-jump-suggestion") + .append($("<a />").attr("href", "/" + s.screen_name).attr("title", s.name + " (@" + s.screen_name + ")") + .append(img) + .append($("<span />").text("@" + s.screen_name)))); }); }); } @@ -26,4 +29,6 @@ $(function() { window.location = "/" + $("input", this).val(); return false; }); + + $("img.twitter-icon").on("error", function() { this.src = '<%= image_path("profile_image_missing.png") %>'; }); }); diff --git a/app/assets/javascripts/tweets.js b/app/assets/javascripts/tweets.js.erb index 25fa145..659c76b 100644 --- a/app/assets/javascripts/tweets.js +++ b/app/assets/javascripts/tweets.js.erb @@ -5,6 +5,9 @@ Application.tweets = { $(this).text(new Date($(this).attr("datetime")) .toLocaleString()); }); + $("img.twitter-icon", d).each(function() { + $(this).on("error", function() { this.src = '<%= image_path("profile_image_missing.png") %>'; }); + }); }; formatTweet($(".statuses")); diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index db1edd8..0052b01 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -1,4 +1,5 @@ class ApplicationController < ActionController::Base + include SecurityHeaders include ControllerErrorHandling if Rails.env.production? protect_from_forgery with: :exception diff --git a/app/controllers/concerns/security_headers.rb b/app/controllers/concerns/security_headers.rb new file mode 100644 index 0000000..e2d3d85 --- /dev/null +++ b/app/controllers/concerns/security_headers.rb @@ -0,0 +1,19 @@ +module SecurityHeaders + extend ActiveSupport::Concern + + included do + before_action :set_csp_header + end + + def set_csp_header + policy = { + "default-src" => "'self'", + "img-src" => "'self' https://pbs.twimg.com https://abs.twimg.com", + "style-src" => "'self' http://fonts.googleapis.com", + "font-src" => "'self' http://fonts.gstatic.com", + "frame-src" => "'self' http://platform.twitter.com" + } + policy_str = policy.map {|k, v| "#{k} #{v}" }.join("; ") + response["Content-Security-Policy"] = policy_str + end +end diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 5fe6350..ede2c51 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -19,8 +19,7 @@ module ApplicationHelper capture_haml do haml_tag("img.twitter-icon", { src: user.profile_image_url(size), - alt: "@" + user.screen_name, - onerror: "this.src = '#{image_path("profile_image_missing.png")}'" + alt: "@" + user.screen_name }.merge(options)) end end diff --git a/app/views/layouts/_base.html.haml b/app/views/layouts/_base.html.haml index 3282123..c6066f2 100644 --- a/app/views/layouts/_base.html.haml +++ b/app/views/layouts/_base.html.haml @@ -7,6 +7,7 @@ %link{rel: "apple-touch-icon-precomposed", href: image_path("apple-touch-icon-precomposed.png")} %meta{name: "msapplication-TileImage", content: image_path("tile-image.png")} %meta{name: "msapplication-TileColor", content: "#f0eadb"} + %meta{name: "twitter:widgets:csp", content: "on"} = stylesheet_link_tag "application", media: nil, "data-turbolinks-track" => true = javascript_include_tag "application", "data-turbolinks-track" => true = csrf_meta_tags diff --git a/app/views/tweets/_tweet_stats.html.haml b/app/views/tweets/_tweet_stats.html.haml index 517ba9a..5c0919d 100644 --- a/app/views/tweets/_tweet_stats.html.haml +++ b/app/views/tweets/_tweet_stats.html.haml @@ -2,7 +2,7 @@ - if tweet.favorites_count > 0 %dl %dt - %a.expand-responses-button{href: "javascript:void(0)", title: "すべて見る", data: { type: "favorites", id: tweet.id }}< + %a.expand-responses-button{href: "#", title: "すべて見る", data: { type: "favorites", id: tweet.id }}< %span>= tweet.favorites_count Favs %dd @@ -11,7 +11,7 @@ - if tweet.retweets_count > 0 %dl %dt - %a.expand-responses-button{href: "javascript:void(0)", title: "すべて見る", data: { type: "retweets", id: tweet.id }}< + %a.expand-responses-button{href: "#", title: "すべて見る", data: { type: "retweets", id: tweet.id }}< %span>= tweet.retweets_count RTs %dd |