oblac / jodd

Jodd! Lightweight. Java. Zero dependencies. Use what you like.

Home Page:https://jodd.org

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Jvm killed by request parameter that change interal representation of String

KarolBedkowski opened this issue · comments

Hello,
Problem detected during migration some code from Jodd 4.x to 5.x.
Tested on version 5.0.10, app based on Joy.
Version 4.x is not affected.

Current behavior

Wrong/prepared request query parameter name can kill jvm.

Example 1:

@Action
public TextResult execute(@In final String action) {
...
}

Request /execute?action.value= (empty value) create String object with internal field value = null, and crash whole jvm with i.e, siginfo: si_signo: 11 (SIGSEGV), si_code: 1 (SEGV_MAPERR) on String::equal, String::length or similar.
This same method can change internal hash value of string, etc.

Example 2:

@Action
public void execute(@In final SomeClass action) {
}

class SomeClass {
 @In("param.value")
String param;
...
}

Request /execute?action.param.value= - also set SomeClass::param to invalid string;
In this case, change field name to i.e. paramValue solve problem.

Expected behavior

Internal representation of basic types like String should not be changed by request parameters.

Steps to Reproduce the Problem

Create simple action with one String parameter a and i.e. log this parameter.
Call this action with query ?a.value=.

wow, Jodd killed JVM :) I am on this!

Some more informationen would be nice:

  • OS
  • Java Version
  • any special Java Flags are set? (like -XX ....)
  • mini example project to reproduce your issue easily

Thanx!

Hi,
Sample project https://github.com/KarolBedkowski/joddt1 (include some logs)
Test with:
curl http://localhost:8080/userAjax.actions.json?query.value=
curl http://localhost:8080/userAjax.actions.json?dt.search.value=

OS: Debian Stable + OpenJDK 1.8; Debian SID + OpenJDK 11.0.3+4-1 / OpenJDK 8u212-b01-1 / Oracle JDK 1.8.0_102-b14 ; Windows 7 + Oracle Java 8

No special flags, env variables.

Tested with jetty maven plugin (jetty:run) and Tomcat 8.5.20 (deployed war).

Ok, so here is what is going on.

Calling the action.value where action is a String will actually try to set the value field of a String. This is not something you would like to do :)

Why do you call /execute?action.value=? You should call just /execute?action=.

On the other hand, I guess Jodd should prevent such cases. So this is the issue with the BeanUtil.

Test to recreate:

	static class Foo {
		public String s;
	}

	@Test
	void testString() {
		final Foo foo = new Foo();
		BeanUtil.declaredForced.setProperty(foo, "s.value", null);
	}

I guess we can add a check for core Java classes (if they are from java.* package)

I agree - it's wrong call, I found this by accident (DataTable send ajax request with parameters like dt.search.value, and I have class with only "String search;"). In Jodd4 - this request don't generate any errors (I'm not sure in this moment, but I guess this simple work (.value was ignored)). But in Jodd5 I have crash.
But user/error in code can generate bad request like this. So this should be somehow handled IMHO.

Thanks.

Yes, it is an easy fix at the end. No fields will be accessible for java.* classes.

And thank you very much for reporting @KarolBedkowski! The fix is on the way, and I will release fixed Jodd until Monday! :)