lib/chartkick/helper.rb in chartkick-3.3.2 vs lib/chartkick/helper.rb in chartkick-3.4.0
- old
+ new
@@ -39,12 +39,12 @@
def chartkick_chart(klass, data_source, **options)
@chartkick_chart_id ||= 0
options = chartkick_deep_merge(Chartkick.options, options)
element_id = options.delete(:id) || "chart-#{@chartkick_chart_id += 1}"
- height = options.delete(:height) || "300px"
- width = options.delete(:width) || "100%"
+ height = (options.delete(:height) || "300px").to_s
+ width = (options.delete(:width) || "100%").to_s
defer = !!options.delete(:defer)
# content_for: nil must override default
content_for = options.key?(:content_for) ? options.delete(:content_for) : Chartkick.content_for
nonce = options.delete(:nonce)
@@ -61,17 +61,30 @@
end
nonce_html = nonce ? " nonce=\"#{ERB::Util.html_escape(nonce)}\"" : nil
# html vars
html_vars = {
- id: element_id,
- height: height,
- width: width
+ id: element_id
}
html_vars.each_key do |k|
html_vars[k] = ERB::Util.html_escape(html_vars[k])
end
- html = (options.delete(:html) || %(<div id="%{id}" style="height: %{height}; width: %{width}; text-align: center; color: #999; line-height: %{height}; font-size: 14px; font-family: 'Lucida Grande', 'Lucida Sans Unicode', Verdana, Arial, Helvetica, sans-serif;">Loading...</div>)) % html_vars
+
+ # css vars
+ css_vars = {
+ height: height,
+ width: width
+ }
+ css_vars.each_key do |k|
+ # limit to alphanumeric and % for simplicity
+ # this prevents things like calc() but safety is the priority
+ raise ArgumentError, "Invalid #{k}" unless css_vars[k] =~ /\A[a-zA-Z0-9%]*\z/
+ # we limit above, but escape for safety as fail-safe
+ # to prevent XSS injection in worse-case scenario
+ css_vars[k] = ERB::Util.html_escape(css_vars[k])
+ end
+
+ html = (options.delete(:html) || %(<div id="%{id}" style="height: %{height}; width: %{width}; text-align: center; color: #999; line-height: %{height}; font-size: 14px; font-family: 'Lucida Grande', 'Lucida Sans Unicode', Verdana, Arial, Helvetica, sans-serif;">Loading...</div>)) % html_vars.merge(css_vars)
# js vars
js_vars = {
type: klass.to_json,
id: element_id.to_json,