Skip to content

Commit

Permalink
Disable rpc.enhancedClasses by default at runtime
Browse files Browse the repository at this point in the history
Logs warnings at compile time, indicating which classes need to be
cleaned up to remove this feature.

Mitigation for gwtproject#9709
  • Loading branch information
niloc132 committed Dec 19, 2023
1 parent f439c5e commit 47a2b34
Show file tree
Hide file tree
Showing 6 changed files with 53 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -869,6 +869,10 @@ public SerializableTypeOracle build(TreeLogger logger) throws UnableToCompleteEx

if (tic.maybeEnhanced()
|| (enhancedClasses != null && enhancedClasses.contains(type.getQualifiedSourceName()))) {
logger.log(TreeLogger.WARN, "The class " + type.getQualifiedSourceName() + " is both " +
"referenced from configuration as rpc.enhancedClasses and has JPA annotations. " +
"This makes the server vulnerable to an issue with deserialization of unsafe " +
"data. See https://github.com/gwtproject/gwt/issues/9709 for more information.");
type.setEnhanced();
}
}
Expand Down
16 changes: 16 additions & 0 deletions user/src/com/google/gwt/user/server/rpc/RemoteServiceServlet.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
package com.google.gwt.user.server.rpc;

import static com.google.gwt.user.client.rpc.RpcRequestBuilder.MODULE_BASE_HEADER;
import static com.google.gwt.user.server.rpc.SerializationPolicyLoader.ENABLE_ENHANCED_CLASSES;
import static com.google.gwt.user.server.rpc.SerializationPolicyLoader.ENABLE_GWT_ENHANCED_CLASSES_PROPERTY;

import com.google.gwt.user.client.rpc.IncompatibleRemoteServiceException;
import com.google.gwt.user.client.rpc.RpcTokenException;
Expand Down Expand Up @@ -94,6 +96,20 @@ static SerializationPolicy loadSerializationPolicy(HttpServlet servlet,
try {
serializationPolicy = SerializationPolicyLoader.loadFromStream(is,
null);
if (serializationPolicy.hasClientFields()) {
if (ENABLE_ENHANCED_CLASSES) {
servlet.log("WARNING: Enhanced JPA client fields are in use for this " +
"application. See https://github.com/gwtproject/gwt/issues/9709 for " +
"more detail. on the vulnerability that this presents.");
} else {
servlet.log("ERROR: Service uses enhanced classes, which are unsafe. Review " +
"build logs to see where this can be fixed, or set " +
ENABLE_GWT_ENHANCED_CLASSES_PROPERTY + " to true to allow using this " +
"service. See https://github.com/gwtproject/gwt/issues/9709 for more " +
"detail.");
serializationPolicy = null;
}
}
} catch (ParseException e) {
servlet.log("ERROR: Failed to parse the policy file '"
+ serializationPolicyFilePath + "'", e);
Expand Down
10 changes: 10 additions & 0 deletions user/src/com/google/gwt/user/server/rpc/SerializationPolicy.java
Original file line number Diff line number Diff line change
Expand Up @@ -82,4 +82,14 @@ public abstract void validateDeserialize(Class<?> clazz)
*/
public abstract void validateSerialize(Class<?> clazz)
throws SerializationException;

/**
* Returns true if there may be any unsafe client fields in the serialization policy. The default
* implementation returns true to ensure that custom implementations validate accordingly.
*
* @return true if the client may send unsafely serialized data, false otherwise
*/
public boolean hasClientFields() {
return true;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,19 @@ public final class SerializationPolicyLoader {
*/
public static final String SERIALIZATION_POLICY_FILE_ENCODING = "UTF-8";

/**
* System property to enable gwt-rpc enhanced classes. To use this, set the JVM system property
* with name {@value ENABLE_GWT_ENHANCED_CLASSES_PROPERTY} to {@code true}, any other value will
* leave this feature disabled in the server at runtime.
*/
public static final String ENABLE_GWT_ENHANCED_CLASSES_PROPERTY = "gwt.enhancedClasses.enabled";

/**
* Flag to enable using enhanced classes, for applications that need them and are taking
* appropriate steps to secure them. Defaults to false.
*/
public static final boolean ENABLE_ENHANCED_CLASSES = "true".equals(System.getProperty(ENABLE_GWT_ENHANCED_CLASSES_PROPERTY));

private static final String FORMAT_ERROR_MESSAGE = "Expected: className, "
+ "[true | false], [true | false], [true | false], [true | false], typeId, signature";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -174,4 +174,9 @@ private boolean isInstantiable(Class<?> clazz) {
}
return SerializabilityUtil.hasCustomFieldSerializer(clazz) != null;
}

@Override
public boolean hasClientFields() {
return false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,11 @@ public Set<String> getClientFieldNamesForEnhancedClass(Class<?> clazz) {
return fieldNames == null ? null : Collections.unmodifiableSet(fieldNames);
}

@Override
public boolean hasClientFields() {
return clientFields != null && !clientFields.isEmpty();
}

public final String getTypeIdForClass(Class<?> clazz)
throws SerializationException {
return typeIds.get(clazz);
Expand Down

0 comments on commit 47a2b34

Please sign in to comment.