这篇“Struts2漏洞如何修复”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Struts2漏洞如何修复”文章吧。
由于struts包由2.3.?升级到2.5.16,很多依赖包、配置需要响应调整。
1.2.5.X版本不再提供xwork.jar ,整合到了 struts-core包中。
2.方法不能访问的问题,需要在每个action配置文件中加上 strict-method-invocation="false":
<package name="login" namespace="/login" extends="struts-default" strict-method-invocation="false">
并修改strut2.xml配置文件头部为2.5版本的:
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN" "http://struts.apache.org/dtds/struts-2.5.dtd"><struts>
3.session失效的问题,针对weblogic server,增加session-descriptor节点:
<?xml version="1.0" encoding="UTF-8"?><weblogic-web-app xmlns="http://www.bea.com/ns/weblogic/90"><context-root>/ynwjnw</context-root><container-descriptor><servlet-reload-check-secs>-1</servlet-reload-check-secs><prefer-web-inf-classes>true</prefer-web-inf-classes></container-descriptor><session-descriptor><cookie-name>JSESSIONID1</cookie-name></session-descriptor></weblogic-web-app>
4.2.5.16版本jdk要求1.7。1.8版本编译后部署有问题
web.xml中
org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
修改为
org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter
5.struts2对multipart/form-data解析需要自定义方法解析,否则丢失表单参数。
<bean type="org.apache.struts2.dispatcher.multipart.MultiPartRequest" name="requestParser" class="com.***.omp.***.util.MyMultiPartRequest" scope="default"/>
由于xwork做了大改,AbstractMultiPartRequest类的一些属性和方法也修改了。MyMultiPartRequest类也需要相应调整。
import java.io.File;import java.io.IOException;import java.io.InputStream;import java.io.UnsupportedEncodingException;import java.util.ArrayList;import java.util.Collections;import java.util.Enumeration;import java.util.HashMap;import java.util.List;import java.util.Map;import java.util.Set; import javax.servlet.http.HttpServletRequest;import org.apache.commons.fileupload.FileItem;import org.apache.commons.fileupload.FileUploadBase;import org.apache.commons.fileupload.FileUploadException;import org.apache.commons.fileupload.RequestContext;import org.apache.commons.fileupload.disk.DiskFileItem;import org.apache.commons.fileupload.disk.DiskFileItemFactory;import org.apache.commons.fileupload.servlet.ServletFileUpload;import org.apache.logging.log4j.LogManager;import org.apache.logging.log4j.Logger;import org.apache.struts2.dispatcher.LocalizedMessage;import org.apache.struts2.dispatcher.multipart.AbstractMultiPartRequest;import org.apache.struts2.dispatcher.multipart.JakartaMultiPartRequest;import org.apache.struts2.dispatcher.multipart.StrutsUploadedFile;import org.apache.struts2.dispatcher.multipart.UploadedFile; public class MyMultiPartRequest extends AbstractMultiPartRequest{ static final Logger LOG = LogManager.getLogger(JakartaMultiPartRequest.class); // maps parameter name -> List of FileItem objects protected Map<String, List<FileItem>> files = new HashMap<String, List<FileItem>>(); // maps parameter name -> List of param values protected Map<String, List<String>> params = new HashMap<>(); // any errors while processing this request protected List<LocalizedMessage> errors = new ArrayList<LocalizedMessage>(); // protected long maxSize;// private Locale defaultLocale = Locale.ENGLISH; /** * Creates a new request wrapper to handle multi-part data using methods adapted from Jason Pell's * multipart classes (see class description). * @param saveDir the directory to save off the file * @param request the request containing the multipart * @throws java.io.IOException is thrown if encoding fails. */ public void parse(HttpServletRequest request, String saveDir) throws IOException { try { setLocale(request); processUpload(request, saveDir); } catch (FileUploadBase.SizeLimitExceededException e) { if (LOG.isWarnEnabled()) { LOG.warn("Request exceeded size limit!", e); } LocalizedMessage errorMessage = buildErrorMessage(e, new Object[]{e.getPermittedSize(), e.getActualSize()}); if (!errors.contains(errorMessage)) { errors.add(errorMessage); } } catch (Exception e) { if (LOG.isWarnEnabled()) { LOG.warn("Unable to parse request", e); } LocalizedMessage errorMessage = buildErrorMessage(e, new Object[]{}); if (!errors.contains(errorMessage)) { errors.add(errorMessage); } } } protected void setLocale(HttpServletRequest request) { if (defaultLocale == null) { defaultLocale = request.getLocale(); } } protected LocalizedMessage buildErrorMessage(Throwable e, Object[] args) { String errorKey = "struts.messages.upload.error." + e.getClass().getSimpleName(); LOG.debug("Preparing error message for key: [{}]", errorKey); return new LocalizedMessage(this.getClass(), errorKey, e.getMessage(), args); } private void processUpload(HttpServletRequest request, String saveDir) throws FileUploadException, UnsupportedEncodingException { for (FileItem item : parseRequest(request, saveDir)) { if (LOG.isDebugEnabled()) { LOG.debug("Found item " + item.getFieldName()); } if (item.isFormField()) { processNormalFormField(item, request.getCharacterEncoding()); } else { processFileField(item); } } } private void processFileField(FileItem item) { if (LOG.isDebugEnabled()) { LOG.debug("Item is a file upload"); } // Skip file uploads that don't have a file name - meaning that no file was selected. if (item.getName() == null || item.getName().trim().length() < 1) { LOG.debug("No file has been uploaded for the field: " + item.getFieldName()); return; } List<FileItem> values; if (files.get(item.getFieldName()) != null) { values = files.get(item.getFieldName()); } else { values = new ArrayList<FileItem>(); } values.add(item); files.put(item.getFieldName(), values); } private void processNormalFormField(FileItem item, String charset) throws UnsupportedEncodingException { if (LOG.isDebugEnabled()) { LOG.debug("Item is a normal form field"); } List<String> values; if (params.get(item.getFieldName()) != null) { values = params.get(item.getFieldName()); } else { values = new ArrayList<String>(); } // note: see http://jira.opensymphony.com/browse/WW-633 // basically, in some cases the charset may be null, so // we're just going to try to "other" method (no idea if this // will work) if (charset != null) { values.add(item.getString(charset)); } else { values.add(item.getString()); } params.put(item.getFieldName(), values); item.delete(); } private List<FileItem> parseRequest(HttpServletRequest servletRequest, String saveDir) throws FileUploadException { DiskFileItemFactory fac = createDiskFileItemFactory(saveDir); ServletFileUpload upload = new ServletFileUpload(fac); upload.setSizeMax(maxSize); // 设置监听器 FileUploadListener progressListener = new FileUploadListener(servletRequest); upload.setProgressListener(progressListener); return upload.parseRequest(createRequestContext(servletRequest)); } private DiskFileItemFactory createDiskFileItemFactory(String saveDir) { DiskFileItemFactory fac = new DiskFileItemFactory(); // Make sure that the data is written to file fac.setSizeThreshold(0); if (saveDir != null) { fac.setRepository(new File(saveDir)); } return fac; } /* (non-Javadoc) * @see org.apache.struts2.dispatcher.multipart.MultiPartRequest#getFileParameterNames() */ public Enumeration<String> getFileParameterNames() { return Collections.enumeration(files.keySet()); } /* (non-Javadoc) * @see org.apache.struts2.dispatcher.multipart.MultiPartRequest#getContentType(java.lang.String) */ public String[] getContentType(String fieldName) { List<FileItem> items = files.get(fieldName); if (items == null) { return null; } List<String> contentTypes = new ArrayList<String>(items.size()); for (FileItem fileItem : items) { contentTypes.add(fileItem.getContentType()); } return contentTypes.toArray(new String[contentTypes.size()]); } /* (non-Javadoc) * @see org.apache.struts2.dispatcher.multipart.MultiPartRequest#getFile(java.lang.String) */ public UploadedFile[] getFile(String fieldName) { List<FileItem> items = files.get(fieldName); if (items == null) { return null; } List<UploadedFile> fileList = new ArrayList<>(items.size()); for (FileItem fileItem : items) { File storeLocation = ((DiskFileItem) fileItem).getStoreLocation(); if (fileItem.isInMemory() && storeLocation != null && !storeLocation.exists()) { try { storeLocation.createNewFile(); } catch (IOException e) { LOG.error("Cannot write uploaded empty file to disk: {}", storeLocation.getAbsolutePath(), e); } } fileList.add(new StrutsUploadedFile(storeLocation)); } return fileList.toArray(new UploadedFile[fileList.size()]); } /* (non-Javadoc) * @see org.apache.struts2.dispatcher.multipart.MultiPartRequest#getFileNames(java.lang.String) */ public String[] getFileNames(String fieldName) { List<FileItem> items = files.get(fieldName); if (items == null) { return null; } List<String> fileNames = new ArrayList<String>(items.size()); for (FileItem fileItem : items) { fileNames.add(getCanonicalName(fileItem.getName())); } return fileNames.toArray(new String[fileNames.size()]); } /* (non-Javadoc) * @see org.apache.struts2.dispatcher.multipart.MultiPartRequest#getFilesystemName(java.lang.String) */ public String[] getFilesystemName(String fieldName) { List<FileItem> items = files.get(fieldName); if (items == null) { return null; } List<String> fileNames = new ArrayList<String>(items.size()); for (FileItem fileItem : items) { fileNames.add(((DiskFileItem) fileItem).getStoreLocation().getName()); } return fileNames.toArray(new String[fileNames.size()]); } /* (non-Javadoc) * @see org.apache.struts2.dispatcher.multipart.MultiPartRequest#getParameter(java.lang.String) */ public String getParameter(String name) { List<String> v = params.get(name); if (v != null && v.size() > 0) { return v.get(0); } return null; } /* (non-Javadoc) * @see org.apache.struts2.dispatcher.multipart.MultiPartRequest#getParameterNames() */ public Enumeration<String> getParameterNames() { return Collections.enumeration(params.keySet()); } /* (non-Javadoc) * @see org.apache.struts2.dispatcher.multipart.MultiPartRequest#getParameterValues(java.lang.String) */ public String[] getParameterValues(String name) { List<String> v = params.get(name); if (v != null && v.size() > 0) { return v.toArray(new String[v.size()]); } return null; } /* (non-Javadoc) * @see org.apache.struts2.dispatcher.multipart.MultiPartRequest#getErrors() */ public List<LocalizedMessage> getErrors() { return errors; } /** * Returns the canonical name of the given file. * * @param filename the given file * @return the canonical name of the given file */// private String getCanonicalName(String filename) {// int forwardSlash = filename.lastIndexOf("/");// int backwardSlash = filename.lastIndexOf("\\");// if (forwardSlash != -1 && forwardSlash > backwardSlash) {// filename = filename.substring(forwardSlash + 1, filename.length());// } else if (backwardSlash != -1 && backwardSlash >= forwardSlash) {// filename = filename.substring(backwardSlash + 1, filename.length());// }// return filename;// } /** * Creates a RequestContext needed by Jakarta Commons Upload. * * @param req the request. * @return a new request context. */ private RequestContext createRequestContext(final HttpServletRequest req) { return new RequestContext() { public String getCharacterEncoding() { return req.getCharacterEncoding(); } public String getContentType() { return req.getContentType(); } public int getContentLength() { return req.getContentLength(); } public InputStream getInputStream() throws IOException { InputStream in = req.getInputStream(); if (in == null) { throw new IOException("Missing content in the request"); } return req.getInputStream(); } }; } /* (non-Javadoc) * @see org.apache.struts2.dispatcher.multipart.MultiPartRequest#cleanUp() */ public void cleanUp() { Set<String> names = files.keySet(); for (String name : names) { List<FileItem> items = files.get(name); for (FileItem item : items) { LOG.debug("Removing file {} {}", name, item ); if (!item.isInMemory()) { item.delete(); } } } } }
以上就是关于“Struts2漏洞如何修复”这篇文章的内容,相信大家都有了一定的了解,希望小编分享的内容对大家有帮助,若想了解更多相关的知识内容,请关注亿速云行业资讯频道。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。