java 富文本 过滤xss_集成富文本编辑器XSS预防过滤措施

# https://github.com/phith0n/python-xss-filter

import re

import copy

from html.parser import HTMLParser

class XSSHtml(HTMLParser):

allow_tags = ['a', 'img', 'br', 'strong', 'b', 'code', 'pre',

'p', 'div', 'em', 'span', 'h1', 'h2', 'h3', 'h4',

'h5', 'h6', 'blockquote', 'ul', 'ol', 'tr', 'th', 'td',

'hr', 'li', 'u', 'embed', 's', 'table', 'thead', 'tbody',

'caption', 'small', 'q', 'sup', 'sub', 'font']

common_attrs = ["style", "class", "name"]

nonend_tags = ["img", "hr", "br", "embed"]

tags_own_attrs = {

"img": ["src", "width", "height", "alt", "align"],

"a": ["href", "target", "rel", "title"],

"embed": ["src", "width", "height", "type", "allowfullscreen", "loop", "play", "wmode", "menu"],

"table": ["border", "cellpadding", "cellspacing"],

"font": ["color"]

}

def __init__(self, allows=[]):

HTMLParser.__init__(self)

self.allow_tags = allows if allows else self.allow_tags

self.result = []

self.start = []

self.data = []

def __enter__(self):

return self

def __exit__(self, exc_type, exc_val, exc_tb):

super().close()

def clean(self, content):

self.feed(content)

return self.get_html()

def get_html(self):

"""

Get the safe html code

"""

for i in range(0, len(self.result)):

if self.result[i].strip('\n'):

self.data.append(self.result[i])

return ''.join(self.data)

def handle_startendtag(self, tag, attrs):

self.handle_starttag(tag, attrs)

def handle_starttag(self, tag, attrs):

if tag not in self.allow_tags:

return

end_diagonal = ' /' if tag in self.nonend_tags else ''

if not end_diagonal:

self.start.append(tag)

attdict = {}

for attr in attrs:

attdict[attr[0]] = attr[1]

attdict = self._wash_attr(attdict, tag)

if hasattr(self, "node_%s" % tag):

attdict = getattr(self, "node_%s" % tag)(attdict)

else:

attdict = self.node_default(attdict)

attrs = []

for (key, value) in attdict.items():

attrs.append('%s="%s"' % (key, self._htmlspecialchars(value)))

attrs = (' ' + ' '.join(attrs)) if attrs else ''

self.result.append('')

def handle_endtag(self, tag):

if self.start and tag == self.start[len(self.start) - 1]:

self.result.append('' + tag + '>')

self.start.pop()

def handle_data(self, data):

self.result.append(self._htmlspecialchars(data))

def handle_entityref(self, name):

if name.isalpha():

self.result.append("&%s;" % name)

def handle_charref(self, name):

if name.isdigit():

self.result.append("%s;" % name)

def node_default(self, attrs):

attrs = self._common_attr(attrs)

return attrs

def node_a(self, attrs):

attrs = self._common_attr(attrs)

attrs = self._get_link(attrs, "href")

attrs = self._set_attr_default(attrs, "target", "_blank")

attrs = self._limit_attr(attrs, {

"target": ["_blank", "_self"]

})

return attrs

def node_embed(self, attrs):

attrs = self._common_attr(attrs)

attrs = self._get_link(attrs, "src")

attrs = self._limit_attr(attrs, {

"type": ["application/x-shockwave-flash"],

"wmode": ["transparent", "window", "opaque"],

"play": ["true", "false"],

"loop": ["true", "false"],

"menu": ["true", "false"],

"allowfullscreen": ["true", "false"]

})

attrs["allowscriptaccess"] = "never"

attrs["allownetworking"] = "none"

return attrs

def _true_url(self, url):

prog = re.compile(r"^(http|https|ftp)://.+", re.I | re.S)

if prog.match(url):

return url

else:

return "http://%s" % url

def _true_style(self, style):

if style:

style = re.sub(r"(\\||/\*|\*/)", "_", style)

style = re.sub(r"e.*x.*p.*r.*e.*s.*s.*i.*o.*n", "_", style)

return style

def _get_style(self, attrs):

if "style" in attrs:

attrs["style"] = self._true_style(attrs.get("style"))

return attrs

def _get_link(self, attrs, name):

if name in attrs:

attrs[name] = self._true_url(attrs[name])

return attrs

def _wash_attr(self, attrs, tag):

if tag in self.tags_own_attrs:

other = self.tags_own_attrs.get(tag)

else:

other = []

if attrs:

for key, value in copy.deepcopy(attrs).items():

if key not in self.common_attrs + other:

del attrs[key]

return attrs

def _common_attr(self, attrs):

attrs = self._get_style(attrs)

return attrs

def _set_attr_default(self, attrs, name, default=''):

if name not in attrs:

attrs[name] = default

return attrs

def _limit_attr(self, attrs, limit={}):

for (key, value) in limit.items():

if key in attrs and attrs[key] not in value:

del attrs[key]

return attrs

def _htmlspecialchars(self, html):

return html.replace("

.replace(">", ">") \

.replace('"', """) \

.replace("'", "'")

if "__main__" == __name__:

with XSSHtml() as parser:

ret = parser.clean("""

1


hehe

>M

MM

#""")

print(ret)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是Java过滤器处理XSS攻击的示例代码: ```java import javax.servlet.*; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper;import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.*; public class XssFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { MyHttpServletRequestWrapper requestWrapper = new MyHttpServletRequestWrapper((HttpServletRequest) servletRequest); HttpServletResponse response = (HttpServletResponse) servletResponse; filterChain.doFilter(requestWrapper, response); } @Override public void destroy() { } private class MyHttpServletRequestWrapper extends HttpServletRequestWrapper { public MyHttpServletRequestWrapper(HttpServletRequest request) { super(request); } @Override public String getParameter(String name) { String value = super.getParameter(name); if (value != null) { value = cleanXSS(value); } return value; } @Override public String[] getParameterValues(String name) { String[] values = super.getParameterValues(name); if (values != null) { for (int i = 0; i < values.length; i++) { values[i] = cleanXSS(values[i]); } } return values; } @Override public Enumeration<String> getParameterNames() { List<String> names = Collections.list(super.getParameterNames()); return Collections.enumeration(names); } @Override public Map<String, String[]> getParameterMap() { Map<String, String[]> paramMap = super.getParameterMap(); Map<String, String[]> newParamMap = new HashMap<>(); for (String key : paramMap.keySet()) { String[] values = paramMap.get(key); for (int i = 0; i < values.length; i++) { values[i] = cleanXSS(values[i]); } newParamMap.put(key, values); } return newParamMap; } private String cleanXSS(String value) { value = value.replaceAll("<", "<").replaceAll(">", ">"); value = value.replaceAll("\\(", "(").replaceAll("\\)", ")"); value = value.replaceAll("'", "'"); value = value.replaceAll("eval\\((.*)\\)", ""); value = value.replaceAll("[\\\"\\\'][\\s]*javascript:(.*)[\\\"\\\']", "\"\""); value = value.replaceAll("script", ""); return value; } } } ``` 该过滤器通过继承HttpServletRequestWrapper类,重写其中的getParameter()、getParameterValues()、getParameterNames()和getParameterMap()方法,对请求参数进行过滤,防止XSS攻击。其中,cleanXSS()方法用于过滤请求参数中的特殊字符和脚本代码。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值