• 判断文件类型,非后缀名的方式


    上传文件如果不做好安全控制的话,攻击者很有可能上传一些恶意攻击脚本,然后再执行,达到不可告人的目的。于是我们需要判断文件的类型,通常情况下我们只是判断了文件的后缀名,根据文件的后缀名的白名单和黑名单来过滤。这种方式非常不可靠,因为后缀名完全可以伪造。例如exe的伪造成jpg。
     
          通过文件内容的判断文件的类型是目前最可靠的,因为一般根据文件的开头一些字节的特征就能判断这个文件的类型,而不需要读取整个文件,所以可行性也比较高。下面给出一个例子。
     
    1、首先定义文件类型的识别数据FileType.java

      1 public enum FileType {
      2     
      3          /**
      4          * JEPG.
      5          */
      6     JPEG("FFD8FF"),
      7  
      8  
      9         /**
     10          * PNG.
     11          */
     12     PNG("89504E47"),
     13  
     14  
     15         /**
     16          * GIF.
     17          */
     18     GIF("47494638"),
     19  
     20  
     21         /**
     22          * TIFF.
     23          */
     24     TIFF("49492A00"),
     25         /**
     26          * RTF.
     27          */
     28     RTF("7B5C727466"),
     29         /**
     30          * DOC
     31          */
     32     DOC("D0CF11E0"),
     33         /**
     34          * XLS
     35          */
     36     XLS("D0CF11E0"),
     37         /**
     38          * ACCESS
     39          */
     40     MDB("5374616E64617264204A"),
     41  
     42  
     43         /**
     44          * Windows Bitmap.
     45          */
     46     BMP("424D"),
     47  
     48  
     49         /**
     50          * CAD.
     51          */
     52     DWG("41433130"),
     53  
     54  
     55         /**
     56          * Adobe Photoshop.
     57          */
     58     PSD("38425053"),
     59  
     60  
     61         /**
     62          * XML.
     63          */
     64     XML("3C3F786D6C"),
     65  
     66  
     67         /**
     68          * HTML.
     69          */
     70     HTML("68746D6C3E"),
     71  
     72  
     73         /**
     74          * Adobe Acrobat.
     75          */
     76     PDF("255044462D312E"),
     77  
     78  
     79         /**
     80          * ZIP Archive.
     81          */
     82     ZIP("504B0304"),
     83  
     84  
     85         /**
     86          * RAR Archive.
     87          */
     88     RAR("52617221"),
     89  
     90  
     91         /**
     92          * Wave.
     93          */
     94     WAV("57415645"),
     95  
     96  
     97         /**
     98          * AVI.
     99          */
    100     AVI("41564920");
    101     
    102     
    103     private String value = "";
    104     
    105     /**
    106      * Constructor.
    107      * 
    108      * @param type 
    109      */
    110     private FileType(String value) {
    111         this.value = value;
    112     }
    113  
    114     public String getValue() {
    115         return value;
    116     }
    117  
    118     public void setValue(String value) {
    119         this.value = value;
    120     }
    121 }
    View Code

    然后读取文件的前面几个字节转化成十六进制

      1 public enum FileType {
      2     
      3          /**
      4          * JEPG.
      5          */
      6     JPEG("FFD8FF"),
      7  
      8  
      9         /**
     10          * PNG.
     11          */
     12     PNG("89504E47"),
     13  
     14  
     15         /**
     16          * GIF.
     17          */
     18     GIF("47494638"),
     19  
     20  
     21         /**
     22          * TIFF.
     23          */
     24     TIFF("49492A00"),
     25         /**
     26          * RTF.
     27          */
     28     RTF("7B5C727466"),
     29         /**
     30          * DOC
     31          */
     32     DOC("D0CF11E0"),
     33         /**
     34          * XLS
     35          */
     36     XLS("D0CF11E0"),
     37         /**
     38          * ACCESS
     39          */
     40     MDB("5374616E64617264204A"),
     41  
     42  
     43         /**
     44          * Windows Bitmap.
     45          */
     46     BMP("424D"),
     47  
     48  
     49         /**
     50          * CAD.
     51          */
     52     DWG("41433130"),
     53  
     54  
     55         /**
     56          * Adobe Photoshop.
     57          */
     58     PSD("38425053"),
     59  
     60  
     61         /**
     62          * XML.
     63          */
     64     XML("3C3F786D6C"),
     65  
     66  
     67         /**
     68          * HTML.
     69          */
     70     HTML("68746D6C3E"),
     71  
     72  
     73         /**
     74          * Adobe Acrobat.
     75          */
     76     PDF("255044462D312E"),
     77  
     78  
     79         /**
     80          * ZIP Archive.
     81          */
     82     ZIP("504B0304"),
     83  
     84  
     85         /**
     86          * RAR Archive.
     87          */
     88     RAR("52617221"),
     89  
     90  
     91         /**
     92          * Wave.
     93          */
     94     WAV("57415645"),
     95  
     96  
     97         /**
     98          * AVI.
     99          */
    100     AVI("41564920");
    101     
    102     
    103     private String value = "";
    104     
    105     /**
    106      * Constructor.
    107      * 
    108      * @param type 
    109      */
    110     private FileType(String value) {
    111         this.value = value;
    112     }
    113  
    114     public String getValue() {
    115         return value;
    116     }
    117  
    118     public void setValue(String value) {
    119         this.value = value;
    120     }
    121 }
    View Code
    2、通过枚举类,管理不同类型文件的文件头(具体每个文件的文件头内容,可以通过UltraEdit工具打开,查看其16进制内容)
      1 package org.hyena.ats.util;
      2  
      3 /**
      4  * 文件类型
      5  * @author zhihao.du
      6  *
      7  */
      8 public enum FileType {
      9     /** 
     10      * JEPG. 
     11      */  
     12     JPEG("FFD8FF"),  
     13   
     14     /** 
     15      * PNG. 
     16      */  
     17     PNG("89504E47"),  
     18   
     19     /** 
     20      * GIF. 
     21      */  
     22     GIF("47494638"),  
     23   
     24     /** 
     25      * TIFF. 
     26      */  
     27     TIFF("49492A00"),  
     28   
     29     /** 
     30      * Windows Bitmap. 
     31      */  
     32     BMP("424D"),  
     33   
     34     /** 
     35      * CAD. 
     36      */  
     37     DWG("41433130"),  
     38   
     39     /** 
     40      * Adobe Photoshop. 
     41      */  
     42     PSD("38425053"),  
     43   
     44     /** 
     45      * Rich Text Format. 
     46      */  
     47     RTF("7B5C727466"),  
     48   
     49     /** 
     50      * XML. 
     51      */  
     52     XML("3C3F786D6C"),  
     53   
     54     /** 
     55      * HTML. 
     56      */  
     57     HTML("68746D6C3E"),  
     58     /** 
     59      * CSS. 
     60      */  
     61     CSS("48544D4C207B0D0A0942"),  
     62     /** 
     63      * JS. 
     64      */  
     65     JS("696B2E71623D696B2E71"),  
     66     /** 
     67      * Email [thorough only]. 
     68      */  
     69     EML("44656C69766572792D646174653A"),  
     70   
     71     /** 
     72      * Outlook Express. 
     73      */  
     74     DBX("CFAD12FEC5FD746F"),  
     75   
     76     /** 
     77      * Outlook (pst). 
     78      */  
     79     PST("2142444E"),  
     80   
     81     /** 
     82      * MS Word/Excel. 
     83      * XLS_DOC:ppt,doc,xls
     84      * XLSX_DOCX:xlsx
     85      */  
     86     XLS_DOC("D0CF11E0"), XLSX_DOCX("504B030414000600080000002100"),
     87     /** 
     88      * Visio 
     89      */  
     90     VSD("d0cf11e0a1b11ae10000"),  
     91     /** 
     92      * MS Access. 
     93      */  
     94     MDB("5374616E64617264204A"),  
     95     /** 
     96      * WPS文字wps、表格et、演示dps都是一样的 
     97      */  
     98     WPS("d0cf11e0a1b11ae10000"),  
     99     /** 
    100      * torrent 
    101      */  
    102     TORRENT("6431303A637265617465"),  
    103     /** 
    104      * WordPerfect. 
    105      */  
    106     WPD("FF575043"),  
    107   
    108     /** 
    109      * Postscript. 
    110      */  
    111     EPS("252150532D41646F6265"),  
    112   
    113     /** 
    114      * Adobe Acrobat. 
    115      */  
    116     PDF("255044462D312E"),  
    117   
    118     /** 
    119      * Quicken. 
    120      */  
    121     QDF("AC9EBD8F"),  
    122   
    123     /** 
    124      * Windows Password. 
    125      */  
    126     PWL("E3828596"),  
    127   
    128     /** 
    129      * ZIP Archive. 
    130      */  
    131     ZIP("504B0304"),  
    132   
    133     /** 
    134      * RAR Archive. 
    135      */  
    136     RAR("52617221"),  
    137     /** 
    138      * JSP Archive. 
    139      */  
    140     JSP("3C2540207061676520"),  
    141     /** 
    142      * JAVA Archive. 
    143      */  
    144     JAVA("7061636B61676520"),  
    145     /** 
    146      * CLASS Archive. 
    147      */  
    148     CLASS("CAFEBABE0000002E00"),  
    149     /** 
    150      * JAR Archive. 
    151      */  
    152     JAR("504B03040A000000"),  
    153     /** 
    154      * MF Archive. 
    155      */  
    156     MF("4D616E69666573742D56"),  
    157     /** 
    158      *EXE Archive. 
    159      */  
    160     EXE("4D5A9000030000000400"),  
    161     /** 
    162      *CHM Archive. 
    163      */  
    164     CHM("49545346030000006000"),
    165     /** 
    166      * Wave. 
    167      */  
    168     WAV("57415645"),  
    169   
    170     /** 
    171      * AVI. 
    172      */  
    173     AVI("41564920"),  
    174   
    175     /** 
    176      * Real Audio. 
    177      */  
    178     RAM("2E7261FD"),  
    179   
    180     /** 
    181      * Real Media. 
    182      */  
    183     RM("2E524D46"),  
    184   
    185     /** 
    186      * MPEG (mpg). 
    187      */  
    188     MPG("000001BA"),  
    189   
    190     /** 
    191      * Quicktime. 
    192      */  
    193     MOV("6D6F6F76"),  
    194   
    195     /** 
    196      * Windows Media. 
    197      */  
    198     ASF("3026B2758E66CF11"),  
    199   
    200     /** 
    201      * MIDI. 
    202      */  
    203     MID("4D546864"),  
    204     /** 
    205      * MP4. 
    206      */  
    207     MP4("00000020667479706d70"),  
    208     /** 
    209      * MP3. 
    210      */  
    211     MP3("49443303000000002176"),
    212     /** 
    213      * FLV. 
    214      */  
    215     FLV("464C5601050000000900"), 
    216     /**
    217      * TXT:txt,docx
    218      */
    219     TXT("0000000000000000000000000000");
    220     
    221     private String value = "";  
    222   
    223     /** 
    224      * Constructor. 
    225      *  
    226      * @param type 
    227      */  
    228     private FileType(String value) {  
    229         this.value = value;  
    230     }  
    231   
    232     public String getValue() {  
    233         return value;  
    234     }  
    235   
    236     public void setValue(String value) {  
    237         this.value = value;  
    238     }  
    239   
    240 }  
    View Code
    操作枚举类:
      1 package org.hyena.ats.util;
      2  
      3 import java.io.IOException;  
      4 import java.io.InputStream;  
      5   
      6 /**
      7  * 文件类型操作类
      8  * @author zhihao.du
      9  *
     10  */
     11 public final class FileTypeJudge {  
     12   
     13     /** 
     14      * Constructor 
     15      */  
     16     private FileTypeJudge() {
     17     }
     18   
     19     /** 
     20      * 将文件头转换成16进制字符串 
     21      * @param 原生byte 
     22      * @return 16进制字符串 
     23      */  
     24     private static String bytesToHexString(byte[] src) {  
     25         StringBuilder stringBuilder = new StringBuilder();  
     26         if (src == null || src.length <= 0) {
     27             return null;
     28         }  
     29         for (int i = 0; i < src.length; i++) {  
     30             int v = src[i] & 0xFF;  
     31             String hv = Integer.toHexString(v);  
     32             if (hv.length() < 2) {  
     33                 stringBuilder.append(0);  
     34             }  
     35             stringBuilder.append(hv);  
     36         }  
     37         return stringBuilder.toString();  
     38     }  
     39   
     40     /** 
     41      * 得到文件头 
     42      * @param filePath 文件路径 
     43      * @return 文件头 
     44      * @throws IOException 
     45      */  
     46     private static String getFileContent(InputStream is) throws IOException {  
     47         byte[] b = new byte[28];
     48         InputStream inputStream = null;  
     49         try {  
     50             is.read(b, 0, 28);
     51         } catch (IOException e) {  
     52             e.printStackTrace();  
     53             throw e;  
     54         } finally {  
     55             if (inputStream != null) {  
     56                 try {  
     57                     inputStream.close();  
     58                 } catch (IOException e) {  
     59                     e.printStackTrace();
     60                     throw e;  
     61                 }  
     62             }  
     63         }  
     64         return bytesToHexString(b);
     65     }  
     66   
     67     /** 
     68      * 获取文件类型类
     69      * @param filePath 文件路径 
     70      * @return 文件类型 
     71      */  
     72     public static FileType getType(InputStream is) throws IOException {  
     73         String fileHead = getFileContent(is);
     74         if (fileHead == null || fileHead.length() == 0) {  
     75             return null;  
     76         }  
     77         fileHead = fileHead.toUpperCase();  
     78         FileType[] fileTypes = FileType.values();  
     79         for (FileType type : fileTypes) {  
     80             if (fileHead.startsWith(type.getValue())) {  
     81                 return type;  
     82             }
     83         }  
     84         return null;  
     85     }
     86   
     87     /**
     88      * 获取文件类型
     89      * @param is
     90      * @return
     91      * @throws Exception
     92      */
     93     public static String getFileType(InputStream is) throws Exception{
     94         FileType fileType = getType(is);
     95         if(fileType!=null){
     96             return fileType.getValue();            
     97         }
     98         return null;
     99     }
    100 }  
    View Code
    判断接口
     1 /**
     2      * 判断文件格式
     3      * @param file
     4      * @return
     5      */
     6     public static boolean checkFileFormat(MultipartFile file) {
     7         if (file == null) {
     8             return false;
     9         }
    10         try {
    11             String type = FileTypeJudge.getFileType(file.getInputStream());
    12             if(FileType.TXT.getValue().equals(type)){//TXT,DOCX
    13                 return true;
    14             }
    15             if(FileType.XLS_DOC.getValue().equals(type)){//PPT,DOC,XLS
    16                 return true;
    17             }
    18             if(FileType.XLSX_DOCX.getValue().equals(type)){//XLSX
    19                 return true;
    20             }
    21             if(FileType.PDF.getValue().equals(type)){//PDF
    22                 return true;
    23             }
    24             if(FileType.PNG.getValue().equals(type)){//PNG
    25                 return true;
    26             }
    27             if(FileType.JPEG.getValue().equals(type)){//JPG
    28                 return true;
    29             }
    30         }catch (Exception e) {
    31             e.printStackTrace();
    32             return false;
    33         }
    34         return false;
    35     }
    View Code

  • 相关阅读:
    Tomcat + Mysql高并发配置优化
    Qt Widget 利用 Qt4.5 实现酷炫透明窗体
    使用VC2005编译真正的静态Qt4.4.3程序 good
    详解 Qt 线程间共享数据(使用signal/slot传递数据,线程间传递信号会立刻返回,但也可通过connect改变)
    浅析在QtWidget中自定义Model(beginInsertRows()和endInsertRows()是空架子,类似于一种信号,用来通知底层)
    英国著名芯片厂商与苹果谈崩 中资收购机会来了!
    跨站脚本攻击(XSS)
    Kafka 协议实现中的内存优化
    读取配置信息
    英语面试准备
  • 原文地址:https://www.cnblogs.com/tushengadbm/p/14150776.html
Copyright © 2020-2023  润新知