Classloader vulnerability reproducing procedure in struts 1.1 - security

In Struts1, I heard that there is a classloader vulnerability issue which is cause by CVE-2014-0114. But I am unable to reproduce this respect to my project. Can anyone help me how to reproduce this issue. I googled but not get any procedure of reproducing.
I am using struts-1.1, Jboss -4.2.3.GA, Apache 2.2.0, MySql 5.0.37, JKMod, JDK 1.6.0_12, Ant 1.7.0 for my web project.

Try to invoke a URL which is mapped to a struts action (backed by an action form). The framework will try to populate your form bean from query parameters. So if you have a query parameter like ?class.classLoader.defaultAssertionStatus=true, it translates to formBean.getClass().getClassLoader().setDefaultAssertionStatus(true).
If you have enabled debug logging, you would see the following messages:
2014-05-05 12:57:50,238 DEBUG [org.apache.struts.action.RequestProcessor] Populating bean properties from this request
2014-05-05 12:57:50,238 DEBUG [org.apache.commons.beanutils.BeanUtils] BeanUtils.populate(com.xxx.struts.demo.web.form.SimpleForm#71909bc, {class.classLoader.defaultAssertionStatus=[Ljava.lang.String;#a6b23fd4})
2014-05-05 12:57:50,238 DEBUG [org.apache.commons.beanutils.BeanUtils] setProperty(com.xxx.struts.demo.web.form.SimpleForm#71909bc, class.classLoader.defaultAssertionStatus, [true])
2014-05-05 12:57:50,246 DEBUG [org.apache.commons.beanutils.BeanUtils] Target bean = com.ibm.ws.classloading.internal.AppClassLoader#3ac10955
2014-05-05 12:57:50,246 DEBUG [org.apache.commons.beanutils.BeanUtils] Target name = defaultAssertionStatus
2014-05-05 12:57:50,250 DEBUG [org.apache.commons.beanutils.ConvertUtils] Convert string 'true' to class 'boolean'
2014-05-05 12:57:50,250 DEBUG [org.apache.commons.beanutils.ConvertUtils] Using converter org.apache.commons.beanutils.converters.BooleanConverter#de2943ef
2014-05-05 12:57:50,250 DEBUG [org.apache.commons.beanutils.PropertyUtils] setSimpleProperty: Invoking method public void java.lang.ClassLoader.setDefaultAssertionStatus(boolean) with value true (class java.lang.Boolean)

I have tried in more than 2 ways to reproducing purpose. It works fine.
http://127.0.0.1:8080/MyFormGroupEditSection.do?com.macao.DelphyHacker.Marathonclass.marathonId=34&groupId=862
http://127.0.0.1:8080/MyFormGroupEditSection.do?class.classLoader=true&groupId=862
For solution purpose of this problem, I want to add some comments. You can follow this 2 links. Hopefully, it will help you to eradicate this problem.
http://h30499.www3.hp.com/t5/HP-Security-Research-Blog/Protect-your-Struts1-applications/ba-p/6463188#.U2J7xeaSxro
http://mail-archives.apache.org/mod_mbox/struts-announcements/201405.mbox/%3C53629980.8060805%40apache.org%3E

A Metasploit-based exploit is available on GitHub: https://github.com/rapid7/metasploit-framework/blob/master/modules/exploits/multi/http/struts_code_exec_classloader.rb and also at http://downloads.securityfocus.com/vulnerabilities/exploits/65999.rb.
See http://www.rapid7.com/db/modules/exploit/multi/http/struts_code_exec_classloader for reference.

Further to the solutions above I wanted to point out that adding a breakpoint in the ClassLoader at the line defaultAssertionStatus = enabled; within setDefaultAssertionStatus and a watcher at the line private boolean defaultAssertionStatus = false; is a great way of verifying if the above url modification: ?class.classLoader.defaultAssertionStatu‌​s=true has worked your defaultAssertionStatus should now be true.
Hope this helps!

Something like this works to test (in code at least)
try {
PropertyUtils.getNestedProperty(this, "class");
Logger.error(this, "SECURITY ISSUE- `class` attribute NOT DISABLED for BeanUtil introspection, See: CVE-2014-0114 ");
} catch (java.lang.NoSuchMethodException nse) {
Logger.info(this, "`class` is disabled as a property for introspection in struts for security");
} catch (Exception e) {
Logger.warn(this, e.getMessage(), e);
}

Related

submitForm() not defined for myfaces.JSF_JS_MODE 'minimal-modern'

I tried to set up a simple JSF 2.2 application using MyFaces 2.2.8.
Since MyFaces has some context parameters that I never used before, I tried to get familiar with those.
So I got to use org.apache.myfaces.JSF_JS_MODE for the first time and ran into problems with h:commandLink.
The commandLink is trying to call myfaces.oam.submitForm() which is not defined if I set the mode to minimal-modern.
If I set the mode to minimal or normal it works.
From reading some internet articles I assume this is a bug because submitForm is neither part of jsf-legacy.js nor jsf-i18n.js nor jsf-experimental.js and it apparently is needed by h:commandLink.
Also the source code comment of org.apache.myfaces.shared.renderkit.html.util.ResourceUtils.markScriptAsRendered(FacesContext, String, String) tells me
oamSubmit script is included inside jsf.js
here:
public static void markScriptAsRendered(FacesContext facesContext, String libraryName, String resourceName)
{
getRenderedScriptResources(facesContext).put(
libraryName != null ? libraryName+'/'+resourceName : resourceName, Boolean.TRUE);
if (JAVAX_FACES_LIBRARY_NAME.equals(libraryName) &&
JSF_JS_RESOURCE_NAME.equals(resourceName))
{
// If we are calling this method, it is expected myfaces core is being used as runtime and note
// oamSubmit script is included inside jsf.js, so mark this one too.
getRenderedScriptResources(facesContext).put(
MYFACES_LIBRARY_NAME+'/'+MYFACES_JS_RESOURCE_NAME, Boolean.TRUE);
}
}
What am I missing here? Thanks in advance!
I can confirm it is a bug. Solved in MYFACES-4034 for 2.2.10

Rendering GORM classes from Spring Boot

I'm trying to write a simple Spring Boot controller that renders a GORM instance and failing.
Here's a shortened version of my code:
#RestController
#RequestMapping("/user")
class UserController {
#RequestMapping(value='/test', method=GET)
User test() {
return new User(username: 'my test username')
}
}
I get the following error message:
Could not write JSON: No serializer found for class org.springframework.validation.DefaultMessageCodesResolver and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) ) (through reference chain: users.domain.User["errors"]->grails.validation.ValidationErrors["messageCodesResolver"]); nested exception is com.fasterxml.jackson.databind.JsonMappingException: No serializer found for class org.springframework.validation.DefaultMessageCodesResolver and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) ) (through reference chain: users.domain.User["errors"]->grails.validation.ValidationErrors["messageCodesResolver"])
The error seems to be caused by extra properties injected by GORM. What is the proposed solution for this? Will this eventually be solved in gorm-hibernate4-spring-boot? Should I simply disable SerializationFeature.FAIL_ON_EMPTY_BEANS (I don't have a lot of experience with Jackson so I'm not entirely sure what side effects this may have)? Should I use Jackson's annotations to solve the problem? Any other options?
I've found a way to get rid of the error using this code:
#Component
class ObjectMapperConfiguration implements InitializingBean {
#Autowired
ObjectMapper objectMapper
#Override
void afterPropertiesSet() {
def validationErrorsModule = new SimpleModule()
validationErrorsModule.addSerializer(ValidationErrors, new ErrorsSerializer())
objectMapper.registerModule(validationErrorsModule)
}
}
class ErrorsSerializer extends JsonSerializer<ValidationErrors> {
#Override
void serialize(ValidationErrors errors, JsonGenerator jgen, SerializerProvider provider) {
jgen.writeStartObject()
jgen.writeEndObject()
}
}
Obviously this solution is far from perfect as it simply nukes all validation errors but right now it is good enough for me. I am pretty sure the Spring Boot team will have to address this issue eventually as the GORM objects are also being serialized with some internal Hibernate properties like attached. I'm not accepting this answer as it is not an acceptable solution for most scenarios, it basically just squelches the exception.
This did not work for me.
So I used this instead and the error disappeared.
#JsonIgnoreProperties(["errors"])
I'm using springBootVersion '1.4.1.RELEASE' with gorm & hibernate5:
compile("org.grails:gorm-hibernate5-spring-boot:6.0.3.RELEASE")
I am having to include the following at the top of each domain class in order to use them in a client response (i.e. json serialization using jackson):
#JsonIgnoreProperties(["errors", "metaClass", "dirty", "attached", "dirtyPropertyNames"])
When using springBootVersion '1.3.5.RELEASE' I was able to get away with:
#JsonIgnoreProperties(["errors"])
This is trending in the wrong direction :)

