`

上传文件校验

    博客分类:
  • java
 
阅读更多

为了防止一些用户将一些病毒文件上传到服务器,我们一般需要对上传的文件做合法性校验, 当时有时候简单的后缀和contentType校验任然还有风险,下面我们一起来讨论一下上传的文件需要做哪些合法性校验。

 

1、文件后缀校验

这层校验应该说是最基本的校验了,我们不能允许用户上传一些exe、jsp、php、asp、html等可执行的文件。

 

2、contentType校验

contentType是内容类型,它会告诉浏览器用什么形式、什么编码来读取这个文件。因此文件后缀和contentType有一个对应关系,上传文件的后缀和contentType应该是对应的,如果不对应则上传信息已被篡改。后缀和contentType关系表参考tomcat下conf/web.xml中。

 

3、上传图片校验

如果需要上传的文件是图片,必须对上传的文件是否是一个图片进行检验,否则如果用户将一个html文件修改后缀为图片并上传,在显示该图片时就会执行html文件中的内容,带来跨域攻击风险。

 

图片校验方式

(1)、通过ImageIO读取文件,如果抛出异常或者读取后的对象为null,表示该文件不是图片

 

/**
	 * 通过读取文件信息判断文件是否是图片
	 * @param imageFile
	 * @return
	 */
	public static boolean checkImageFileByRead(File imageFile){
		try {
			BufferedImage image = ImageIO.read(imageFile);
			if(image == null){
				log.error("The file could not be opened , it is not an image");
				return false;
			}
		} catch (IOException e) {
			log.error(e.getMessage(), e);
			return false;
		}
		return true;
	}

 

(2)、通过ImageIO读取文件成图片流,如果抛出异常或者读取后的流对象为null,表示文件不是图片

/**
	 * 通过将文件转换为图片流方式监测文件是否为图片
	 * @param imageFile
	 * @return
	 */
	public static boolean checkImageFileByIS(File imageFile){
		try {
			ImageInputStream is = ImageIO.createImageInputStream(imageFile);
			if(is == null){
				return false;
			}
			is.close();
		} catch (IOException e) {
			log.error(e.getMessage(), e);
			return false;
		}
		return true;
	}

 

 (3)有些图片中可能会嵌入IFrame,以同样会导致跨域攻击,可以采用添加水印方式解决

/**
     * 给图片添加水印、可设置水印图片旋转角度
    * 
     * @param iconPath
     *            水印图片路径
    * @param srcImgPath
     *            源图片路径
    * @param targerPath
     *            目标图片路径
    * @param degree
     *            水印图片旋转角度
    * @param width
     *            宽度(与左相比)
     * @param height
     *            高度(与顶相比)
     * @param clarity
     *            透明度(小于1的数)越接近0越透明
    */
    public static void waterMarkImageByIcon(String iconPath, String srcImgPath,
            String targerPath, Integer degree, Integer width, Integer height,
            float clarity) {
        OutputStream os = null;
        try {
            Image srcImg = ImageIO.read(new File(srcImgPath));
            System.out.println("width:" + srcImg.getWidth(null));
            System.out.println("height:" + srcImg.getHeight(null));
            BufferedImage buffImg = new BufferedImage(srcImg.getWidth(null),
                    srcImg.getHeight(null), BufferedImage.TYPE_INT_RGB);
            // 得到画笔对象
           // Graphics g= buffImg.getGraphics();
            Graphics2D g = buffImg.createGraphics();
            // 设置对线段的锯齿状边缘处理
           g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
                    RenderingHints.VALUE_INTERPOLATION_BILINEAR);
            g.drawImage(
                    srcImg.getScaledInstance(srcImg.getWidth(null),
                            srcImg.getHeight(null), Image.SCALE_SMOOTH), 0, 0,
                    null);
            if (null != degree) {
                // 设置水印旋转
               g.rotate(Math.toRadians(degree),
                        (double) buffImg.getWidth() / 2,
                        (double) buffImg.getHeight() / 2);
            }
            // 水印图象的路径 水印一般为gif或者png的,这样可设置透明度
           ImageIcon imgIcon = new ImageIcon(iconPath);
            // 得到Image对象。
           Image img = imgIcon.getImage();
            float alpha = clarity; // 透明度
           g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP,
                    alpha));
            // 表示水印图片的位置
            g.drawImage(img, width, height, null);
            g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER));
            g.dispose();
            os = new FileOutputStream(targerPath);
            // 生成图片
           ImageIO.write(buffImg, "JPG", os);
            System.out.println("添加水印图片完成!");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (null != os)
                    os.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    /**
     * 给图片添加水印、可设置水印图片旋转角度
    * 
     * @param logoText
     *            水印文字
    * @param srcImgPath
     *            源图片路径
    * @param targerPath
     *            目标图片路径
    * @param degree
     *            水印图片旋转角度
    * @param width
     *            宽度(与左相比)
     * @param height
     *            高度(与顶相比)
     * @param clarity
     *            透明度(小于1的数)越接近0越透明
    */
    public static void waterMarkByText(String logoText, String srcImgPath,
            String targerPath, Integer degree, Integer width, Integer height,
            Float clarity) {
        // 主图片的路径
       InputStream is = null;
        OutputStream os = null;
        try {
            Image srcImg = ImageIO.read(new File(srcImgPath));
            BufferedImage buffImg = new BufferedImage(srcImg.getWidth(null),
                    srcImg.getHeight(null), BufferedImage.TYPE_INT_RGB);
            // 得到画笔对象
           // Graphics g= buffImg.getGraphics();
            Graphics2D g = buffImg.createGraphics();
            // 设置对线段的锯齿状边缘处理
           g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
                    RenderingHints.VALUE_INTERPOLATION_BILINEAR);
            g.drawImage(
                    srcImg.getScaledInstance(srcImg.getWidth(null),
                            srcImg.getHeight(null), Image.SCALE_SMOOTH), 0, 0,
                    null);
            if (null != degree) {
                // 设置水印旋转
               g.rotate(Math.toRadians(degree),
                        (double) buffImg.getWidth() / 2,
                        (double) buffImg.getHeight() / 2);
            }
            // 设置颜色
           g.setColor(Color.red);
            // 设置 Font
            g.setFont(new Font("宋体", Font.BOLD, 30));
            float alpha = clarity;
            g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP,
                    alpha));
            // 第一参数->设置的内容,后面两个参数->文字在图片上的坐标位置(x,y) .
            g.drawString(logoText, width, height);
            g.dispose();
            os = new FileOutputStream(targerPath);
            // 生成图片
           ImageIO.write(buffImg, "JPG", os);
            System.out.println("添加水印文字完成!");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (null != is)
                    is.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
            try {
                if (null != os)
                    os.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

 

 

做到这几步,一般的安全问题就解决了,如果大家有更好的解决方案,欢迎一起讨论。

分享到:
评论

相关推荐

    js 上传文件校验文件类型和大小

    js 上传图片 校验 文件类型 大小js 上传图片 校验 文件类型 大小js 上传图片 校验 文件类型 大小 js 上传文件校验 js 上传文件校验 js 上传文件校验

    java实现上传文件类型检测过程解析

    Java 实现上传文件类型检测过程解析是指在进行文件上传时,对上传文件的格式进行控制,以防止黑客将病毒脚本上传。单纯的将文件名的类型进行截取的方式非常容易遭到破解,上传者只需要将病毒改换文件名便可以完成...

    MimeType文件校验demo

    MimeType文件校验是网络服务中常见的操作,特别是在处理用户上传的文件时,它能确保服务器正确地解析和处理文件。本示例"MimeType文件校验demo"提供了关于如何在Java环境中检查和验证MimeType的方法,特别提到了利用...

    文件传输与文件校验.pdf

    通过本次实验,学习者能够掌握使用md5sum进行文件校验的方法,同时理解了在Linux环境下如何利用命令行工具来完成文件的上传和下载,这是网络运维和系统管理员在实际工作中经常需要执行的技能。此外,此次实验还加深...

    奇安信代码卫士,文件上传漏洞解决demo

    (2)对上传文件后缀与MIME Type进行匹配校验, 对文件头信息与文件后缀进行匹配校验。 (3)对单个文件大小和总文件数进行限制, 避免拒绝服务攻击。 (4)对文件名进行输入校验,显示时进行输出编码。 3. 文件存储...

    ExtJS验证上传文件类型

    ExtJS 验证上传文件类型 ExtJS 中实现文件上传功能是非常方便的,但对于新手来说,控制文件上传类型是一个难题。例如,我们只想让用户上传特定的文件类型,例如txt文件,那么如何实现当用户上传非txt文件时,给出...

    netty4.0文件分片上传+断点续传+权限校验

    在本文中,我们将深入探讨如何利用Netty 4.0实现文件分片上传、断点续传以及权限校验的功能。 **文件分片上传** 文件分片上传是为了处理大文件传输时,避免一次性加载整个文件到内存中,从而减少内存消耗和提高...

    ssh2多文件的上传与下载

    Struts2+hibernate+spring实现多文件的上传与下载功能,主要包括:上传、下载、删除 1.能够对多个文件进行上传(可以选择上传文件个数,也即...文件上传是运用了Ajax技术对上传文件校验,判断数据库中是否存在该文件

    一个极度纯净的上传插件,支持多文件上传、上传速率动态控制、真实进度监控kb/s、分块生成MD5、分块上传、MD5校验秒传、暂停、取消等.zip

    一个极度纯净的上传插件,支持多文件上传、上传速率动态控制、真实进度监控kb/s、分块生成MD5、分块上传、MD5校验秒传、暂停、取消等。.zip,anyupload是一个极度纯净的上传插件,通过简单调整就可以融入到任何项目,...

    ftp.zip_ftp 文件续传_文件校验_断点传输

    在标题"ftp.zip_ftp 文件续传_文件校验_断点传输"中,涉及了几个关键概念,分别是FTP文件续传、文件校验以及断点传输。接下来,我们将深入探讨这些知识点。 1. FTP 文件续传: FTP文件续传是FTP服务的一个重要功能...

    java socket 传输文件时做和校验,校验位

    java socket在传输文件时,分包、组包和校验。 校验包数据,现成的代码可以拷贝直接运行。

    图片上传校验

    服务端可以验证请求的合法性,执行文件校验,以及存储文件。 7. **异步上传**:对于大文件,可以采用分块上传或者异步上传机制,提供更好的用户体验,同时减轻服务器一次性处理大文件的压力。 8. **权限控制**:在...

    Java防止文件被篡改之文件校验功能的实例代码

    "Java防止文件被篡改之文件校验功能的实例代码" 本文主要介绍了Java防止文件被篡改之文件校验功能,给大家分享了文件校验和原理及具体实现思路。文件校验和的主要作用是保证系统版本的正确性和唯一性。 文件校验和...

    网络C/S文件传输工具,支持`UDP/TCP`,断点续传,局域网探测,上传下载,文件校验:

    网络C/S文件传输工具,支持`UDP/TCP`,断点续传,局域网探测,上传下载,文件校验: 上传命令: $ file put //参数支持用-分割,也可直接输入 $ file -put //第三参数为空时,默认TCP上传方式 $ file put -tcp //...

    POI导入Excel并返回校验后的错误文件(原样)下载以及校验错误信息,同时加进度条

    POI导入Excel并返回校验后的错误文件(原样数据文件,并添加批注,注:由于批注只能加1000条,会在Excel后面添加一栏错误信息)下载以及页面展示校验错误信息,同时添加导入进度条,提供页面js和css代码,后端...

    ASP.NET 上传文件并验证文件真正的类型

    在ASP.NET中,上传文件是一项常见的任务,尤其是在处理用户提交的图像时。在这个场景中,我们不仅需要上传文件,还要确保文件的安全性,避免恶意用户上传非图片类型的文件。"ASP.NET 上传文件并验证文件真正的类型...

    文件/文本及文件夹的校验工具

    虽然MD5在早期被广泛用于文件校验,但由于碰撞攻击的可能性增加,其安全性也受到了质疑,如今也被认为不再适合安全用途。 文件夹校验工具不仅能够对单个文件进行哈希值计算,还能遍历整个文件夹及其子文件夹,对...

    基于sha256的cs架构的文件校验系统

    **基于SHA256的CS架构文件校验系统详解** 在信息安全领域,文件校验是确保数据完整性和防止篡改的重要手段。本文将详细介绍一种基于SHA256(安全哈希算法256位版本)的客户端-服务器(Client-Server,CS)架构的...

    自己重新封装的C# FTP实现上传,下载,创建文件,文件夹,删除单个文件 MD5校验等

    FTP客户端通常包括上传、下载、创建文件和文件夹、删除文件以及进行MD5校验等多种操作。以下将详细阐述这些知识点。 1. **FTP协议**:FTP是Internet上的标准协议,用于在不同主机之间交换文件。它基于TCP/IP协议栈...

    测试时校验文件上传的文件大于50M的word文件

    测试时校验文件上传的文件大于50M的word文件

Global site tag (gtag.js) - Google Analytics