41 lines
1.7 KiB
Java
41 lines
1.7 KiB
Java
// Apache Struts2 Jakarta multipart parser — pre-CVE-2017-5638 (S2-045).
|
|
// The error-message branch evaluates user-controlled Content-Type as an
|
|
// OGNL expression for "helpful" exception formatting. Attacker controls
|
|
// the Content-Type header → controls the OGNL string → RCE.
|
|
|
|
package org.apache.struts2.dispatcher.multipart;
|
|
|
|
import com.opensymphony.xwork2.util.LocalizedTextUtil;
|
|
import org.apache.commons.fileupload.FileUploadException;
|
|
|
|
import javax.servlet.http.HttpServletRequest;
|
|
import java.util.Locale;
|
|
|
|
public final class JakartaMultiPartRequest {
|
|
|
|
public void parse(HttpServletRequest req, String saveDir) throws FileUploadException {
|
|
try {
|
|
parseUploadInternal(req, saveDir);
|
|
} catch (FileUploadException e) {
|
|
// BUG: attacker-controlled Content-Type flows into LocalizedTextUtil
|
|
// which evaluates ${...} / %{...} as OGNL — bypassing all
|
|
// type/security restrictions, running arbitrary Java.
|
|
String contentType = req.getContentType();
|
|
String errorMessage = LocalizedTextUtil.findText(
|
|
getClass(),
|
|
"struts.messages.upload.error.InvalidContentTypeException",
|
|
Locale.ENGLISH,
|
|
"Unable to parse Content-Type " + contentType,
|
|
new Object[] { contentType }
|
|
);
|
|
throw new FileUploadException(errorMessage, e);
|
|
}
|
|
}
|
|
|
|
private void parseUploadInternal(HttpServletRequest req, String saveDir) throws FileUploadException {
|
|
// ...real parsing happens here, but invalid Content-Types throw the
|
|
// FileUploadException caught above.
|
|
throw new FileUploadException("invalid boundary");
|
|
}
|
|
}
|