RESTEasy, CDI, embedded Jetty, bean validation is ignored

I've a Groovy project where I use RESTEasy with Weld and deploy to embedded Jetty. What I can't seem to get working is bean validation. RESTEasy documentation says that adding resteasy-validator-provider-11 along with hibernate validator dependencies (hibernate-validator, hibernate-validator-cdi, javax.el-api, javax.el) is enough. But the bean validation is simply ignored by RESTEasy. I curiously also get the following message in the logs:
plugins.validation.ValidatorContextResolver - Unable to find CDI supporting ValidatorFactory. Using default ValidatorFactory
Based on the suggestions on [this][1] post, I tried registering Hibernate InjectingConstraintValidatorFactory in META-INF/validation.xml but it depends on a BeanManager being injected and blows up at runtime.
The code can be found here https://github.com/abhijitsarkar/groovy/tree/master/movie-manager/movie-manager-web
A log gist is here: https://gist.github.com/anonymous/8947319
I've tried everything under the sun without any success. Pls help.
To do this without EE, I believe you'll need to fork the existing InjectingConstraintValidatorFactory but instead of using injection of the bean manager, use the CDI 1.1 class CDI to get a reference to the bean manager, e.g. CDI.current().getBeanManager(). http://docs.jboss.org/cdi/api/1.1/javax/enterprise/inject/spi/CDI.html
You do need to be on CDI 1.1 to do this (so Weld 2+, 2.1.1 is current I believe). Here's an example impl, based on: https://github.com/hibernate/hibernate-validator/blob/master/cdi/src/main/java/org/hibernate/validator/internal/cdi/InjectingConstraintValidatorFactory.java
public class InjectingConstraintValidatorFactory implements ConstraintValidatorFactory {
// TODO look for something with better performance (HF)
private final Map<Object, DestructibleBeanInstance<?>> constraintValidatorMap =
Collections.synchronizedMap( new IdentityHashMap<Object, DestructibleBeanInstance<?>>() );
private final BeanManager beanManager;
public InjectingConstraintValidatorFactory() {
this.beanManager = CDI.current().getBeanManager();
Contracts.assertNotNull( this.beanManager, "The BeanManager cannot be null" );
}
#Override
public <T extends ConstraintValidator<?, ?>> T getInstance(Class<T> key) {
DestructibleBeanInstance<T> destructibleBeanInstance = new DestructibleBeanInstance<T>( beanManager, key );
constraintValidatorMap.put( destructibleBeanInstance.getInstance(), destructibleBeanInstance );
return destructibleBeanInstance.getInstance();
}
#Override
public void releaseInstance(ConstraintValidator<?, ?> instance) {
DestructibleBeanInstance<?> destructibleBeanInstance = constraintValidatorMap.remove( instance );
destructibleBeanInstance.destroy();
}
}
I finally fixed this. Turns out, a validation.xml is not really required, resteasy-cdi module does a fine job of registering the BeanManager. What I was missing and not clearly documented anywhere, is that if an annotation is placed on a method, the validation engine just "decides" what should be validated. I placed a #NotNull on a method and it was validating the return type, not the parameters. One can use validationAppliesTo element in some cases but #NotNull doesn't have it. When I moved it from the method to the parameter, it started working.
Now I ran across what I believe is a Weld bug but I'll post that question separately.

