2
0
mirror of https://github.com/tenrok/vue-meta.git synced 2026-06-22 16:30:33 +03:00

Merge pull request #30 from declandewet/escape

implement sanitization
This commit is contained in:
Declan de Wet
2016-11-23 16:24:07 +02:00
committed by GitHub
5 changed files with 320 additions and 253 deletions
+23 -2
View File
@@ -1,5 +1,5 @@
> **Please note** that this project is still in very early alpha development and is *not* considered to be production ready. > **Please note** that this project is still in very early alpha development and is *not* considered to be production ready.
> **You have been warned.** There is no sanitization yet, hardly any tests, and you might find some bugs. > **You have been warned.** There might still be a few bugs and many tests have yet to be written.
<p align="center"> <p align="center">
<img src="http://imgur.com/258WtHI.png" alt="vue-meta"> <img src="http://imgur.com/258WtHI.png" alt="vue-meta">
@@ -90,7 +90,7 @@ These properties, when set on a deeply nested component, will cleverly overwrite
# Disclaimer # Disclaimer
**Please note** that this project is still in very early alpha development and is *not* considered to be production ready. **Please note** that this project is still in very early alpha development and is *not* considered to be production ready.
**You have been warned.** There is no sanitization yet, hardly any tests, and you might find some bugs. **You have been warned.** There might still be a few bugs and many tests have yet to be written.
# Installation # Installation
@@ -506,6 +506,27 @@ Each item in the array maps to a newly-created `<noscript>` element, where objec
<noscript>This website requires JavaScript.</noscript> <noscript>This website requires JavaScript.</noscript>
``` ```
#### `__dangerouslyDisableSanitizers` ([String])
By default, `vue-meta` sanitizes HTML entities in _every_ property. You can disable this behaviour on a per-property basis using `__dangerouslyDisableSantizers`. Just pass it a list of properties you want sanitization to be disabled on:
```js
{
metaInfo: {
title: '<I will be sanitized>',
meta: [{ vmid: 'description', name: 'description', content: '& I will not be <sanitized>'}],
__dangerouslyDisableSanitizers: ['meta']
}
}
```
```html
<title>&lt;I will be sanitized&gt;</title>
<meta vmid="description" name="description" content="& I will not be <sanitized>">
```
:warning: **Using this option is not recommended unless you know exactly what you are doing.** By disabling sanitization, you are opening potential vectors for attacks such as SQL injection & Cross-Site Scripting (XSS). Be very careful to not compromise your application.
#### `changed` (Function) #### `changed` (Function)
Will be called when the client `metaInfo` updates/changes. Receives the following parameters: Will be called when the client `metaInfo` updates/changes. Receives the following parameters:
+3
View File
@@ -10,6 +10,8 @@
"bugs": "https://github.com/declandewet/vue-meta/issues", "bugs": "https://github.com/declandewet/vue-meta/issues",
"dependencies": { "dependencies": {
"deepmerge": "^1.2.0", "deepmerge": "^1.2.0",
"lodash.escape": "^4.0.1",
"lodash.isplainobject": "^4.0.6",
"object-assign": "^4.1.0" "object-assign": "^4.1.0"
}, },
"devDependencies": { "devDependencies": {
@@ -52,6 +54,7 @@
"vue": "^2.0.3", "vue": "^2.0.3",
"vue-loader": "^10.0.0", "vue-loader": "^10.0.0",
"vue-router": "^2.0.1", "vue-router": "^2.0.1",
"vue-template-compiler": "^2.1.0",
"vuex": "^2.0.0", "vuex": "^2.0.0",
"webpack": "beta", "webpack": "beta",
"webpack-dev-server": "beta" "webpack-dev-server": "beta"
+35 -3
View File
@@ -1,4 +1,7 @@
import deepmerge from 'deepmerge' import deepmerge from 'deepmerge'
import escapeHTML from 'lodash.escape'
import isPlainObject from 'lodash.isplainobject'
import isArray from './isArray'
import getComponentOption from './getComponentOption' import getComponentOption from './getComponentOption'
export default function _getMetaInfo (options = {}) { export default function _getMetaInfo (options = {}) {
@@ -23,11 +26,12 @@ export default function _getMetaInfo (options = {}) {
link: [], link: [],
style: [], style: [],
script: [], script: [],
noscript: [] noscript: [],
__dangerouslyDisableSanitizers: []
} }
// collect & aggregate all metaInfo $options // collect & aggregate all metaInfo $options
const info = getComponentOption({ let info = getComponentOption({
component, component,
option: keyName, option: keyName,
deep: true, deep: true,
@@ -73,6 +77,34 @@ export default function _getMetaInfo (options = {}) {
info.base = Object.keys(info.base).length ? [info.base] : [] info.base = Object.keys(info.base).length ? [info.base] : []
} }
return deepmerge(defaultInfo, info) // sanitizes potentially dangerous characters
const escape = (info) => Object.keys(info).reduce((escaped, key) => {
const ref = info.__dangerouslyDisableSanitizers
const isDisabled = ref && ref.indexOf(key) > -1
const val = info[key]
if (!isDisabled) {
if (typeof val === 'string') {
escaped[key] = escapeHTML(val)
} else if (isPlainObject(val)) {
escaped[key] = escape(val)
} else if (isArray(val)) {
escaped[key] = val.map(escape)
} else {
escaped[key] = val
}
} else {
escaped[key] = val
}
return escaped
}, {})
// merge with defaults
info = deepmerge(defaultInfo, info)
// begin sanitization
info = escape(info)
return info
} }
} }
+10
View File
@@ -0,0 +1,10 @@
/**
* checks if passed argument is an array
* @param {any} arr - the object to check
* @return {Boolean} - true if `arr` is an array
*/
export default function isArray (arr) {
return Array.isArray
? Array.isArray(arr)
: Object.prototype.toString.call(arr) === '[object Array]'
}
+249 -248
View File
File diff suppressed because it is too large Load Diff