Jackson Deserialization Validation
SkillDev toolsSecuring Jackson JSON deserialization by validating input before processing and preventing unknown properties.
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the Jackson Deserialization Validation skill
What this skill tells your AI
The instructions your AI receives, as published by cxcscmu/skilllearnbench in skills/b1-one-shot-claude-haiku-4-5/fix-security-bug/jackson-deserialization-validation/SKILL.md and read by ahel’s review.
Vulnerability Pattern
When Jackson deserializes JSON with unknown properties, if not handled properly, malicious extra properties can bypass validation logic:
{
"validProperty": "legitimate value",
"": {
"enabled": true,
"other": "malicious"
}
}
The empty key "" can be overlooked by simple property checks.
Jackson Configuration
1. Fail on Unknown Properties
@JsonIgnoreProperties(ignoreUnknown = false)
public class MyFilter {
@JsonProperty
private String function;
// This will throw exception on unknown properties
}
2. Custom Deserialization
@JsonDeserialize(using = CustomDeserializer.class)
public class MyFilter {
// Custom logic during deserialization
}
3. @JsonAnySetter for Validation
public class MyFilter {
@JsonProperty
private String function;
@JsonAnySetter
public void handleUnknown(String key, Object value) {
if (key == null || key.isEmpty()) {
throw new IllegalArgumentException("Empty property keys not allowed");
}
// Validate other unknown properties
}
}
Validation Strategies
Strategy 1: Whitelist Allowed Keys
private static final Set<String> ALLOWED_KEYS =
Set.of("function", "type", "name");
@JsonAnySetter
public void handleProperty(String key, Object value) {
if (!ALLOWED_KEYS.contains(key)) {
throw new IllegalArgumentException(
"Unknown property: " + key);
}
}
Strategy 2: Reject Empty/Null Keys
@JsonAnySetter
public void validateKey(String key, Object value) {
if (key == null || key.trim().isEmpty()) {
throw new IllegalArgumentException(
"Property keys cannot be empty or null");
}
}
Strategy 3: Post-Deserialization Validation
@JsonProperty
private Map<String, Object> properties;
@PostConstruct
public void validate() {
for (String key : properties.keySet()) {
if (key == null || key.isEmpty()) {
throw new IllegalArgumentException(
"Empty keys not allowed");
}
}
}
Implementation in Druid
Finding Vulnerable Classes
- Search for
@JsonTypeName("javascript") - Look for JavaScript filter/transform specs
- Check deserialization of filter objects
Key Locations
JavaScriptFilter.java- Main JavaScript filter class- Filter spec handlers in indexing-service
- Transform spec deserialization
Fix Pattern
@JsonIgnoreProperties(ignoreUnknown = false)
public class JavaScriptFilter {
@JsonProperty
private String function;
@JsonAnySetter
public void handleUnknown(String key, Object value) {
throw new IllegalArgumentException(
"Unknown property '" + key +
"' in JavaScript filter specification");
}
}
Testing the Fix
Test Case 1: Valid Request
String json = "{\"type\":\"javascript\",\"function\":\"function(){return true;}\"}";
JavaScriptFilter filter = mapper.readValue(json, JavaScriptFilter.class);
// Should succeed
Test Case 2: Empty Key (Should Fail)
String json = "{\"type\":\"javascript\",\"function\":\"...\",\"\":{\"enabled\":true}}";
assertThrows(JsonMappingException.class, () ->
mapper.readValue(json, JavaScriptFilter.class));
// Should throw exception
Test Case 3: Null Key (Should Fail)
String json = "{\"type\":\"javascript\",null:{\"value\":\"bad\"}}";
assertThrows(JsonMappingException.class, () ->
mapper.readValue(json, JavaScriptFilter.class));
Druid-Specific Considerations
- Custom ObjectMapper: Druid may use custom ObjectMapper configuration
- Multiple Filter Types: Fix may need to apply to multiple filter classes
- Backward Compatibility: Ensure legitimate requests still work
- Nested Specs: Check if transformSpec or other nested objects also need fixes
Recommended Approach
- Use
@JsonIgnoreProperties(ignoreUnknown = false)to detect unknown properties - Add
@JsonAnySetterto validate property names - Reject any empty string keys explicitly
- Test both via HTTP API and direct deserialization
Signals
- GitHub stars
- 83
- Forks
- 5
- Last commit
- Jul 2026
Advanced
- Catalog kind
- skill
- Gateway key
jackson-deserialization-validation- Source
- github.com/cxcscmu/skilllearnbench