Don’t load sanitize-html in the browser
This approach solves the same xss vulnerability, but by doing it a way we can guarantee that what we are trying to .html() onto the page is safe (and not just arbitrary user content) instead of having to load the _huge_ sanitize-html npm package and all of it’s deps (like postcss, source-map, htmlparser2, buffer, and a bunch of others) On the frontend so we can use it to sanitize all the untrusted data-mathml content. closes: CORE-2748 refs COMMS-1846 Test Plan: * Go to the calendar, click on a day to add an event, and click on the "More Options" button. * Switch to the html editor, and add the following: <img class='equation_image' data-mathml='<img src=x onerror=prompt(document.cookie); />'> * Save the event. Go back to the calendar and click on the newly saved event, and notice that you don't get XSS'd * Create another event in the calendar, and this time add the following via the html editor: <img class="equation_image" title="(-\infty,\infty)" src="/equation_images/(-%255Cinfty%252C%255Cinfty)" alt="Infinities: (-\infty,\infty)" data-equation-content="(-\infty,\infty)" /> * Save the event, and load it in the calendar. Notice that it still properly displays this mathml image properly. * Test the same calendar event with a screen reader, and notice that it is still accessible Change-Id: I5fc1e17ecfc8576dfeaffacff8efcb08873bdd5e Reviewed-on: https://gerrit.instructure.com/188609 Tested-by: Jenkins Reviewed-by: Landon Gilbert-Bland <lbland@instructure.com> QA-Review: Landon Gilbert-Bland <lbland@instructure.com> Product-Review: Ryan Shaw <ryan@instructure.com>
This commit is contained in:
parent
eac5a15d71
commit
e28bb762a9
|
@ -19,46 +19,17 @@ import $ from 'jquery'
|
||||||
import _ from 'underscore'
|
import _ from 'underscore'
|
||||||
import htmlEscape from 'str/htmlEscape'
|
import htmlEscape from 'str/htmlEscape'
|
||||||
import I18n from 'i18n!user_content'
|
import I18n from 'i18n!user_content'
|
||||||
import mathMLTagNames from 'mathml-tag-names'
|
|
||||||
import sanitizeHtml from 'sanitize-html'
|
|
||||||
|
|
||||||
// From https://developer.mozilla.org/en-US/docs/Web/MathML/Attribute
|
|
||||||
const MATHML_ATTRIBUTES = [
|
|
||||||
'accent', 'accentunder', 'actiontype', 'align', 'alignmentscope', 'altimg', 'altimg-width',
|
|
||||||
'altimg-height', 'altimg-valign', 'alttext', 'bevelled', 'charalign', 'close', 'columnalign',
|
|
||||||
'columnlines', 'columnspacing', 'columnspan', 'columnwidth', 'crossout', 'decimalpoint',
|
|
||||||
'denomalign', 'depth', 'dir', 'display', 'displaystyle', 'edge', 'equalcolumns', 'equalrows',
|
|
||||||
'fence', 'form', 'frame', 'framespacing', 'groupalign', 'height', 'id', 'indentalign',
|
|
||||||
'indentalignfirst', 'indentalignlast', 'indentshift', 'indentshiftfirst', 'indentshiftlast',
|
|
||||||
'indenttarget', 'infixlinebreakstyle', 'largeop', 'length', 'linebreak', 'linebreakmultchar',
|
|
||||||
'linebreakstyle', 'lineleading', 'linethickness', 'location', 'longdivstyle', 'lspace',
|
|
||||||
'lquote', 'mathbackground', 'mathcolor', 'mathsize', 'mathvariant', 'maxsize', 'minlabelspacing',
|
|
||||||
'minsize', 'movablelimits', 'notation', 'numalign', 'open', 'overflow', 'position', 'rowalign',
|
|
||||||
'rowlines', 'rowspacing', 'rowspan', 'rspace', 'rquote', 'scriptlevel', 'scriptminsize',
|
|
||||||
'Starting', 'scriptsizemultiplier', 'selection', 'separator', 'separators', 'shift', 'side',
|
|
||||||
'src', 'stackalign', 'stretchy', 'subscriptshift', 'supscriptshift', 'symmetric', 'voffset',
|
|
||||||
'width', 'xmlns'
|
|
||||||
]
|
|
||||||
|
|
||||||
function sanitizeMathmlHtml(html) {
|
|
||||||
const opts = {
|
|
||||||
allowedTags: mathMLTagNames,
|
|
||||||
allowedAttributes: {
|
|
||||||
'*': MATHML_ATTRIBUTES
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return sanitizeHtml(html, opts)
|
|
||||||
}
|
|
||||||
|
|
||||||
const apiUserContent = {
|
const apiUserContent = {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
xsslint safeString.identifier mathml
|
xsslint safeString.identifier mathml
|
||||||
xsslint safeString.identifier sanitized
|
|
||||||
*/
|
*/
|
||||||
translateMathmlForScreenreaders ($equationImage) {
|
translateMathmlForScreenreaders ($equationImage) {
|
||||||
const sanitized = sanitizeMathmlHtml($equationImage.data('mathml'))
|
// note, it is safe to treat the x-canvaslms-safe-mathml as html because it
|
||||||
const mathml = $('<div/>').html(sanitized).html()
|
// only ever gets put there by us (in Api::Html::Content::apply_mathml).
|
||||||
|
// Any user content that gets sent to the server will have the
|
||||||
|
// x-canvaslms-safe-mathml attribute stripped out.
|
||||||
|
const mathml = $('<div/>').html($equationImage.attr('x-canvaslms-safe-mathml')).html()
|
||||||
const mathmlSpan = $('<span class="hidden-readable"></span>')
|
const mathmlSpan = $('<span class="hidden-readable"></span>')
|
||||||
mathmlSpan.html(mathml)
|
mathmlSpan.html(mathml)
|
||||||
return mathmlSpan
|
return mathmlSpan
|
||||||
|
@ -148,7 +119,7 @@ const apiUserContent = {
|
||||||
$dummy.find('img.equation_image').each((index, equationImage) => {
|
$dummy.find('img.equation_image').each((index, equationImage) => {
|
||||||
const $equationImage = $(equationImage)
|
const $equationImage = $(equationImage)
|
||||||
const mathmlSpan = apiUserContent.translateMathmlForScreenreaders($equationImage)
|
const mathmlSpan = apiUserContent.translateMathmlForScreenreaders($equationImage)
|
||||||
$equationImage.removeAttr('data-mathml')
|
$equationImage.removeAttr('x-canvaslms-safe-mathml')
|
||||||
$equationImage.after(mathmlSpan)
|
$equationImage.after(mathmlSpan)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -168,7 +168,12 @@ module Api
|
||||||
mathml = UserContent.latex_to_mathml(equation)
|
mathml = UserContent.latex_to_mathml(equation)
|
||||||
return if mathml.blank?
|
return if mathml.blank?
|
||||||
|
|
||||||
node['data-mathml'] = mathml
|
# NOTE: we use "x-canvaslms-safe-mathml" instead of just "data-mathml"
|
||||||
|
# because canvas_sanitize will strip it out on the way in but it won't
|
||||||
|
# strip out data-mathml. This means we can gaurentee that there is never
|
||||||
|
# user input in x-canvaslms-safe-mathml and we can safely pass it to
|
||||||
|
# $el.html() in translateMathmlForScreenreaders in the js in the frontend
|
||||||
|
node['x-canvaslms-safe-mathml'] = mathml
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -81,7 +81,6 @@
|
||||||
"jquery.elastic": "1.0.0",
|
"jquery.elastic": "1.0.0",
|
||||||
"location-origin": "^1.1.4",
|
"location-origin": "^1.1.4",
|
||||||
"lodash": "^4.16.4",
|
"lodash": "^4.16.4",
|
||||||
"mathml-tag-names": "^2.1.0",
|
|
||||||
"md5": "^2.2.1",
|
"md5": "^2.2.1",
|
||||||
"mediaelement": "https://github.com/instructure/mediaelement.git#master",
|
"mediaelement": "https://github.com/instructure/mediaelement.git#master",
|
||||||
"moment": "^2.10.6",
|
"moment": "^2.10.6",
|
||||||
|
@ -106,7 +105,6 @@
|
||||||
"redux": "^4.0.1",
|
"redux": "^4.0.1",
|
||||||
"redux-actions": "^2.6.4",
|
"redux-actions": "^2.6.4",
|
||||||
"redux-thunk": "^2.3.0",
|
"redux-thunk": "^2.3.0",
|
||||||
"sanitize-html": "^1.20.0",
|
|
||||||
"spin.js": "2.3.2",
|
"spin.js": "2.3.2",
|
||||||
"swfobject": "^2.2.1",
|
"swfobject": "^2.2.1",
|
||||||
"tablesorter": "^2.28.5",
|
"tablesorter": "^2.28.5",
|
||||||
|
|
|
@ -31,9 +31,9 @@ describe Api::Html::Content, type: :request do
|
||||||
expect(@node['alt']).to eql(@latex)
|
expect(@node['alt']).to eql(@latex)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "sets data-mathml" do
|
it "sets x-canvaslms-safe-mathml" do
|
||||||
Api::Html::Content.apply_mathml(@node)
|
Api::Html::Content.apply_mathml(@node)
|
||||||
expect(@node['data-mathml']).to eql(Ritex::Parser.new.parse(@latex))
|
expect(@node['x-canvaslms-safe-mathml']).to eql(Ritex::Parser.new.parse(@latex))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -52,9 +52,9 @@ describe Api::Html::Content, type: :request do
|
||||||
expect(@node['alt']).to eql(@latex)
|
expect(@node['alt']).to eql(@latex)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "doesn't set data-mathml" do
|
it "doesn't set x-canvaslms-safe-mathml" do
|
||||||
Api::Html::Content.apply_mathml(@node)
|
Api::Html::Content.apply_mathml(@node)
|
||||||
expect(@node['data-mathml']).to be_nil
|
expect(@node['x-canvaslms-safe-mathml']).to be_nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -23,8 +23,8 @@ let mathml_html
|
||||||
QUnit.module('apiUserContent.convert', {
|
QUnit.module('apiUserContent.convert', {
|
||||||
setup() {
|
setup() {
|
||||||
mathml_html ="<div><ul>\n" +
|
mathml_html ="<div><ul>\n" +
|
||||||
"<li><img class=\"equation_image\" data-mathml=\"<math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"><mi>i</mi><mi>n</mi><mi>t</mi><mi>f</mi><mo stretchy='false'>(</mo><mi>x</mi><mo stretchy='false'>)</mo><mo>/</mo><mi>g</mi><mo stretchy='false'>(</mo><mi>x</mi><mo stretchy='false'>)</mo></math>\"></li>\n" +
|
"<li><img class=\"equation_image\" x-canvaslms-safe-mathml=\"<math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"><mi>i</mi><mi>n</mi><mi>t</mi><mi>f</mi><mo stretchy='false'>(</mo><mi>x</mi><mo stretchy='false'>)</mo><mo>/</mo><mi>g</mi><mo stretchy='false'>(</mo><mi>x</mi><mo stretchy='false'>)</mo></math>\"></li>\n" +
|
||||||
"<li><img class=\"equation_image\" data-mathml='<math xmlns=\"http://www.w3.org/1998/Math/MathML\" display=\"inline\"><mo lspace=\"thinmathspace\" rspace=\"thinmathspace\">&Sum;</mo><mn>1</mn><mo>.</mo><mo>.</mo><mi>n</mi></math>'></li>\n" +
|
"<li><img class=\"equation_image\" x-canvaslms-safe-mathml='<math xmlns=\"http://www.w3.org/1998/Math/MathML\" display=\"inline\"><mo lspace=\"thinmathspace\" rspace=\"thinmathspace\">&Sum;</mo><mn>1</mn><mo>.</mo><mo>.</mo><mi>n</mi></math>'></li>\n" +
|
||||||
"<li><img class=\"nothing_special\"></li>\n"+
|
"<li><img class=\"nothing_special\"></li>\n"+
|
||||||
"</ul></div>"
|
"</ul></div>"
|
||||||
}
|
}
|
||||||
|
@ -35,12 +35,6 @@ test('moves mathml into a screenreader element', () => {
|
||||||
ok(output.includes('<span class="hidden-readable"><math '))
|
ok(output.includes('<span class="hidden-readable"><math '))
|
||||||
})
|
})
|
||||||
|
|
||||||
test('prevents XSS on data-mathml content', () => {
|
|
||||||
const xss_mathml = "<img class='equation_image' data-mathml='<img src=x onerror=prompt(document.cookie); />'>"
|
|
||||||
const output = apiUserContent.convert(xss_mathml)
|
|
||||||
ok(!output.includes('onerror'))
|
|
||||||
})
|
|
||||||
|
|
||||||
test('mathml need not be screenreadered if editing content (this would start an update loop)', () => {
|
test('mathml need not be screenreadered if editing content (this would start an update loop)', () => {
|
||||||
const output = apiUserContent.convert(mathml_html, {forEditing: true})
|
const output = apiUserContent.convert(mathml_html, {forEditing: true})
|
||||||
ok(!output.includes('<span class="hidden-readable"><math '))
|
ok(!output.includes('<span class="hidden-readable"><math '))
|
||||||
|
|
|
@ -82,8 +82,8 @@ module Api
|
||||||
url_helper = double(rewrite_api_urls: nil)
|
url_helper = double(rewrite_api_urls: nil)
|
||||||
html = Content.new(string).rewritten_html(url_helper)
|
html = Content.new(string).rewritten_html(url_helper)
|
||||||
expected = "<div><ul>\n"\
|
expected = "<div><ul>\n"\
|
||||||
"<li><img class=\"equation_image\" data-equation-content=\"\int f(x)/g(x)\" data-mathml=\"<math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"><mi>i</mi><mi>n</mi><mi>t</mi><mi>f</mi><mo stretchy='false'>(</mo><mi>x</mi><mo stretchy='false'>)</mo><mo>/</mo><mi>g</mi><mo stretchy='false'>(</mo><mi>x</mi><mo stretchy='false'>)</mo></math>\"></li>\n"\
|
"<li><img class=\"equation_image\" data-equation-content=\"\int f(x)/g(x)\" x-canvaslms-safe-mathml=\"<math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"><mi>i</mi><mi>n</mi><mi>t</mi><mi>f</mi><mo stretchy='false'>(</mo><mi>x</mi><mo stretchy='false'>)</mo><mo>/</mo><mi>g</mi><mo stretchy='false'>(</mo><mi>x</mi><mo stretchy='false'>)</mo></math>\"></li>\n"\
|
||||||
"<li><img class=\"equation_image\" data-equation-content=\"\\sum 1..n\" data-mathml='<math xmlns=\"http://www.w3.org/1998/Math/MathML\" display=\"inline\"><mo lspace=\"thinmathspace\" rspace=\"thinmathspace\">&Sum;</mo><mn>1</mn><mo>.</mo><mo>.</mo><mi>n</mi></math>'></li>\n"\
|
"<li><img class=\"equation_image\" data-equation-content=\"\\sum 1..n\" x-canvaslms-safe-mathml='<math xmlns=\"http://www.w3.org/1998/Math/MathML\" display=\"inline\"><mo lspace=\"thinmathspace\" rspace=\"thinmathspace\">&Sum;</mo><mn>1</mn><mo>.</mo><mo>.</mo><mi>n</mi></math>'></li>\n"\
|
||||||
"<li><img class=\"nothing_special\"></li>\n</ul></div>"
|
"<li><img class=\"nothing_special\"></li>\n</ul></div>"
|
||||||
expect(html).to eq(expected)
|
expect(html).to eq(expected)
|
||||||
end
|
end
|
||||||
|
|
|
@ -541,7 +541,7 @@ equation: <img class="equation_image" title="Log_216" src="/equation_images/Log_
|
||||||
qtext = <<-HTML.strip
|
qtext = <<-HTML.strip
|
||||||
equation: <p>
|
equation: <p>
|
||||||
<img class="equation_image" title="\\sum" src="/equation_images/%255Csum"
|
<img class="equation_image" title="\\sum" src="/equation_images/%255Csum"
|
||||||
alt="LaTeX: \\sum" data-equation-content="\\sum" data-mathml="<math xmlns="http://www.w3.org/1998/Math/MathML">
|
alt="LaTeX: \\sum" data-equation-content="\\sum" x-canvaslms-safe-mathml="<math xmlns="http://www.w3.org/1998/Math/MathML">
|
||||||
<mo>&#x2211;<!-- ∑ --></mo></math>" />
|
<mo>&#x2211;<!-- ∑ --></mo></math>" />
|
||||||
</p>
|
</p>
|
||||||
HTML
|
HTML
|
||||||
|
@ -559,7 +559,7 @@ equation: <img class="equation_image" title="Log_216" src="/equation_images/Log_
|
||||||
|
|
||||||
it "should do more terrible equation stuff" do
|
it "should do more terrible equation stuff" do
|
||||||
qtext = <<-HTML.strip
|
qtext = <<-HTML.strip
|
||||||
hmm: <p><img class="equation_image"
|
hmm: <p><img class="equation_image"
|
||||||
data-equation-content="h\\left( x \\right) = \\left\\{ {\\begin{array}{*{20}{c}}
|
data-equation-content="h\\left( x \\right) = \\left\\{ {\\begin{array}{*{20}{c}}
|
||||||
{{x^2} + 4x - 1}&{{\\rm{for}}}&{ - 7 \\le x \\le - 1}\\\\
|
{{x^2} + 4x - 1}&{{\\rm{for}}}&{ - 7 \\le x \\le - 1}\\\\
|
||||||
{ - 3x + p}&{{\\rm{for}}}&{ - 1 < x \\le 6}
|
{ - 3x + p}&{{\\rm{for}}}&{ - 1 < x \\le 6}
|
||||||
|
|
40
yarn.lock
40
yarn.lock
|
@ -11102,7 +11102,7 @@ lodash.camelcase@^4.3.0:
|
||||||
resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6"
|
resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6"
|
||||||
integrity sha1-soqmKIorn8ZRA1x3EfZathkDMaY=
|
integrity sha1-soqmKIorn8ZRA1x3EfZathkDMaY=
|
||||||
|
|
||||||
lodash.clonedeep@^4.3.2, lodash.clonedeep@^4.5.0:
|
lodash.clonedeep@^4.3.2:
|
||||||
version "4.5.0"
|
version "4.5.0"
|
||||||
resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef"
|
resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef"
|
||||||
integrity sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=
|
integrity sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=
|
||||||
|
@ -11129,11 +11129,6 @@ lodash.escape@^4.0.1:
|
||||||
resolved "https://registry.yarnpkg.com/lodash.escape/-/lodash.escape-4.0.1.tgz#c9044690c21e04294beaa517712fded1fa88de98"
|
resolved "https://registry.yarnpkg.com/lodash.escape/-/lodash.escape-4.0.1.tgz#c9044690c21e04294beaa517712fded1fa88de98"
|
||||||
integrity sha1-yQRGkMIeBClL6qUXcS/e0fqI3pg=
|
integrity sha1-yQRGkMIeBClL6qUXcS/e0fqI3pg=
|
||||||
|
|
||||||
lodash.escaperegexp@^4.1.2:
|
|
||||||
version "4.1.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/lodash.escaperegexp/-/lodash.escaperegexp-4.1.2.tgz#64762c48618082518ac3df4ccf5d5886dae20347"
|
|
||||||
integrity sha1-ZHYsSGGAglGKw99Mz11YhtriA0c=
|
|
||||||
|
|
||||||
lodash.flattendeep@^4.4.0:
|
lodash.flattendeep@^4.4.0:
|
||||||
version "4.4.0"
|
version "4.4.0"
|
||||||
resolved "https://registry.yarnpkg.com/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz#fb030917f86a3134e5bc9bec0d69e0013ddfedb2"
|
resolved "https://registry.yarnpkg.com/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz#fb030917f86a3134e5bc9bec0d69e0013ddfedb2"
|
||||||
|
@ -11169,11 +11164,6 @@ lodash.isplainobject@^4.0.6:
|
||||||
resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb"
|
resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb"
|
||||||
integrity sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=
|
integrity sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=
|
||||||
|
|
||||||
lodash.isstring@^4.0.1:
|
|
||||||
version "4.0.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/lodash.isstring/-/lodash.isstring-4.0.1.tgz#d527dfb5456eca7cc9bb95d5daeaf88ba54a5451"
|
|
||||||
integrity sha1-1SfftUVuynzJu5XV2ur4i6VKVFE=
|
|
||||||
|
|
||||||
lodash.kebabcase@^4.1.1:
|
lodash.kebabcase@^4.1.1:
|
||||||
version "4.1.1"
|
version "4.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz#8489b1cb0d29ff88195cceca448ff6d6cc295c36"
|
resolved "https://registry.yarnpkg.com/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz#8489b1cb0d29ff88195cceca448ff6d6cc295c36"
|
||||||
|
@ -11198,7 +11188,7 @@ lodash.merge@^4.6.0:
|
||||||
resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.1.tgz#adc25d9cb99b9391c59624f379fbba60d7111d54"
|
resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.1.tgz#adc25d9cb99b9391c59624f379fbba60d7111d54"
|
||||||
integrity sha512-AOYza4+Hf5z1/0Hztxpm2/xiPZgi/cjMqdnKTUWTBSKchJlxXXuUSxCCl8rJlf4g6yww/j6mA8nC8Hw/EZWxKQ==
|
integrity sha512-AOYza4+Hf5z1/0Hztxpm2/xiPZgi/cjMqdnKTUWTBSKchJlxXXuUSxCCl8rJlf4g6yww/j6mA8nC8Hw/EZWxKQ==
|
||||||
|
|
||||||
lodash.mergewith@^4.6.0, lodash.mergewith@^4.6.1:
|
lodash.mergewith@^4.6.0:
|
||||||
version "4.6.1"
|
version "4.6.1"
|
||||||
resolved "https://registry.yarnpkg.com/lodash.mergewith/-/lodash.mergewith-4.6.1.tgz#639057e726c3afbdb3e7d42741caa8d6e4335927"
|
resolved "https://registry.yarnpkg.com/lodash.mergewith/-/lodash.mergewith-4.6.1.tgz#639057e726c3afbdb3e7d42741caa8d6e4335927"
|
||||||
integrity sha512-eWw5r+PYICtEBgrBE5hhlT6aAa75f411bgDz/ZL2KZqYV03USvucsxcHUIlGTDTECs1eunpI7HOV7U+WLDvNdQ==
|
integrity sha512-eWw5r+PYICtEBgrBE5hhlT6aAa75f411bgDz/ZL2KZqYV03USvucsxcHUIlGTDTECs1eunpI7HOV7U+WLDvNdQ==
|
||||||
|
@ -11565,7 +11555,7 @@ math-random@^1.0.1:
|
||||||
resolved "https://registry.yarnpkg.com/math-random/-/math-random-1.0.1.tgz#8b3aac588b8a66e4975e3cdea67f7bb329601fac"
|
resolved "https://registry.yarnpkg.com/math-random/-/math-random-1.0.1.tgz#8b3aac588b8a66e4975e3cdea67f7bb329601fac"
|
||||||
integrity sha1-izqsWIuKZuSXXjzepn97sylgH6w=
|
integrity sha1-izqsWIuKZuSXXjzepn97sylgH6w=
|
||||||
|
|
||||||
mathml-tag-names@^2.0.1, mathml-tag-names@^2.1.0:
|
mathml-tag-names@^2.0.1:
|
||||||
version "2.1.0"
|
version "2.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/mathml-tag-names/-/mathml-tag-names-2.1.0.tgz#490b70e062ee24636536e3d9481e333733d00f2c"
|
resolved "https://registry.yarnpkg.com/mathml-tag-names/-/mathml-tag-names-2.1.0.tgz#490b70e062ee24636536e3d9481e333733d00f2c"
|
||||||
integrity sha512-3Zs9P/0zzwTob2pdgT0CHZuMbnSUSp8MB1bddfm+HDmnFWHGT4jvEZRf+2RuPoa+cjdn/z25SEt5gFTqdhvJAg==
|
integrity sha512-3Zs9P/0zzwTob2pdgT0CHZuMbnSUSp8MB1bddfm+HDmnFWHGT4jvEZRf+2RuPoa+cjdn/z25SEt5gFTqdhvJAg==
|
||||||
|
@ -15389,22 +15379,6 @@ sane@^4.0.3:
|
||||||
minimist "^1.1.1"
|
minimist "^1.1.1"
|
||||||
walker "~1.0.5"
|
walker "~1.0.5"
|
||||||
|
|
||||||
sanitize-html@^1.20.0:
|
|
||||||
version "1.20.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/sanitize-html/-/sanitize-html-1.20.0.tgz#9a602beb1c9faf960fb31f9890f61911cc4d9156"
|
|
||||||
integrity sha512-BpxXkBoAG+uKCHjoXFmox6kCSYpnulABoGcZ/R3QyY9ndXbIM5S94eOr1IqnzTG8TnbmXaxWoDDzKC5eJv7fEQ==
|
|
||||||
dependencies:
|
|
||||||
chalk "^2.4.1"
|
|
||||||
htmlparser2 "^3.10.0"
|
|
||||||
lodash.clonedeep "^4.5.0"
|
|
||||||
lodash.escaperegexp "^4.1.2"
|
|
||||||
lodash.isplainobject "^4.0.6"
|
|
||||||
lodash.isstring "^4.0.1"
|
|
||||||
lodash.mergewith "^4.6.1"
|
|
||||||
postcss "^7.0.5"
|
|
||||||
srcset "^1.0.0"
|
|
||||||
xtend "^4.0.1"
|
|
||||||
|
|
||||||
sass-direction@^1:
|
sass-direction@^1:
|
||||||
version "1.2.0"
|
version "1.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/sass-direction/-/sass-direction-1.2.0.tgz#84be38ed3876e4847c9924376d434203763bc26e"
|
resolved "https://registry.yarnpkg.com/sass-direction/-/sass-direction-1.2.0.tgz#84be38ed3876e4847c9924376d434203763bc26e"
|
||||||
|
@ -16117,14 +16091,6 @@ sprintf-js@~1.0.2, sprintf-js@~1.0.3:
|
||||||
resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c"
|
resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c"
|
||||||
integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=
|
integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=
|
||||||
|
|
||||||
srcset@^1.0.0:
|
|
||||||
version "1.0.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/srcset/-/srcset-1.0.0.tgz#a5669de12b42f3b1d5e83ed03c71046fc48f41ef"
|
|
||||||
integrity sha1-pWad4StC87HV6D7QPHEEb8SPQe8=
|
|
||||||
dependencies:
|
|
||||||
array-uniq "^1.0.2"
|
|
||||||
number-is-nan "^1.0.0"
|
|
||||||
|
|
||||||
sshpk@^1.7.0:
|
sshpk@^1.7.0:
|
||||||
version "1.16.0"
|
version "1.16.0"
|
||||||
resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.16.0.tgz#1d4963a2fbffe58050aa9084ca20be81741c07de"
|
resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.16.0.tgz#1d4963a2fbffe58050aa9084ca20be81741c07de"
|
||||||
|
|
Loading…
Reference in New Issue