这篇“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漏洞如何修复”这篇文章的内容,相信大家都有了一定的了解,希望小编分享的内容对大家有帮助,若想了解更多相关的知识内容,请关注亿速云行业资讯频道。
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。