CVE-2021-20289 - migrate from Resteasy jaxrs 3 to RESTEasy > 4.6.0 - resteasy

The vulnerability scan system detects a CVE regarding RestEasy 3.7.0: CVE-2021-20289
https://nvd.nist.gov/vuln/detail/CVE-2021-20289, which states RESTEasy should upgrade to above 4.6.0.Final. But, here comes the question: RESTEasy > 4 does not contains this submodule.
I noticed that in https://developer.jboss.org/en/resteasy/blog/2019/03/28/resteasy-4-is-coming-soon, it is stated that
the big resteasy-jaxrs and resteasy-client modules have been split into resteasy-core-spi, resteasy-client-api, resteasy-core and resteasy-client, with the first and second ones to be considered as public modules, for which we're expected to retain backward compatibility till next major release.
If I comment out the resteasy-jaxrs dependency from pom.xml, I will get error of cannot access class org/jboss/resteasy/microprofile/config/ResteasyConfigFactory. But I cannot find it in resteasy-core-spi or rest-client-api module. The nearest is resteasy-4.7.4.Final/resteasy-core-spi/src/main/java/org/jboss/resteasy/spi/config/ConfigurationFactory.java. But if the class name changed, there would not be easy migration. Or am I missing something?
Actually according to https://issues.redhat.com/browse/RESTEASY-2878, this CVE is fixed in 3.15.2. So I am lost.

At last I
migrate from resteasy 3 to 4, abandon resteasy-jaxrs and introduce resteasy-client-api and resteasy-client
switch from org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder to org.jboss.resteasy.client.jaxrs.internal.ResteasyClientBuilderImpl, even though it's under internal package, it's a public class and Javadoc does not suggest against using it directly. And this implementation is quite standard, and introduces the minimal fraction while migrating. I also compared the default values set in the class, such as connectionPoolSize and so on, they are the same as in resteasy-jaxrs 3.
The code change is minimal:
// before
private ResteasyClient client = new ResteasyClientBuilder()
.connectionPoolSize(CONNECTION_POOL_SIZE)
.build();
// after
private ResteasyClient client = new ResteasyClientBuilderImpl()
.connectionPoolSize(CONNECTION_POOL_SIZE)
.build();
And the provider:
I am receiving content type text/plain. In Resteasy-jaxrs 3, I used ResteasyJackson2Provider and it implements MessageBodyReader and MessageBodyWriter, and it worked. Now, in Restyeasy 4, the content type check seems to be stricter and isReadable() of this same named class only accepts Content-Type of null or contains json. As I receive text/plain, it no longer works.
For reading plain text, I suggest using StringTextStar. A new class in Resteasy 4.7.5, and it seems to work. Reading inputstream and write as string, just what I need. Check its impl.
ResteasyClient client1 = new ResteasyClient()
.register(new ResteasyJackson2Provider()) // for JSON
.build();
ResteasyClient client2 = new ResteasyClient()
.register(new StringTextStar()) // for text/plain
.build();
And the auto-closeable client:
Now you need to use try-finally or try-with-resources to close it. It will be closed automatically if you don't, but you receive a warning: Closing an instance of ApacheHttpClient43Engine for you and so.

Related

Cant use InternetAddress with umlauts anymore after switching to com.sun.mail:javax.mail

