首页 > 其他分享 >记一个漏洞处理,SSH框架上传限制文件类型,以及关于文件上传安全问题的讨论

记一个漏洞处理,SSH框架上传限制文件类型,以及关于文件上传安全问题的讨论

时间:2023-11-17 17:14:32浏览次数:36  
标签:String new SSH file fi 文件类型 null 上传

-----------------------------------------------------------------------------------------------------------------------------------

与同事讨论的文件上传安全问题:

1.老项目采用的上传至项目下某个目录的做法是很不安全的,容易被访问到上传文件,应当制定到项目之外的目录.

2.如果只使用一次,比如上传Excel导入数据,则可以不将文件保存到磁盘.

3.限制文件类型使用 后缀名 判断即可,因为只要黑客可以操作修改后缀名了,那改文件头之类的也可以被改回.

4.条件允许的话使用 minio存储系统,设置token 和有效时间,可增强安全性

5.新型的攻击方式改为攻击防护薄弱的客户端

----------------------------------------------------------------------------------------------------------------------------------------------------------

背景:公司老项目,使用的一个基于SSH的老框架二次开发,原框架封装的上传类没有限制文件类型,等保评测查出需要整改

思路:因为原上传类封装在jar包中不好处理,所以在web.xml中将处理上传的类改为自己编写的类

即:

<servlet>
        <servlet-name>fileUpload</servlet-name>
        <!-- <servlet-class>com.htsoft.core.web.servlet.FileUploadServlet</servlet-class> -->
        <!-- 替换htsoft封装的原有上传方法,加入对文件类型的过滤,只允许上传几种文件,防止恶意上传可执行文件 -->
        <servlet-class>com.htsoft.core.web.servlet.FileUploadServletNew</servlet-class>
    </servlet>

上传处理类

public class FileUploadServletNew extends HttpServlet{
 
    private static final long serialVersionUID = 1L;

    private Log logger=LogFactory.getLog(FileUploadServletNew.class);
    
    @SuppressWarnings("unused")
    private ServletConfig servletConfig=null;
    
    private FileAttachService fileAttachService=(FileAttachService)AppUtil.getBean("fileAttachService");

    private AppUserService appUserService = (AppUserService)AppUtil.getBean("appUserService");
    
    private GlobalTypeService globalTypeService = (GlobalTypeService)AppUtil.getBean("globalTypeService");
    
    private String uploadPath=""; // 上传文件的目录   
    private String tempPath=""; // 临时文件目录 
    
    private String fileCat="others";
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("===========上传方法New===========");
        String flexUserId = req.getParameter("flexUserId"); // flex中获取登录用户的id
        String fileTypeId = req.getParameter("fileTypeId"); // 附件类型id
        GlobalType globalType = null;
        if(StringUtils.isNotEmpty(fileTypeId)){
            globalType = globalTypeService.get(new Long(fileTypeId));
        }
        //指定保存至某个目录,若提交时,指定了该参数值,则表示保存的操作 
        String filePath="";
        String fileId="";
        
