1. For data requested from the interface
Try to use {{}} loading, not V-HTML.
Braces in vue interpret the data as plain text. Usually if you want to interpret it as html code, you need to use v-html.
This directive is equivalent to innerHTML.
Although script tags are not output directly like innerHTML, it can also output img, iframe and other tags.
The description of vue documentation about v-html is as follows:
2. Escape the customer information loaded with V-HTML and INNERHTML
If there is an html fragment in the display content, you must load it with v-html or innerHTML
For example:
<div v-html="`<span>${message}</span>`"></div>
The message inside is the information entered by the customer himself. If it is a malicious dom clip at this time, it will definitely cause XSS attacks. At this time we can translate "<", ">" into "<", ">". Then enter it to the page.
You can use the escape method in lodash to translate customer information.
as follows:
import _escape from 'lodash/escape' .$escape = _escape
Insert a global method in vue and use this method for data that needs to be translated:
<div v-html="`<span>${$escape(message)}</span>`"></div>
3. Use CSP in META on the entry page
Add meta tag to the head of the entry file
<meta http-equiv="Content-Security-Policy" content="script-src 'self';style-src 'self'">
<meta http-equiv="Content-Security-Policy" content="style-src 'self' 'unsafe-inline';script-src 'self' 'unsafe-inline' 'unsafe-eval' https://appx/;worker-src blob:">
This instruction states: Allow its own css, js, Gaode map API and map data.
The above CSP settings indicate that script script resources and style resources can only load resources under the current domain name. This can avoid the loading and execution of malicious external scripts.
If the page has a tag like the following, then these CDN resources cannot be loaded.
<link href="/ajax/libs/font-awesome/1.0.0/css/" rel="stylesheet"> <script src='/ajax/libs//0.10.0/'></script>
Off topic: I do not recommend using third-party CDNs. First, it will not reduce the volume of the page loading resources. Second, the stability of third-party CDNs cannot be guaranteed. Sometimes the server of third-party CDNs will be hang up, resulting in the required resources not being loaded.
The following CSP configuration is usually used:
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-eval';style-src 'self' 'unsafe-inline'">
Settings explanation:
- script-src: Only load resources under the face domain name server and allow eval to execute scripts. Because webpack uses eval to inject scripts in development mode, and the commonly used souce-map in development is cheap-module-eval-source-map.
- If script-src is set to 'self', it will prevent the use of eval.
- style-src: Only load resources under the face domain name server, and inline resources are allowed. Sometimes, whether in the development environment or the production environment, CSS content may be packaged into JS files through webpack. When loading the page, the JS script will insert style tags into the page to supplement the cascading style model. If style-src is set to 'self', it will prevent the insertion and execution of style inline styles.
4. Selectively filter XSS tags for special scenarios
In projects, XSS security vulnerabilities are prone to occur, such as chat modules and rich text modules.
Sometimes you want to implement the business of editing html content in a rich text editor.
But I'm worried about the injection of XSS malicious scripts.
You can use an xss tool at this time.
Website:/leizongmin/js-xss。
For more detailed usage, you can see the attached URL. Here is a brief description of the usage.
Download xss first
npm i xss -S
(1) Introduce resources into the page and generate XSS filters to filter the content
var xss = require("xss") const option={} //Custom settingsconst myxss = new (option); const line='<script type="text/javascript">alert(1);</script>' var html = (line); (html); //Output:&lt;script type="text/javascript"&gt;alert(1);&lt;/script&gt;
(2) If I want to filter the onerror attribute of the img tag, or filter the style tag.
Retain specific tags and their properties by setting whiteList optional
For example:
const option={ whiteList:{ img:['src','onerror'] //img tag retains src,onerror attributes style:['type'] //The style tag is not in the whileList attribute by default. Now add it } } const myxss = new (option); letline='<img src="./" onerror="alert(1);" alt="123">' let html = (line); (html); //Output: <img src="./" onerror="alert(1);">line='<style type="text/css">color:white;</style>' html = (line); (html); //Output:<style type="text/css">color:white;</style>
The default whiteList of xss can be displayed via ().
(3) If you want to completely filter out script and noscript tags, the option can be set as follows:
const option={ stripIgnoreTagBody: ["script","noscript"], } const myxss = new (option) let line='<script type="text/javascript">alert(1);</script>' let html = (line) () //Output 0, that is, html is converted into an empty stringline='<noscript>123</noscript>' html = (line) () //Output0,Right nowhtmlConverted to an empty string
stripIgnoreTagBody is used to set the filtering method of tags not in whiteList.
For example, if script is not in whiteList, the escapeHtml method inside xss will be executed. For example, the example at the beginning will escape "<" and ">".
But if stripIgnoreTagBody add script. Then the entire script tag will be filtered out directly.
(4) The default generated filter will filter out the class attributes of any tags.
If we don't want to filter the class attribute of any tags in whiteList, we can set it like this:
const option={ onIgnoreTagAttr: function(tag, name, value, isWhiteAttr) { if (['style','class'].includes(name)) { return `${name}="${(value)}"` } }, } const myxss = new (option); let line='<div class="box"></div>' let html = (line); (html); //Output:<div class="box"></div>
The onIgnoreAttr method is used to set filtering methods for specific attributes in the whitelist.
For more detailed tutorials, please see the URL attached at the beginning.
Summarize
The above is personal experience. I hope you can give you a reference and I hope you can support me more.