zoukankan      html  css  js  c++  java
  • 校验文件的合法性

    今天客户提出需要检验系统的安全性并且提出几点需要处理:

    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();
        }
    }

      

  • 相关阅读:
    第二周作业
    第二次作业
    第一周作业
    我的2018年终总结
    css总结
    python中使用selenium错误-Firefox浏览器
    postman中 form-data、x-www-form-urlencoded、raw、binary的区别
    谷歌地图API(一)
    2014新年开题
    图书馆管理系统-需求分析
  • 原文地址:https://www.cnblogs.com/huanlingjisi/p/14823025.html
Copyright © 2011-2022 走看看