SpringMVC结果参数转换XSS攻击安全处理

首先在sprigMvc的配置文件中配置返回结果集使用的类

<!-- 参数转码 -->
    <mvc:annotation-driven>
        <!-- 注册处理 JSON 的转换器 register-defaults="true" -->
        <mvc:message-converters register-defaults="true">
            <bean class="org.springframework.http.converter.StringHttpMessageConverter">
                <property name="supportedMediaTypes" value="text/html;charset=UTF-8" />
                <property name="writeAcceptCharset" value="false" />
            </bean>
            <bean class="com.util.json.JsonConverter">
                <property name="supportedMediaTypes">
                    <list>
                        <!-- 这里顺序不能反,一定先写text/html,不然ie下出现下载提示 -->
                        <value>text/html;charset=UTF-8</value>
                        <value>application/json;charset=UTF-8</value>
                    </list>
                </property>
            </bean>
        </mvc:message-converters>
    </mvc:annotation-driven>

由于现有工程使用的是json对象结果集,所以只对json格式的参数进行转义

然后在自己工程里配置一个JSON返回结果集的参数转换类

package com.util.json;

import java.io.IOException;
import java.io.OutputStream;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import net.sf.json.JSONArray;
import net.sf.json.JSONException;
import net.sf.json.JSONObject;

import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;
import org.springframework.http.HttpOutputMessage;
import org.springframework.http.converter.HttpMessageNotWritableException;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;

/**
 * JSON格式返回参数转换类
 * <功能详细描述>
 * 
 * @author  songxiaotong
 * @version  [版本号, 2016年10月14日]
 * @see  [相关类/方法]
 * @since  [产品/模块版本]
 */
public class JsonConverter extends FastJsonHttpMessageConverter
{
    /**
     * 日志记录器
     **/
    private static final Logger LOGGER = LogManager.getLogger(JsonConverter.class);
    
    /** 
     * 重写writeInternal方法,在返回内容前首先进行HTML字符转义
     * <功能详细描述>
     * @param object
     * @param outputMessage
     * @throws IOException
     * @throws HttpMessageNotWritableException
     * @see [类、类#方法、类#成员]
     */
    @Override
    protected void writeInternal(Object object, HttpOutputMessage outputMessage)
        throws IOException, HttpMessageNotWritableException
    {
        // 获取输出流
        OutputStream out = outputMessage.getBody();
        
        // 获取要输出的文本
        String text = JSON.toJSONString(object, super.getFeatures());
        
        // 对文本做HTML特殊字符转义
        String result = convertJson(text);
        
        // 输出转义后的文本
        out.write(result.getBytes(super.getCharset()));
    }
    
    /** 
     * JSON参数转义
     * <功能详细描述>
     * @param json
     * @return
     * @see [类、类#方法、类#成员]
     */
    private String convertJson(String json)
    {
        try
        {
            // 判断是否是JSON对象
            if (json.startsWith("{"))
            {
                // 将参数转换成JSONObject
                JSONObject jsonObj = JSONObject.fromObject(json);
                // 处理参数
                JSONObject myobj = jsonObj(jsonObj);
                return myobj.toString();
            }
            // 判断是否是JSON数组
            else if (json.startsWith("["))
            {
                // 将参数转换成JSONArray
                JSONArray jsonArray = JSONArray.fromObject(json);
                //处理参数
                JSONArray array = parseArray(jsonArray);
                return array.toString();
            }
            else
            {
                return json;
            }
        }
        catch (JSONException e)
        {
            LOGGER.error("Json数据解析处理失败!");
            return "{}";
        }
    }
    
    /** 
     * JSON参数Map(对象)转义
     * <功能详细描述>
     * @param json
     * @return
     * @see [类、类#方法、类#成员]
     */
    @SuppressWarnings("rawtypes")
    private JSONObject jsonObj(JSONObject json)
    {
        
        for (Iterator iter = json.keys(); iter.hasNext();)
        {
            // 获取对象的key
            String key = (String)iter.next();
            // 获取对象的值
            Object obj = json.get(key);
            
            // 判断对象类型
            if (obj instanceof List)
            {
                json.put(key, parseArray((JSONArray)obj));
                
            }
            // 判断是否是对象结构
            else if (obj instanceof Map)
            {
                // 处理参数
                json.put(key, jsonObj((JSONObject)obj));
            }
            else if (obj instanceof String)
            {
                // 处理参数
                json.put(key, convertStr((String)obj));
            }
            
        }
        return json;
    }
    
    /** 
     * JSON参数List(数组)转义
     * <功能详细描述>
     * @param json
     * @return
     * @see [类、类#方法、类#成员]
     */
    private JSONArray parseArray(JSONArray jsonArray)
    {
        // 判空
        if (null == jsonArray || jsonArray.isEmpty() || jsonArray.size() == 0)
        {
            return jsonArray;
        }
        // 
        for (int i = 0, l = jsonArray.size(); i < l; i++)
        {
            Object obj = jsonArray.get(i);
            
            // 判断是否是数据结构
            if (obj instanceof List)
            {
                // 处理数组对象
                parseArray((JSONArray)obj);
            }
            // 判断是否是对象结构
            else if (obj instanceof Map)
            {
                // 处理参数
                jsonObj((JSONObject)obj);
            }
            // 判断是否是String结构
            else if (obj instanceof String)
            {
                jsonArray.set(i, convertStr((String)obj));
            }
        }
        
        return jsonArray;
    }
    
    /** 
     * HTML脚本转义
     * <功能详细描述>
     * @param str
     * @return
     * @see [类、类#方法、类#成员]
     */
    private String convertStr(String str)
    {
        // TODO &、<、>、"、'、(、)、%、+、\
        return str.replace("&", "&amp;")
            .replace("<", "&lt;")
            .replace(">", "&gt;")
            .replace("\"", "&quot;")
            .replace("'", "&#x27;")
            .replace("(", "&#40;")
            .replace(")", "&#41;")
            .replace("%", "&#37;")
            .replace("+", "&#43;")
            .replace("\\", "&#92;");
    }
}

 

posted @ 2017-03-27 14:30  不知名的宋某某  阅读(4249)  评论(0编辑  收藏  举报