Evan You 9 лет назад
Родитель
Сommit
1e37633567

+ 7 - 0
src/core/vdom/helpers/resolve-async-component.js

@@ -1,5 +1,12 @@
 /* @flow */
 
+// () => ({
+//   component: import('./xxx.vue'),
+//   delay: 200,
+//   loading: LoadingComponent,
+//   error: ErrorComponent
+// })
+
 import {
   warn,
   isObject

+ 3 - 1
src/platforms/web/server/modules/attrs.js

@@ -1,5 +1,7 @@
 /* @flow */
 
+import { escape } from 'he'
+
 import {
   isBooleanAttr,
   isEnumeratedAttr,
@@ -40,7 +42,7 @@ export function renderAttr (key: string, value: string): string {
   } else if (isEnumeratedAttr(key)) {
     return ` ${key}="${isFalsyAttrValue(value) || value === 'false' ? 'false' : 'true'}"`
   } else if (!isFalsyAttrValue(value)) {
-    return ` ${key}="${value}"`
+    return ` ${key}="${typeof value === 'string' ? escape(value) : value}"`
   }
   return ''
 }

+ 2 - 1
src/platforms/web/server/modules/class.js

@@ -1,10 +1,11 @@
 /* @flow */
 
+import { escape } from 'he'
 import { genClassForVnode } from 'web/util/index'
 
 export default function renderClass (node: VNodeWithData): ?string {
   const classList = genClassForVnode(node)
   if (classList) {
-    return ` class="${classList}"`
+    return ` class="${escape(classList)}"`
   }
 }

+ 3 - 1
src/platforms/web/server/modules/style.js

@@ -1,4 +1,6 @@
 /* @flow */
+
+import { escape } from 'he'
 import { hyphenate } from 'shared/util'
 import { getStyle } from 'web/util/style'
 
@@ -14,6 +16,6 @@ function genStyleText (vnode: VNode): string {
 export default function renderStyle (vnode: VNodeWithData): ?string {
   const styleText = genStyleText(vnode)
   if (styleText) {
-    return ` style=${JSON.stringify(styleText)}`
+    return ` style=${JSON.stringify(escape(styleText))}`
   }
 }

+ 15 - 0
test/ssr/ssr-string.spec.js

@@ -761,6 +761,21 @@ describe('SSR: renderToString', () => {
     })
     expect(vm.a).toBe(func)
   })
+
+  it('should prevent xss in attribtues', () => {
+    renderVmWithOptions({
+      data: {
+        xss: '"><script>alert(1)</script>'
+      },
+      template: `
+        <div>
+          <a :title="xss" :style="{ color: xss }" :class="[xss]">foo</a>
+        </div>
+      `
+    }, res => {
+      expect(res).not.toContain(`<script>alert(1)</script>`)
+    })
+  })
 })
 
 function renderVmWithOptions (options, cb) {