we recently switched from javax.mail:mail to com.sun.mail:javax.mail.
Since then the following code fails:
new InternetAddress("chr#möllers.de", false).validate();
Caught: javax.mail.internet.AddressException: Domain contains control or whitespace in string ``chr#möllers.de''
javax.mail.internet.AddressException: Domain contains control or whitespace in string ``chr#möllers.de''
The implementation of InternetAddress#validate() has obviously changed. A few additional lines concerning CRLF checks are followed by this snippet:
else if (c <= 040 || c >= 0177) {
throw new AddressException(
"Domain contains control or whitespace", addr);
Every char >= 177 is treated as control or whitespace - which is wrong, e.g. for umlauts (ö = 246).
So the exception message is misleading.
Did the change of validate() introduce a bug?
By now, Internet email addresses may contain umlauts encoded in punycode. Thats why i expected to be safe passing a string with umlauts.
Is InternetAddress intended to be used with an encoded String in this case?
Thanks in advance
Update to Bill Shannons answer
The nicely formatted Groovy script mentioned in my comment:
#GrabResolver(name='snapshots', root='https://maven.java.net/content/repositories/snapshots/', m2Compatible='true')
#Grab("com.sun.mail:javax.mail:1.6.0-SNAPSHOT")
import javax.mail.internet.InternetAddress
new InternetAddress("chr#möllers.de", false)
Update: test with latest snapshot
import org.junit.Test;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
public class ValidateEmailTest {
#Test
public void test() throws AddressException {
new InternetAddress("chr#möllers.de", true).validate();
new InternetAddress("chr#möllers.de", false).validate();
}
}
The test runs successfully (not throwing an AddressException) with the latest snapshot 1.6.0-SNAPSHOT that is currently from Tue Feb 21.
Use of non-ASCII characters in domain names requires support for RFC 6530, RFC 6531, and RFC 6532. Both the client and the server need to support these new standards. I've added such support to JavaMail 1.6; you can download a development SNAPSHOT release as described on the JavaMail web page. You need to ensure that the server supports the SMTPUTF8 extension, and you need to set the Session property mail.mime.allowutf8 to true.
If you're able to test this new support for internationalized email addresses using a real mail server, please let me know your experiences, good or bad, at javamail_ww#oracle.com. Thanks.

Objectify with Cloud Endpoints

I am using appengine cloud endpoints and objectify. I have previously deployed these endpoints before and now I am updating them and it is not working with Objectify. I have moved to a new machine and running latest appengine 1.8.6. Have tried putting objectify in the classpath and that did not work. I know this can work, what am I missing??
When running endpoints.sh:
Error: Parameterized type
com.googlecode.objectify.Key<MyClass> not supported.
UPDATE:
I went back to my old computer and ran endpoints.sh on same endpoint and it worked fine. Old machine has 1.8.3. I am using objectify 3.1.
UPDATE 2:
Updated my old machine to 1.8.6 and get same error as other machine. Leaves 2 possibilities:
1) Endpoints no longer support objectify 3.1
or
2) Endpoints have a bug in most recent version
Most likely #1...I've been meaning to update to 4.0 anyways...
Because of the popularity of Objectify, a workaround was added in prior releases to support the Key type, until a more general solution was available. Because the new solution is available, the workaround has been removed. There are two ways you can now approach the issue with the property.
Add an #ApiResourceProperty annotation that causes the key to be omitted from your object during serialization. Use this approach if you want a simple solution and don't need access to the key in your clients.
Add an #ApiTransformer annotation that provides a compatible mechanism to serialize/deserialize the field. Use this approach if need access to the key (or a representation of it) in your clients. As this requires writing a transformer class, it is more work than the first option.
I came up with the following solution for my project:
#Entity
public class Car {
#Id Long id;
#ApiResourceProperty(ignored = AnnotationBoolean.TRUE)
Key<Driver> driver;
public Key<Driver> getDriver() {
return driver;
}
public void setDriver(Key<Driver> driver) {
this.driver = driver;
}
public Long getDriverId() {
return driver == null ? null : driver.getId();
}
public void setDriverId(Long driverId) {
driver = Key.create(Driver.class, driverId);
}
}
#Entity
public class Driver {
#Id Long id;
}
I know, it's a little bit boilerplate, but hey - it works and adds some handy shortcut methods.
At first, I did not understand the answer given by Flori, and how useful it really is. Because others may benefit, I will give a short explanation.
As explained earlier, you can use #ApiTransformer to define a transformer for your class. This would transform an unserializable field, like those of type Key<myClass> into something else, like a Long.
It turns out that when a class is processed by GCE, methods called get{fieldName} and set{FieldName} are automatically used to transform the field {fieldName}. I have not been able to find this anywhere in Google's documentation.
Here is how I use it for the Key{Machine} property in my Exercise class:
public class Exercise {
#ApiResourceProperty(ignored = AnnotationBoolean.TRUE)
public Key<Machine> machine;
// ... more properties
public Long getMachineId() {
return this.machine.getId();
}
public void setMachineId(Long machineId) {
this.machine = new Key<Machine>(Machine.class, machineId);
}
// ...
}
Others already mentioned how to approach this with #ApiResourceProperty and #ApiTransformer. But I do need the key available in client-side, and I don't wanna transform the whole entity for every one. I tried replacing the Objectify Key with com.google.appengine.api.datastore.Key, and it looks like it worked just fine as well in my case, since the problem here is mainly due to that endpoint does not support parameterized types.

Using Objectify For retrieving from Datastore- Error :Did you forget to inherit required module

I am using Objectify for retrieving data From datastore in GWT,But i get the Following Error :
[ERROR] No source code is available for type
com.logins.entity.experts; did you forget to inherit a required
module?
I have Client->entity->Server and i did define the RPC properly with RemoteServicePath.
i intiaized the Rpc in client side
final findexpertAsync
finexp=(findexpertAsync)GWT.create(findexpert.class);
GWT compiler throws Error at the method i call,
finexp.expert(expnam, new AsyncCallback<ArrayList<experts>>()
Note:
1) findexpert and FindexpertAsync are the RPC interface which has a method for retriving data from datastore
2)com.logins.entity.experts:experts is a server class.
Any guesses where i am going wrong ?
All classes directly or indirectly referenced from the client must be part of the client source path. You can't access server-only code from GWT. In this case, class "experts" needs to be part of the GWT-compiled client code.
Also: You should capitalize Java class names.