        req.setCharacterEncoding("UTF-8");
        resp.setCharacterEncoding("UTF-8");
        try {
            
            DiskFileItemFactory factory = new DiskFileItemFactory();
            // 缓存大小
            factory.setSizeThreshold(4096);
            factory.setRepository(new File(tempPath));
            ServletFileUpload fu=new ServletFileUpload(factory);

            List<FileItem> fileItems = fu.parseRequest(req); 
            //取得相关参数值
            for(FileItem fi:fileItems){
                if("file_cat".equals(fi.getFieldName())){
                    fileCat=fi.getString();
                    //break;
                }
                if("file_path".equals(fi.getFieldName())){
                    filePath=fi.getString();
                }
                if("fileId".equals(fi.getFieldName())){
                    fileId=fi.getString();
                }
            }
            logger.info("fileId:" + fileId);
            Iterator<FileItem> i = fileItems.iterator();
            StringBuffer sb = new StringBuffer("");
            StringBuffer sb1 = new StringBuffer("");
            StringBuffer sb2 = new StringBuffer("");
            
            sb = new StringBuffer("{\"success\":\"true\"");
            sb.append(",\"fileId\":[");
            
            //目前处理每次只上传一个文件
            while(i.hasNext()) {
                FileAttach file=null;
                FileItem fi = (FileItem)i.next();
            
                if(fi.getContentType()==null){
                    continue;
                }
                
                //返回文件名及路径及fileId.
                String path = fi.getName();
                
                int start=path.lastIndexOf("\\");
                
                //原文件名
                String fileName=path.substring(start+1);
                
              //处理文件名,只允许xls,xlxs
                int hzmindex=fileName.lastIndexOf(".");
                String hzm = fileName.substring(hzmindex+1);
                if(!(hzm.equals("xls") || hzm.equals("xlsx"))){
                    System.out.println("=======文件类型错误,只允许上传Excel文件!========");
                    sb2.append("文件类型错误,只允许上传Excel文件!");
                    break;
                }
                
                
                String relativeFullPath=null;
                
                if(!"".equals(filePath)){
                    relativeFullPath=filePath;
                }
                else if(!"".equals(fileId)){
                  FileAttach fileAttach=fileAttachService.get(new Long(fileId));
                  relativeFullPath=fileAttach.getFilePath();
                  logger.info("exist filePath:" + relativeFullPath);
                }
                else{
                    relativeFullPath=fileCat+"/" + FileUtil.generateFilename(fileName);
                }
                
                int index=relativeFullPath.lastIndexOf("/");

                File dirPath=new File(uploadPath+"/" + relativeFullPath.substring(0,index+1));
                
                if(!dirPath.exists()){
                    dirPath.mkdirs();
                }

                fi.write(new File(uploadPath+"/" + relativeFullPath));
                
                if(!"".equals(filePath)){
                    file=fileAttachService.getByPath(filePath);
                    file.setTotalBytes(fi.getSize());
                    file.setNote(getStrFileSize(fi.getSize()));
                    fileAttachService.save(file);
                }
                if(!"".equals(fileId)){
                    file=fileAttachService.get(new Long(fileId));
                    file.setTotalBytes(fi.getSize());
                    file.setNote(getStrFileSize(fi.getSize()));
                    fileAttachService.save(file);
                }
                
                if(file==null) {
                    file=new FileAttach();
                    file.setCreatetime(new Date());
                    AppUser curUser = ContextUtil.getCurrentUser();
                    if(StringUtils.isNotEmpty("isFlex") && StringUtils.isNotEmpty(flexUserId)){
                        curUser = appUserService.get(new Long(flexUserId));
                    }
                    if(curUser != null){
                        file.setCreator(curUser.getFullname());
                        file.setCreatorId(curUser.getUserId());
                    } else {
                        file.setCreator("UNKown");
                    }
                    int dotIndex=fileName.lastIndexOf(".");
                    file.setExt(fileName.substring(dotIndex+1));
                    file.setFileName(fileName);
                    file.setFilePath(relativeFullPath);
                    file.setFileType(fileCat);
                    if(globalType == null){
                        globalType = globalTypeService.findByFileType(fileCat);
                    }  
                    if(globalType != null){                        
                        file.setGlobalType(globalType);
                    }
                    file.setTotalBytes(fi.getSize());
                    file.setNote(getStrFileSize(fi.getSize()));
                    file.setCreatorId(curUser.getUserId());
                    file.setDelFlag(FileAttach.FLAG_NOT_DEL);
                    FileAttach newFile = new FileAttach();
                    if(file.getTotalBytes()>0) {
                        //将文件信息存入数据库
                        newFile = fileAttachService.save(file);
                    }
                  //组建返回文件信息的json字符串
                    sb1.append(newFile.getFileId()+",");
                }
                
            }
            
            if(sb2.toString().equals("")){
            String str = sb1.substring(0, sb1.length()-1);
            if(str!=null&&(!str.equals("null"))&&str.length()>0) {
                sb.append(str);
            }
            sb.append("]}");
            }else{
                System.out.println("=======出错========");
                sb = new StringBuffer("{'success':false,'message':'"+sb2.toString()+"'}");
            }
            
            
            resp.setContentType("text/html;charset=UTF-8");
            PrintWriter writer = resp.getWriter();
            
            writer.println(sb.toString());
        }    
        catch(Exception e) {    
            resp.getWriter().write("{'success':false,'message':'error..."+e.getMessage()+"'}");
        }    
        
    }
    
    @Override
    public void init(ServletConfig config) throws ServletException {
        super.init(config);
        this.servletConfig=config;
    }
    
    public void init() throws ServletException {
       
        //初始化上传的路径及临时文件路径
        
        uploadPath=getServletContext().getRealPath("/attachFiles/");
        
        File uploadPathFile=new File(uploadPath);
        if(!uploadPathFile.exists()){
            uploadPathFile.mkdirs();
        }
        tempPath=uploadPath+"/temp";
        
        File tempPathFile=new File(tempPath); 
        if(!tempPathFile.exists()){
            tempPathFile.mkdirs();
        }
    }
    
    
    /*------------------------------------------------------------
    保存文档到服务器磁盘,返回值true,保存成功,返回值为false时,保存失败。
    --------------------------------------------------------------*/
    @SuppressWarnings("unused")
    public boolean saveFileToDisk(String officefileNameDisk)
    {
        File officeFileUpload = null;
        FileItem officeFileItem =null ;
        
        boolean result=true ;
        try
        {
            if(!"".equalsIgnoreCase(officefileNameDisk)&&officeFileItem!=null)
            {
                officeFileUpload =  new File(uploadPath+officefileNameDisk);
                officeFileItem.write(officeFileUpload);
            }
        }catch(FileNotFoundException e){
            
        }catch(Exception e){
            e.printStackTrace();
            result=false;
        }
        return result;    
    }
    
    private String getStrFileSize(double size){
        DecimalFormat df=new DecimalFormat("0.00");
        if(size>1024*1024){
             double ss=size/(1024*1024);
              return df.format(ss)+" M";
        }else if(size>1024){
            double ss=size/1024;
            return df.format(ss)+" KB";
        }else{
            return size+" bytes";
        }
    }

    
}

 

