From 80a0af8c9f287b4909d3f899c9b60405231bd058 Mon Sep 17 00:00:00 2001 From: zmagod Date: Thu, 11 May 2017 11:36:47 +0200 Subject: [PATCH] replace all ActionController::Base.helpers.sanitize calls with custom sanitize_input method [fixes SCI-1241] --- .../users/invitations_controller.rb | 4 +- app/helpers/application_helper.rb | 24 +- app/helpers/input_sanitize_helper.rb | 13 +- app/helpers/notifications_helper.rb | 6 +- app/models/activity.rb | 15 +- config/initializers/constants.rb | 635 ++++++++++++++++++ 6 files changed, 666 insertions(+), 31 deletions(-) diff --git a/app/controllers/users/invitations_controller.rb b/app/controllers/users/invitations_controller.rb index bac1b5707..b9a7cee5f 100644 --- a/app/controllers/users/invitations_controller.rb +++ b/app/controllers/users/invitations_controller.rb @@ -175,8 +175,8 @@ module Users message = "#{I18n.t('search.index.team')} #{team.name}" notification = Notification.create( type_of: :assignment, - title: ActionController::Base.helpers.sanitize(title), - message: ActionController::Base.helpers.sanitize(message) + title: InputSanitizeHelper.sanitize_inpute(title), + message: InputSanitizeHelper.sanitize_input(message) ) if target_user.assignments_notification diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index cf037686a..0e10f8071 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -92,10 +92,8 @@ module ApplicationHelper def generate_annotation_notification(target_user, title, message) notification = Notification.create( type_of: :assignment, - title: - ActionController::Base.helpers.sanitize(title), - message: - ActionController::Base.helpers.sanitize(message) + title: sanitize_input(title), + message: sanitize_input(message) ) if target_user.assignments_notification UserNotification.create(notification: notification, user: target_user) @@ -122,11 +120,13 @@ module ApplicationHelper project = Project.find_by_id(match[3].base62_decode) next unless project if project.archived? - "#{sanitize(match[2])} " \ + "" \ + "#{sanitize_input(match[2])} " \ "#{link_to project.name, projects_archive_path} #{I18n.t('atwho.res.archived')}" else - "#{sanitize(match[2])} " \ + "" \ + "#{sanitize_input(match[2])} " \ "#{link_to project.name, project_path(project)}" end @@ -134,12 +134,14 @@ module ApplicationHelper experiment = Experiment.find_by_id(match[3].base62_decode) next unless experiment if experiment.archived? - "#{sanitize(match[2])} " \ + "" \ + "#{sanitize_input(match[2])} " \ "#{link_to experiment.name, experiment_archive_project_path(experiment.project)} " \ "#{I18n.t('atwho.res.archived')}" else - "#{sanitize(match[2])} " \ + ""\ + "#{sanitize_input(match[2])} " \ "#{link_to experiment.name, canvas_experiment_path(experiment)}" end @@ -147,12 +149,14 @@ module ApplicationHelper my_module = MyModule.find_by_id(match[3].base62_decode) next unless my_module if my_module.archived? - "#{sanitize(match[2])} " \ + "" \ + "#{sanitize_input(match[2])} " \ "#{link_to my_module.name, module_archive_experiment_path(my_module.experiment)} " \ "#{I18n.t('atwho.res.archived')}" else - "#{sanitize(match[2])} " \ + "" \ + "#{sanitize_input(match[2])} " \ "#{link_to my_module.name, protocols_my_module_path(my_module)}" end diff --git a/app/helpers/input_sanitize_helper.rb b/app/helpers/input_sanitize_helper.rb index 6b038e3ec..b8ba5b5d6 100644 --- a/app/helpers/input_sanitize_helper.rb +++ b/app/helpers/input_sanitize_helper.rb @@ -5,12 +5,13 @@ module InputSanitizeHelper # the ActiveRecord connecton method on the caller object which in # our cases throws an error when called from not ActiveRecord objects # such as SamplesDatatables - def sanitize_input(text, tags = [], attributes = []) + def sanitize_input(html, tags = [], attributes = []) Sanitize.fragment( - text, + html, elements: Constants::WHITELISTED_TAGS + tags, - attributes: { all: Constants::WHITELISTED_ATTRIBUTES + attributes } - ) + attributes: { all: Constants::WHITELISTED_ATTRIBUTES + attributes }, + css: Constants::WHITELISTED_CSS_ATTRIBUTES + ).html_safe end def escape_input(text) @@ -22,9 +23,9 @@ module InputSanitizeHelper team = options.fetch(:team) { nil } wrapper_tag = options.fetch(:wrapper_tag) { {} } tags = options.fetch(:tags) { [] } - fromat_opt = wrapper_tag.merge(sanitize: false) + format_opt = wrapper_tag.merge(sanitize: false) text = sanitize_input(text, tags) - text = simple_format(sanitize_input(text), {}, fromat_opt) if simple_f + text = simple_format(sanitize_input(text), {}, format_opt) if simple_f auto_link( smart_annotation_parser(text, team), link: :urls, diff --git a/app/helpers/notifications_helper.rb b/app/helpers/notifications_helper.rb index e21066a54..f41eb90ac 100644 --- a/app/helpers/notifications_helper.rb +++ b/app/helpers/notifications_helper.rb @@ -40,10 +40,8 @@ module NotificationsHelper notification = Notification.create( type_of: :assignment, - title: - ActionController::Base.helpers.sanitize(title), - message: - ActionController::Base.helpers.sanitize(message) + title: sanitize_input(title), + message: sanitize_input(message) ) if target_user.assignments_notification diff --git a/app/models/activity.rb b/app/models/activity.rb index 47541a78f..e0768d43f 100644 --- a/app/models/activity.rb +++ b/app/models/activity.rb @@ -104,15 +104,12 @@ class Activity < ActiveRecord::Base notification = Notification.create( type_of: notification_type, - title: - ActionController::Base.helpers.sanitize(message, tags: %w(strong a)), - message: - ActionController::Base - .helpers.sanitize( - "#{I18n.t('search.index.project')} - #{project_m} #{experiment_m} #{task_m}", - tags: %w(strong a) - ), + title: InputSanitizeHelper.sanitize_input(message, tags: %w(strong a)), + message: InputSanitizeHelper.sanitize_input( + "#{I18n.t('search.index.project')} + #{project_m} #{experiment_m} #{task_m}", + tags: %w(strong a) + ), generator_user_id: user.id ) diff --git a/config/initializers/constants.rb b/config/initializers/constants.rb index 3b48409e1..c91632ac8 100644 --- a/config/initializers/constants.rb +++ b/config/initializers/constants.rb @@ -222,8 +222,643 @@ class Constants WHITELISTED_ATTRIBUTES = %w( href src width height alt cite datetime title class name xml:lang abbr style + target data-* ).freeze + WHITELISTED_CSS_ATTRIBUTES = { + allow_comments: false, + allow_hacks: false, + at_rules_with_properties: %w[ + bottom-center bottom-left bottom-left-corner bottom-right + bottom-right-corner font-face left-bottom left-middle left-top page + right-bottom right-middle right-top top-center top-left + top-left-corner top-right top-right-corner + ], + at_rules_with_styles: %w[ + -moz-keyframes -o-keyframes -webkit-keyframes document + keyframes media supports + ], + protocols: ['http', 'https', :relative], + properties: %w[ + -moz-appearance + -moz-background-inline-policy + -moz-box-sizing + -moz-column-count + -moz-column-fill + -moz-column-gap + -moz-column-rule + -moz-column-rule-color + -moz-column-rule-style + -moz-column-rule-width + -moz-column-width + -moz-font-feature-settings + -moz-font-language-override + -moz-hyphens + -moz-text-align-last + -moz-text-decoration-color + -moz-text-decoration-line + -moz-text-decoration-style + -moz-text-size-adjust + -ms-background-position-x + -ms-background-position-y + -ms-block-progression + -ms-content-zoom-chaining + -ms-content-zoom-limit + -ms-content-zoom-limit-max + -ms-content-zoom-limit-min + -ms-content-zoom-snap + -ms-content-zoom-snap-points + -ms-content-zoom-snap-type + -ms-content-zooming + -ms-filter + -ms-flex + -ms-flex-align + -ms-flex-direction + -ms-flex-order + -ms-flex-pack + -ms-flex-wrap + -ms-flow-from + -ms-flow-into + -ms-grid-column + -ms-grid-column-align + -ms-grid-column-span + -ms-grid-columns + -ms-grid-row + -ms-grid-row-align + -ms-grid-row-span + -ms-grid-rows + -ms-high-contrast-adjust + -ms-hyphenate-limit-chars + -ms-hyphenate-limit-lines + -ms-hyphenate-limit-zone + -ms-hyphens + -ms-ime-mode + -ms-interpolation-mode + -ms-layout-flow + -ms-layout-grid + -ms-layout-grid-char + -ms-layout-grid-line + -ms-layout-grid-mode + -ms-layout-grid-type + -ms-overflow-style + -ms-overflow-x + -ms-overflow-y + -ms-progress-appearance + -ms-scroll-chaining + -ms-scroll-limit + -ms-scroll-limit-x-max + -ms-scroll-limit-x-min + -ms-scroll-limit-y-max + -ms-scroll-limit-y-min + -ms-scroll-rails + -ms-scroll-snap-points-x + -ms-scroll-snap-points-y + -ms-scroll-snap-type + -ms-scroll-snap-x + -ms-scroll-snap-y + -ms-scroll-translation + -ms-scrollbar-arrow-color + -ms-scrollbar-base-color + -ms-scrollbar-darkshadow-color + -ms-scrollbar-face-color + -ms-scrollbar-highlight-color + -ms-scrollbar-shadow-color + -ms-scrollbar-track-color + -ms-text-align-last + -ms-text-autospace + -ms-text-justify + -ms-text-kashida-space + -ms-text-overflow + -ms-text-size-adjust + -ms-text-underline-position + -ms-touch-action + -ms-user-select + -ms-word-break + -ms-word-wrap + -ms-wrap-flow + -ms-wrap-margin + -ms-wrap-through + -ms-writing-mode + -ms-zoom + -webkit-align-content + -webkit-align-items + -webkit-align-self + -webkit-animation + -webkit-animation-delay + -webkit-animation-direction + -webkit-animation-duration + -webkit-animation-fill-mode + -webkit-animation-iteration-count + -webkit-animation-name + -webkit-animation-play-state + -webkit-animation-timing-function + -webkit-appearance + -webkit-backface-visibility + -webkit-background-blend-mode + -webkit-background-clip + -webkit-background-composite + -webkit-background-origin + -webkit-background-size + -webkit-blend-mode + -webkit-border-after + -webkit-border-after-color + -webkit-border-after-style + -webkit-border-after-width + -webkit-border-before + -webkit-border-before-color + -webkit-border-before-style + -webkit-border-before-width + -webkit-border-bottom-left-radius + -webkit-border-bottom-right-radius + -webkit-border-end + -webkit-border-end-color + -webkit-border-end-style + -webkit-border-end-width + -webkit-border-fit + -webkit-border-image + -webkit-border-radius + -webkit-border-start + -webkit-border-start-color + -webkit-border-start-style + -webkit-border-start-width + -webkit-border-top-left-radius + -webkit-border-top-right-radius + -webkit-box-align + -webkit-box-decoration-break + -webkit-box-flex + -webkit-box-flex-group + -webkit-box-lines + -webkit-box-ordinal-group + -webkit-box-orient + -webkit-box-pack + -webkit-box-reflect + -webkit-box-shadow + -webkit-box-sizing + -webkit-clip-path + -webkit-column-axis + -webkit-column-break-after + -webkit-column-break-before + -webkit-column-break-inside + -webkit-column-count + -webkit-column-gap + -webkit-column-progression + -webkit-column-rule + -webkit-column-rule-color + -webkit-column-rule-style + -webkit-column-rule-width + -webkit-column-span + -webkit-column-width + -webkit-columns + -webkit-filter + -webkit-flex + -webkit-flex-basis + -webkit-flex-direction + -webkit-flex-flow + -webkit-flex-grow + -webkit-flex-shrink + -webkit-flex-wrap + -webkit-flow-from + -webkit-flow-into + -webkit-font-size-delta + -webkit-font-smoothing + -webkit-grid-area + -webkit-grid-auto-columns + -webkit-grid-auto-flow + -webkit-grid-auto-rows + -webkit-grid-column + -webkit-grid-column-end + -webkit-grid-column-start + -webkit-grid-definition-columns + -webkit-grid-definition-rows + -webkit-grid-row + -webkit-grid-row-end + -webkit-grid-row-start + -webkit-justify-content + -webkit-line-clamp + -webkit-logical-height + -webkit-logical-width + -webkit-margin-after + -webkit-margin-after-collapse + -webkit-margin-before + -webkit-margin-before-collapse + -webkit-margin-bottom-collapse + -webkit-margin-collapse + -webkit-margin-end + -webkit-margin-start + -webkit-margin-top-collapse + -webkit-marquee + -webkit-marquee-direction + -webkit-marquee-increment + -webkit-marquee-repetition + -webkit-marquee-speed + -webkit-marquee-style + -webkit-mask + -webkit-mask-box-image + -webkit-mask-box-image-outset + -webkit-mask-box-image-repeat + -webkit-mask-box-image-slice + -webkit-mask-box-image-source + -webkit-mask-box-image-width + -webkit-mask-clip + -webkit-mask-composite + -webkit-mask-image + -webkit-mask-origin + -webkit-mask-position + -webkit-mask-position-x + -webkit-mask-position-y + -webkit-mask-repeat + -webkit-mask-repeat-x + -webkit-mask-repeat-y + -webkit-mask-size + -webkit-mask-source-type + -webkit-max-logical-height + -webkit-max-logical-width + -webkit-min-logical-height + -webkit-min-logical-width + -webkit-opacity + -webkit-order + -webkit-padding-after + -webkit-padding-before + -webkit-padding-end + -webkit-padding-start + -webkit-perspective + -webkit-perspective-origin + -webkit-perspective-origin-x + -webkit-perspective-origin-y + -webkit-region-break-after + -webkit-region-break-before + -webkit-region-break-inside + -webkit-region-fragment + -webkit-shape-inside + -webkit-shape-margin + -webkit-shape-outside + -webkit-shape-padding + -webkit-svg-shadow + -webkit-tap-highlight-color + -webkit-text-decoration + -webkit-text-decoration-color + -webkit-text-decoration-line + -webkit-text-decoration-style + -webkit-text-size-adjust + -webkit-touch-callout + -webkit-transform + -webkit-transform-origin + -webkit-transform-origin-x + -webkit-transform-origin-y + -webkit-transform-origin-z + -webkit-transform-style + -webkit-transition + -webkit-transition-delay + -webkit-transition-duration + -webkit-transition-property + -webkit-transition-timing-function + -webkit-user-drag + -webkit-wrap-flow + -webkit-wrap-through + align-content + align-items + align-self + alignment-adjust + alignment-baseline + all + anchor-point + animation + animation-delay + animation-direction + animation-duration + animation-fill-mode + animation-iteration-count + animation-name + animation-play-state + animation-timing-function + azimuth + backface-visibility + background + background-attachment + background-clip + background-color + background-image + background-origin + background-position + background-repeat + background-size + baseline-shift + binding + bleed + bookmark-label + bookmark-level + bookmark-state + border + border-bottom + border-bottom-color + border-bottom-left-radius + border-bottom-right-radius + border-bottom-style + border-bottom-width + border-collapse + border-color + border-image + border-image-outset + border-image-repeat + border-image-slice + border-image-source + border-image-width + border-left + border-left-color + border-left-style + border-left-width + border-radius + border-right + border-right-color + border-right-style + border-right-width + border-spacing + border-style + border-top + border-top-color + border-top-left-radius + border-top-right-radius + border-top-style + border-top-width + border-width + bottom + box-decoration-break + box-shadow + box-sizing + box-snap + box-suppress + break-after + break-before + break-inside + caption-side + chains + clear + clip + clip-path + clip-rule + color + color-interpolation-filters + column-count + column-fill + column-gap + column-rule + column-rule-color + column-rule-style + column-rule-width + column-span + column-width + columns + contain + content + counter-increment + counter-reset + counter-set + crop + cue + cue-after + cue-before + cursor + direction + display + display-inside + display-list + display-outside + dominant-baseline + elevation + empty-cells + filter + flex + flex-basis + flex-direction + flex-flow + flex-grow + flex-shrink + flex-wrap + float + float-offset + flood-color + flood-opacity + flow-from + flow-into + font + font-family + font-feature-settings + font-kerning + font-language-override + font-size + font-size-adjust + font-stretch + font-style + font-synthesis + font-variant + font-variant-alternates + font-variant-caps + font-variant-east-asian + font-variant-ligatures + font-variant-numeric + font-variant-position + font-weight + grid + grid-area + grid-auto-columns + grid-auto-flow + grid-auto-rows + grid-column + grid-column-end + grid-column-start + grid-row + grid-row-end + grid-row-start + grid-template + grid-template-areas + grid-template-columns + grid-template-rows + hanging-punctuation + height + hyphens + icon + image-orientation + image-rendering + image-resolution + ime-mode + initial-letters + inline-box-align + justify-content + justify-items + justify-self + left + letter-spacing + lighting-color + line-box-contain + line-break + line-grid + line-height + line-snap + line-stacking + line-stacking-ruby + line-stacking-shift + line-stacking-strategy + list-style + list-style-image + list-style-position + list-style-type + margin + margin-bottom + margin-left + margin-right + margin-top + marker-offset + marker-side + marks + mask + mask-box + mask-box-outset + mask-box-repeat + mask-box-slice + mask-box-source + mask-box-width + mask-clip + mask-image + mask-origin + mask-position + mask-repeat + mask-size + mask-source-type + mask-type + max-height + max-lines + max-width + min-height + min-width + move-to + nav-down + nav-index + nav-left + nav-right + nav-up + object-fit + object-position + opacity + order + orphans + outline + outline-color + outline-offset + outline-style + outline-width + overflow + overflow-wrap + overflow-x + overflow-y + padding + padding-bottom + padding-left + padding-right + padding-top + page + page-break-after + page-break-before + page-break-inside + page-policy + pause + pause-after + pause-before + perspective + perspective-origin + pitch + pitch-range + play-during + position + presentation-level + quotes + region-fragment + resize + rest + rest-after + rest-before + richness + right + rotation + rotation-point + ruby-align + ruby-merge + ruby-position + shape-image-threshold + shape-margin + shape-outside + size + speak + speak-as + speak-header + speak-numeral + speak-punctuation + speech-rate + stress + string-set + tab-size + table-layout + text-align + text-align-last + text-combine-horizontal + text-combine-upright + text-decoration + text-decoration-color + text-decoration-line + text-decoration-skip + text-decoration-style + text-emphasis + text-emphasis-color + text-emphasis-position + text-emphasis-style + text-height + text-indent + text-justify + text-orientation + text-overflow + text-rendering + text-shadow + text-size-adjust + text-space-collapse + text-transform + text-underline-position + text-wrap + top + touch-action + transform + transform-origin + transform-style + transition + transition-delay + transition-duration + transition-property + transition-timing-function + unicode-bidi + unicode-range + vertical-align + visibility + voice-balance + voice-duration + voice-family + voice-pitch + voice-range + voice-rate + voice-stress + voice-volume + volume + white-space + widows + width + will-change + word-break + word-spacing + word-wrap + wrap-flow + wrap-through + writing-mode + z-index + ] + }.freeze + EXPORTABLE_ZIP_EXPIRATION_DAYS = 7 # Very basic regex to check for validity of emails