chinabugotech/hutool · critical · InvalidClassException
Unauthorized deserialization attempt
Error message
Unauthorized deserialization attempt
What it means
When a white list is configured via accept(), ValidateObjectInputStream permits only those class names during deserialization. Any class not in the white list — including referenced superclasses, array element types, and standard JDK helper classes — throws InvalidClassException("Unauthorized deserialization attempt").
Source
Thrown at hutool-core/src/main/java/cn/hutool/core/io/ValidateObjectInputStream.java:92
/**
* 验证反序列化的类是否合法
* @param className 类名
* @throws InvalidClassException 非法类
*/
private void validateClassName(String className) throws InvalidClassException {
// 黑名单
if(CollUtil.isNotEmpty(this.blackClassSet)){
if(this.blackClassSet.contains(className)){
throw new InvalidClassException("Unauthorized deserialization attempt by black list", className);
}
}
if(CollUtil.isEmpty(this.whiteClassSet) || this.whiteClassSet.contains(className)){
return;
}
throw new InvalidClassException("Unauthorized deserialization attempt", className);
}
}
View on GitHub (pinned to 8870454b2a)
Solutions
- Add the missing class and all types it references to the white list via accept().
- If you do not want whitelist enforcement, simply do not call accept() — an empty/absent white list allows all classes.
- Audit the full object graph (inspect the serialized descriptor names) and register every class.
Example fix
// before: only the top type registered vois.accept(MyDto.class); MyDto o = (MyDto) IoUtil.readObj(vois, MyDto.class); // throws for nested Item // after: register the whole graph vois.accept(MyDto.class, Item.class, java.util.ArrayList.class); MyDto o = (MyDto) IoUtil.readObj(vois, MyDto.class);
Defensive patterns
Strategy: try-catch
Validate before calling
// Register the full object graph, not just the top type. vois.accept(MyDto.class, Item.class, java.util.ArrayList.class, "[Lcom.example.Item;"); // Or, to allow all classes, do not call accept() at all.
Try / catch
try {
return IoUtil.readObj(vois, clazz);
} catch (java.io.InvalidClassException e) {
// e.classname tells you which class is missing from the white list
vois.accept(Class.forName(e.classname)); // only if trusted
} Prevention
- Whitelist every class in the object graph: the top type, field types, superclasses, and array element types.
- Remember JDK helper classes (ArrayList, HashMap, etc.) must be allowed too.
- If whitelist enforcement is not wanted, simply do not call accept().
When it happens
Trigger: Deserializing an object whose class, or any class reachable in its graph (supertypes, field types, array types), is not present in the configured white list.
Common situations: White list too narrow: missing a referenced type, an array variant, a superclass, or JDK core classes; a new model class added but not registered; forgetting that nested objects pull in additional class names.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- Unauthorized deserialization attempt by black list
- Zip bomb attack detected, invalid sizes: compressed {}, unco
- Read limit exceeded
AI-assisted analysis of chinabugotech/hutool@8870454b2a (2026-08-14).
Data as JSON: /api/errors/2202aeeba510f93e.
Report an issue: GitHub.