Class: Vangrail::Rails::Markup
- Inherits:
-
Vangrail::Rail
- Object
- Vangrail::Rail
- Vangrail::Rails::Markup
- Defined in:
- lib/vangrail/rails/markup.rb
Overview
Removes markup that does something when the answer is rendered.
An answer is text until a client renders it, and most clients render markdown by pulling in a library that passes raw HTML straight through. At that point a script tag in the answer is a script tag in the page, and the model wrote it because a retrieved document told it to. That is a cross-site scripting bug with a language model in the middle of it, and the fact that the model is the delivery mechanism does not make it a different class of bug.
The application's own sanitiser is the real defence and this does not replace it. What this covers is the case where there is no sanitiser, which is most of them, and where the answer is passed to a renderer that was chosen for how its tables look.
Removes rather than blocks. An answer with a script tag in it is an answer with one bad span, the same as an answer with a credential in it.
Not on by default. A desk whose client renders markdown as text, or which escapes before rendering, does not need it, and a rail that strips markup nobody was going to execute is noise in the result.
Constant Summary collapse
- PATTERNS =
{ # Executes on load. 'script' => /<script\b[^>]*>.*?<\/script>|<script\b[^>]*\/?>/mi, # Loads and executes something else. 'frame' => /<(?:iframe|frame|embed|object|applet)\b[^>]*>(?:.*?<\/(?:iframe|frame|embed|object|applet)>)?/mi, # Runs on an event, which is how a lone img tag becomes an exploit. 'event_handler' => /\son[a-z]{3,20}\s*=\s*(?:"[^"]*"|'[^']*'|[^\s>]+)/i, # A scheme that executes rather than fetches. 'active_scheme' => /(?:javascript|vbscript|data)\s*:\s*[^\s"'<>)]+/i, # Rewrites where a form or a link goes, or what the page loads next. 'meta_refresh' => /<meta\b[^>]*http-equiv\s*=\s*["']?refresh["']?[^>]*>/i, 'base_tag' => /<base\b[^>]*>/i, 'form' => /<form\b[^>]*>.*?<\/form>|<form\b[^>]*>/mi, # Styling can position an invisible overlay over the page. 'style_block' => /<style\b[^>]*>.*?<\/style>/mi }.freeze
Constants inherited from Vangrail::Rail
Vangrail::Rail::DEFAULT_SIDES, Vangrail::Rail::SIDES
Instance Attribute Summary collapse
-
#patterns ⇒ Object
readonly
Returns the value of attribute patterns.
Attributes inherited from Vangrail::Rail
Instance Method Summary collapse
- #cache_key(text, _context) ⇒ Object
- #call(text, _context) ⇒ Object
-
#initialize(patterns: PATTERNS, name: 'markup', sides: [:output]) ⇒ Markup
constructor
A new instance of Markup.
- #offline? ⇒ Boolean
Methods inherited from Vangrail::Rail
#applies_to?, #placeholder?, #to_s
Constructor Details
Instance Attribute Details
#patterns ⇒ Object (readonly)
Returns the value of attribute patterns.
46 47 48 |
# File 'lib/vangrail/rails/markup.rb', line 46 def patterns @patterns end |
Instance Method Details
#cache_key(text, _context) ⇒ Object
57 58 59 |
# File 'lib/vangrail/rails/markup.rb', line 57 def cache_key(text, _context) text end |
#call(text, _context) ⇒ Object
61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
# File 'lib/vangrail/rails/markup.rb', line 61 def call(text, _context) body = text.to_s found = [] cleaned = patterns.reduce(body) do |acc, (label, pattern)| acc.gsub(pattern) do found << label '' end end return pass if found.empty? modify(cleaned, categories: found.uniq, reason: "removed #{found.uniq.join(', ')} from the answer") end |
#offline? ⇒ Boolean
53 54 55 |
# File 'lib/vangrail/rails/markup.rb', line 53 def offline? true end |