今天客户提出需要检验系统的安全性并且提出几点需要处理:
1、任意下载文件问题
可以任意下载文件,在使用burp抓包后,发送请求可以随便下载文件,解决方法对传入的路径过滤".","","、"字符串。
2、发射型xss
可以通过XSS过滤检测或者对数据进行转义。
3、使用备份获取shell
限定文件后缀名,文件路径。
4、任意上传文件
检查文件的合法性和后缀名。
package com.hundsun.fund.common; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.util.HashMap; import java.util.Map; public class FileFormatVerify { private static Map<String,String> FileTypes = null; public FileFormatVerify(){ FileTypes = new HashMap<String,String>(); // images FileTypes.put("FFD8FFE0", ".jpg"); FileTypes.put("89504E47", ".png"); FileTypes.put("47494638", ".gif"); FileTypes.put("49492A00", ".tif"); FileTypes.put("424D", ".bmp"); //PS和CAD FileTypes.put("38425053", ".psd"); FileTypes.put("41433130", ".dwg"); // CAD FileTypes.put("252150532D41646F6265",".ps"); //办公文档类 FileTypes.put("D0CF11E0", ".doc"); //ppt、doc、xls FileTypes.put("504B0304", ".docx");//pptx、docx、xlsx /**注意由于文本文档录入内容过多,则读取文件头时较为多变-START**/ FileTypes.put("0D0A0D0A", ".txt");//txt FileTypes.put("0D0A2D2D", ".txt");//txt FileTypes.put("0D0AB4B4", ".txt");//txt FileTypes.put("B4B4BDA8", ".txt");//文件头部为汉字 FileTypes.put("73646673", ".txt");//txt,文件头部为英文字母 FileTypes.put("32323232", ".txt");//txt,文件头部内容为数字 FileTypes.put("0D0A09B4", ".txt");//txt,文件头部内容为数字 FileTypes.put("3132330D", ".txt");//txt,文件头部内容为数字 /**注意由于文本文档录入内容过多,则读取文件头时较为多变-END**/ FileTypes.put("7B5C727466", ".rtf"); // 日记本 FileTypes.put("255044462D312E", ".pdf"); //视频或音频类 FileTypes.put("3026B275",".wma"); FileTypes.put("57415645", ".wav"); FileTypes.put("41564920", ".avi"); FileTypes.put("4D546864", ".mid"); FileTypes.put("2E524D46", ".rm"); FileTypes.put("000001BA", ".mpg"); FileTypes.put("000001B3", ".mpg"); FileTypes.put("6D6F6F76", ".mov"); FileTypes.put("3026B2758E66CF11", ".asf"); //压缩包 FileTypes.put("52617221", ".rar"); FileTypes.put("1F8B08", ".gz"); //程序文件 FileTypes.put("3C3F786D6C", ".xml"); FileTypes.put("68746D6C3E", ".html"); FileTypes.put("7061636B", ".java"); FileTypes.put("3C254020", ".jsp"); FileTypes.put("4D5A9000", ".exe"); FileTypes.put("44656C69766572792D646174653A", ".eml"); // 邮件 FileTypes.put("5374616E64617264204A", ".mdb");//Access数据库文件 FileTypes.put("46726F6D", ".mht"); FileTypes.put("4D494D45", ".mhtml"); } /** * @Description 根据传入的文件获得后缀,获得指定文件格式byte[]数组中的前8位字符 * 将传入文件转化为byte[]数组,取前8位.判断传入文件的前8位和我们指定好的文件byte[]的前8位是否相同, * 如果相同则文件格式没有被篡改,反之,文件后缀格式被篡改 * @Param [file] * @return boolean 返回true 表示文件格式验证通过, 返回false 文件格式验证失败 **/ public boolean suffixVerify(File file){ String fileType = ""; boolean isgood = false; String name = file.getName(); int i = name.lastIndexOf("."); // 获取文件的后缀 if(i > 0){ fileType = name.substring(i + 1); } //根据文件的后缀获取,获取文件的byte[]的前8位 if(FileTypes.containsValue(fileType.toLowerCase())){ for(Map.Entry<String, String> filetype:FileTypes.entrySet()){ if(filetype.getValue().equals(fileType)){ String fileByte8 = String.valueOf(filetype.getKey()); //获取传入文件的byte[]的前8位 byte[] bytes = inputStream2ByteArray(file); String compareByte = bytesToHexString(bytes); //如果传入文件的byte[]的前8位和我们定义好的byte[]的前8位相同,验证通过. if (compareByte.startsWith(fileByte8)){ //如果格式校验成功 isgood = true; } } } }else{ return isgood; } return isgood; } /** * @Description 将file文件转化为byte[] * @Param [file] * @return byte[] **/ public byte[] inputStream2ByteArray(File file){ ByteArrayOutputStream bos = new ByteArrayOutputStream(); FileInputStream fis = null; byte[] buffer = null; try { fis = new FileInputStream(file); //不用读取全部文件,只读文件前面的部分 byte[] b = new byte[1024]; fis.read(b); bos.write(b, 0, 1024); buffer = bos.toByteArray(); }catch (FileNotFoundException e){ e.printStackTrace(); }catch (IOException e1){ e1.printStackTrace(); }finally { try { if(fis !=null){ fis.close(); } }catch (Exception e){ e.printStackTrace(); } try { if(bos !=null){ bos.close(); } }catch (Exception e){ e.printStackTrace(); } } return buffer; } /** * @Description 取byte[]前8位的为字符串 * @Param [src] * @return java.lang.String **/ public String bytesToHexString(byte[] src) { StringBuilder stringBuilder = new StringBuilder(); if (src == null || src.length <= 0) { return null; } for (int i = 0; i < src.length; i++) { int v = src[i] & 0xFF; String hv = Integer.toHexString(v); if (hv.length() < 2) { stringBuilder.append(0); } stringBuilder.append(hv); } //return stringBuilder.toString().substring(0, 8); return stringBuilder.toString(); } }