Returning JSON from a RESTful service using CXF DOSGI

I have a simple service which is annotated with JAX-RS annotations and includes the #Produces("application/json") annotation. I have set up the following properties when I register the service (I am using DS but that shouldn't matter):
service.exported.interfaces -> *
service.exported.configs -> org.apache.cxf.rs
org.apache.cxf.rs.address -> myURI
When I run my application I can hit the URL, but my browser returns:
No message body writer has been found for response class MyClass.
My OSGi console displays:
Jan 11, 2012 2:29:48 PM org.apache.cxf.jaxrs.interceptor.JAXRSOutInterceptor writeResponseErrorMessage
WARNING: No message body writer has been found for response class MyClass.
I read the documentation and thought maybe I needed to register a JSON provider. In may Activator I added:
bundleContext.registerService(new String[] { "javax.ws.rs.ext.MessageBodyReader",
"javax.ws.rs.ext.MessageBodyWriter" },
new org.apache.cxf.jaxrs.provider.JSONProvider(), null);
but this has not made any difference.
How do I fix the "No message body writer has been found for response class MyClass." error message?
No message body writer means that your json provider does not understand how to marshal your class that you returned into JSON. If you are using the default JSONProvider, then you are using Jackson, which uses JAXB annotations. In other words, the class that you return should have a #XmlRootElement annotation on the class level.

Windows Phone 7 App Quits when I attempt to deserialize JSON

I'm developing my first windows phone 7 app, and I've hit a snag. basically it's just reading a json string of events and binding that to a list (using the list app starting point)
public void Load()
{
// form the URI
UriBuilder uri = new UriBuilder("http://mysite.com/events.json");
WebClient proxy = new WebClient();
proxy.OpenReadCompleted += new OpenReadCompletedEventHandler(OnReadCompleted);
proxy.OpenReadAsync(uri.Uri);
}
void OnReadCompleted(object sender, OpenReadCompletedEventArgs e)
{
if (e.Error == null)
{
var serializer = new DataContractJsonSerializer(typeof(EventList));
var events = (EventList)serializer.ReadObject(e.Result);
foreach (var ev in events)
{
Items.Add(ev);
}
}
}
public ObservableCollection<EventDetails> Items { get; private set; }
EventDetails is my class that wraps the json string. this class has to be correct because it is an exact copy of the class used by that website internally from which the json is generated...
I get the json string correctly from the webclient call (I read the memorystream and the json is indeed there) but as soon as I attempt to deserialize the string, the application exits and the debugger stops.
I get no error message or any indication that anything happen, it just stops. This happens if I type the deserialize method into the watch window as well...
I have already tried using JSON.net in fact I thought maybe it was a problem with JSON.net so I converted it to use the native deserializer in the .net framework but the error is the same either way.
why would the application just quit? shouldn't it give me SOME kind of error message?
what could I be doing wrong?
many thanks!
Firstly, the fact that you have some string there that looks like JSON does not mean that you have a valid JSON. Try converting a simple one.
If your JSON is valid, it might be that your JSON implementation does not know how to convert a list to EventList. Give it a try with ArrayList instead and let me know.
The application closes because an unhandled exception happens. If check the App.xaml.cs file you will find the code that closes your app. What you need to do is try catch your deserialization process and handle it locally. So most likely you have some JSON the DataContractJsonSerializer does not like. I have been having issue with it deserializing WCF JSON and have had to go other routes.
You may want to check to ensure your JSON is valid, just because your website likes it does not mean it is actually valid, the code on your site may be helping to correct the issue. Drop a copy of your JSON object (the string) in http://jsonlint.com/ to see if it is valid or not. Crokford (the guy who created JSON) wrote this site to validate JSON, so I would rely on it more than your site ;) This little site has really helped me out of some issues over the past year.
I ran into this same kind of problem when trying to migrate some existing WM code to run on WP7. I believe that the WP7 app crashes whenever it loads an assembly (or class?) that references something that's not available in WP7. In my case, I think it was Assembly.Load or something in the System.IO namespace, related to file access via paths.
While your case might be something completely different, the symptoms were exactly the same.
The only thing I can recommend is to go through the JSON library and see if it's referencing base classes that are not allowed in WP7. Note that it doesn't even have to hit the line of code that's causing the issue - it'll crash as soon as it tries to hit the class that contains the bad reference.
If you can step into the JSON library, you can get a better idea of which class is causing the problem, because as soon as the code references it, the whole app will crash and the debugger will stop.

Resources