Accessing methods from imported jars in managed beans

I'm sure I'm missing something, but I'm not seeing it at all.
I'm creating PDFs using iText, and I want to do this in a bean. I've created one, but it's been erroring out. It seems some of the ways I've usually worked in Java don't seem to work in this bean.
For example, this line:
com.itextpdf.text.Document document1 = new com.itextpdf.text.Document();
will throw the error java.lang.NoClassDefFoundError: com.itextpdf.text.Document, even though the jar is imported, in the build path and com.itextpdf.text.Document is imported in the bean.
if you change it to this:
com.itextpdf.text.Document document1;
or
com.itextpdf.text.Document document1 = null;
the error goes away. I don't understand why one way works and the other doesn't, but it's a fairly easy change to make.
Now I need to set the page size. This will work in Eclipse:
document1.setPageSize(PageSize.LETTER);
but this is the error I get:
java.lang.NoClassDefFoundError: com.itextpdf.text.PageSize
Which might be because I've set it to null to initialize it. But
document1 = new Document();
and
document1 = new com.itextpdf.text.Document();
both throw java.lang.NoClassDefFoundError: com.itextpdf.text.Document
Oddly, the import statement for (iText) Document warns me it is never used.
document1.open();
will give the error java.lang.NoClassDefFoundError: com.itextpdf.text.Document as well.
So, am I missing something in the syntax in beans? I've created Notes Java agents, XAgents, and straight up Java Eclipse projects that work, but I can't get the methods to work in a 8.5.3 Java Bean. I imported the iText jars into WebContent\WEB-INF\lib and then added those (via add jars, not add external jars) to the build path. I've gotten the latest jars and I'm using them, I've built and cleaned, the bean is in faces-config. But I'm doing something wrong, and I can't see it.
If someone could point me in the right direction, I would be very grateful.
Cheers,
Brian
EDIT:
The license isn't a problem, but I still can't get the class to load even using the classLoader:
Thread currentThread = Thread.currentThread();
ClassLoader clCurrent = currentThread.getContextClassLoader();
//ClassLoader clCurrent=com.ibm.domino.xsp.module.nsf.NotesContext.getCurrent().getModule().getModuleClassLoader();
try {
currentThread.setContextClassLoader(Activator.class.getClassLoader());
DebugToolbar.get().info("after setting up FileOutputStream");
com.itextpdf.text.Document document1 = new com.itextpdf.text.Document();
//com.itextpdf.text.Document document1;
//com.itextpdf.text.Document document1 = null;
//document1 = new com.itextpdf.text.Document();
//document1.open();
document1.setPageSize(PageSize.LETTER);
I still get java.lang.NoClassDefFoundError: com.itextpdf.text.Document
I've cut the beans out, cleaned, built, pasted back in, cleaned built, still the error.
I appreciate the assistance.
Brian
Most likely you have a classloader isssue. Unless your app is strictly for internal use, you might reconsider use of iText since it is GPL. Apache PDFBox is an Apache licensed alternative (I'm particularly fond of) or Apache FOP (I'll complete the ]2 missing articles](http://www.wissel.net/blog/htdocs/DominoXSLT), promise). Of course OpenNTF's POI4XPages might just be what you need.
I called Lotus/ICS support. It seems for 8.5.3, if you put the jars in ~Lotus\Notes\jvm\lib\ext they will load. I'm testing this on my local, but the same path should work on the server. I'll test that Monday. I had researched, and if that is mentioned I didn't find it. Jars will be a design element in 9, putting them in a directory like this should not be needed for that version, but it seems that adding them this way is more consistent now. The jars have loaded properly for some applications I've made, so this confused me a bit.
Stephan and Panu, thank you for responding.
Brian

Multiple Threads in Xpages

I have a problem and hoped somone could help me
I'm trying to start multiple threads from an XAgent (not rendered XPage)
public class ImportThread extends NotesThread {
Session currentSession;
public ImportThread(String maildb, String Server)
{
try{
currentSession =DominoAccess.getCurrentSession();
this.maildb = currentSession.getDatabase(Server, maildb);
}catch (Exception e) {
e.printStackTrace();
}
}
public void runNotes()
{
View v = maildb.getView("$Calendar");
}
in this version I could not access the View I only get "null" back
Ive tryed a version with Java Threads not realy better.
thean i've found something on Openntf
http://www.openntf.org/internal/home.nsf/project.xsp?action=openDocument&name=Threads%20and%20Jobs
but there I got an "AccessControl Exception"
I have no more ideas, I hope that someone has an idea how to create
an XAgent with multiple thread
As Egor wrote you need the change the Java policy file if you run the Java code from an NSF. You don't have to do this if you deploy your Java code as OSGi plugin. See the documentation of that OpenNTF project.
Afaik NotesObjects should not be shared between threads. So instead of using Database mailDB you should use String mailDBName and instantiate all NotesObjects inside their own thread. You also need to watch run time: if your XAgent waits for the treads to conclude, you should be fine, but if it is a 'fire-and-forget' approach you need to start it from something more persistent like a managed bean in the session scope.
Hope that helps

Resources