我必须在Liferay Portal中实施一个过滤器以防止XSS攻击。我已经阅读了很多关于它的答案,所以我使用了一个HttpServletRequestWrapper来为我的请求添加已清理的参数。我的过滤器工作正常:调试代码我意识到过滤器接受参数并对其进行消毒。 我的问题是,在portlet的processAction中,我无法使用request.getParameter()检索已清理的参数,但我总是得到旧的未清理的参数。
例如,假设我有一个像这样的简单形式的portlet:
正如您在输入字段中看到的那样,有一个 b 标签可以进行清理。提交表单时,我的过滤器被调用,它会抛出doFilter()方法。 我的doFilter方法迭代所有进行卫生的参数。然后我将它们添加到我的WrappedRequest中:
/*
* Did it make any difference?
*/
if (!Arrays.equals(processedParams, params)) {
logger.info("Parameter: " + params[0] + " sanitized with: " + processedParams[0] );
/*
* If so, wrap up the request with a new version that will return the trimmed version of the param
*/
HashMap<String, String[]> map = new HashMap<>();
map.put(name, processedParams);
final HttpServletRequestWrapper newRequest = new ExtendedRequestWrapper(httpServletRequest,map);
/*
* Return the wrapped request and forward the processing instruction from
* the validation rule
*/
return newRequest;
我的类ExtendedRequestWrapper实现了getparameter方法:
public class ExtendedRequestWrapper extends HttpServletRequestWrapper {
private final Map<String, String[]> modifiableParameters;
private Map<String, String[]> allParameters = null;
public ExtendedRequestWrapper(final HttpServletRequest request,
final Map<String, String[]> additionalParams)
{
super(request);
this.modifiableParameters = new TreeMap<String, String[]>();
this.modifiableParameters.putAll(additionalParams);
}
@Override
public String getParameter(final String name)
{
String[] strings = getParameterMap().get(name);
if (strings != null)
{
return strings[0];
}
return super.getParameter(name);
}
@Override
public Map<String, String[]> getParameterMap()
{
if (this.allParameters == null)
{
this.allParameters = new TreeMap<String, String[]>();
this.allParameters.putAll(super.getParameterMap());
this.allParameters.putAll(modifiableParameters);
}
//Return an unmodifiable collection because we need to uphold the interface contract.
return Collections.unmodifiableMap(allParameters);
}
@Override
public Enumeration<String> getParameterNames()
{
return Collections.enumeration(getParameterMap().keySet());
}
@Override
public String[] getParameterValues(final String name)
{
return getParameterMap().get(name);
}
}
现在,当我尝试在我的processAction()中访问已清理的params时,我得到了旧的值,即没有消毒的那个:
@Override
public void processAction(ActionRequest request, ActionResponse response) throws PortletException, IOException {
String azione = request.getParameter("MyXSSaction");
if(azione.equals("XSSAttack")) {
String descr = req.getParameter("mydescr");
}
}
我该如何解决?
答案 0 :(得分:0)
您不应该在输入处理中执行此操作。首先,InputStream
中没有XSS,因为XSS中的第二个S用于编写脚本&#39; - 而<b>
并不包含任何脚本。
其次,这种过滤器的一般和彻底应用将有效地阻止您添加适当的网页内容,博客文章和其他合法格式化的内容。
第三 - 让我们说你有一个随机的图书管理系统:为什么人们不能作为书名输入<b>
,甚至Let x < 5
- 不会#&#他们是正确的书名吗?实际上,它们是正确的数据,您希望在显示时将其转义。
如果要将某些元素显示为HTML,则可能存在消毒(如Liferay的AntiSamy插件所做)的争论。但是其他任何东西都需要在输出过程中正确转义。
另一种说法:这些参数只有当你在HTML页面中显示时错误地将它们转义时才会有危险 - 但是如果你将它们嵌入到文本/普通邮件正文中,它们就是&# 39;完全无害。