标签:String,new,SSH,file,fi,文件类型,null,上传
From: https://www.cnblogs.com/dirgo/p/17839189.html

相关文章

  • vue-富文本/自定义上传图片
    1、下载组件npminstallvue-quill-editor–D2、在需要的组件内引入富文本import{quillEditor}from'vue-quill-editor'import'quill/dist/quill.core.css'import'quill/dist/quill.snow.css'import'quill/dist/quill.bubble.css'com......
  • [转]SSH框架 Struts2 过滤特殊字符,防止xss攻击
    原文地址:基于Struts2修复XSS漏洞(博主验证有效)_struts2xss-CSDN博客1.编写XssFilterimportjava.io.IOException;importjavax.servlet.Filter;importjavax.servlet.FilterChain;importjavax.servlet.FilterConfig;importjavax.servlet.ServletException;importjavax.servl......
  • 实现多个大文件拖拽上传+大文件分片上传+断点续传+文件预览
    技术关键词前端:@vue/cli-service+element-ui+axios后端:node.js+koa思路分析拖拽上传拖拽上传是利用HTML5新特性实现拖拽上传,详细用法可阅读MDN-drag利用dragover事件(当某物被拖动的对象在另一对象容器范围内拖动时触发此事件)和drop事件(在一个拖动过程中,释放鼠标键时......
  • vue上传视频插件
    视频作为一种信息表达方式,越来越受到人们的关注和喜爱。近年来,随着移动互联网的普及,手机、平板电脑等设备可以随时随地观看视频。在开发网站或移动应用时,上传和展示视频成为一项不可或缺的功能。Vue作为一种现代化JavaScript框架,提供了丰富的开发工具和插件,其中视频上传插件是Vue开......
  • vue实现视频上传功能
    本文实例为大家分享了vue实现视频上传功能的具体代码,供大家参考,具体内容如下环境:vue+TS上传视频+上传到阿里云主要处理前端在vue下上传视频使用的是阿里云的视频点播服务1、需要后台去申请一个开发API,请求阿里云的接口访问控制2、有了开发视频的token,供给前端3、前端去请求阿......
  • 大文件上传的处理方法——切片上传
    本篇介绍了切片上传的基本实现方式,以及实现切片上传后的一些附加功能,切片上传原理较为简单,代码注释比较清晰就不多赘述了,后面的附加功能介绍了实现原理,并贴出了在原本代码上的改进方式。有什么错误希望大佬可以指出,感激不尽。切片后上传切片上传的原理较为简单,即获取文件后切片,切片......
  • 前端大文件上传如何做到刷新续传?
    前言这两天在学习阿里云oss上传。踩了不少坑,终于实现了大文件分片、断点续传的功能。这篇文章主要分享学习笔记,希望能给大家一些帮助。先看效果 技术栈1.前端:react+Ts+axios上传文件2.Node部分:定义接口、阿里云oss3.socket.io:实时同步上传进度特别说明axios中onUploadPr......
  • java如何做大体积的文件上传和下载
    在Java中,实现大体积文件的上传和下载涉及到处理文件的分片、并发上传、断点续传等问题。本文将详细介绍如何通过Java实现大体积文件的上传和下载。1.文件上传文件上传是将本地文件上传到服务器的过程。对于大体积文件的上传,我们可以将文件分成多个小片段进行并发上传。1.1文件分......
  • 前端如何实现大文件上传
    在开发过程中,经常会遇到一些较大文件上传,如果只使用一次请求去上传文件,一旦这次请求中出现什么问题,那么无论这次上传了多少文件,都会失去效果,用户则需要重新上传所有资源。所以就想到一种方式,将一个大文件分成多个小文件,这样通过多个请求实现大文件上传。接下来我们就来看看具体是怎......
  • 大文件断点续传上传
    最近接到一个新的需求,需要上传2G左右的视频文件,用测试环境的OSS试了一下,上传需要十几分钟,再考虑到公司的资源问题,果断放弃该方案。一提到大文件上传,我最先想到的就是各种网盘了,现在大家都喜欢将自己收藏的「小电影」上传到网盘进行保存。网盘一般都支持断点续传和文件秒传功能,减少......