Graylog2 / Graylog2/graylog2-server
`FallbackConfig` classes are broken, causing crashes when MongoDB contains unknown polymorphic types
- Dominant language
- Java
- Stars
- 8.1k
- Forks
- 1.1k
- Avg merge
- 1d 20h
- Merged PRs (30d)
- 217
Description
### Description
Several interfaces use Jackson's `@JsonTypeInfo(defaultImpl = FallbackConfig.class)` to gracefully handle unknown type discriminators during deserialization from MongoDB. However, all `FallbackConfig` implementations are broken and **crash during deserialization itself**, defeating their purpose entirely.
The combination of `visible = true` (which passes the `"type"` property through to the deserialized object) and `FallbackConfig` having zero `@JsonProperty` fields causes Jackson to throw `UnrecognizedPropertyException` every time:
```
Caused by: com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException:
Unrecognized field "type" (class EventProcessorConfig$FallbackConfig),
not marked as ignorable (0 known properties: ])
```
MongoJack wraps this as `RuntimeException("IOException encountered while parsing")`, which surfaces as a 500 error to the user.
### Impact
This affects any scenario where MongoDB contains a polymorphic config type the running code doesn't recognize:
- **Version downgrade** (newer version wrote a type the older version doesn't know)
- **Plugin removal** (a plugin registered a type, then was uninstalled)
- **License tier change** (enterprise type exists in DB but enterprise plugin not loaded)
The crash is especially severe in bulk read paths like `EventDefinitionFacade.listEntityExcerpts()`, which streams ALL event definitions to build a title catalog for the start page. One unknown document kills the entire stream, breaking unrelated functionality (favorites, recent activity, last opened).
### Reproduction
1. Run Graylog 7.1 (which creates `traffic-v1` and `native-anomaly-v1` event definitions via migrations)
2. Downgrade to Graylog 7.0
3. Open the start page
4. All three start page widgets fail with `{"type":"ApiError","message":"IOException encountered while parsing"}`
### Root cause
`EventProcessorConfig.FallbackConfig` (and all other `FallbackConfig` classes) cannot be deserialized because:
1. `@JsonTypeInfo(visible = true)` passes the `"type"` field through to the target object
2. `FallbackConfig` has no `@JsonProperty` fields and no `@JsonIgnoreProperties(ignoreUnknown = true)`
3. Jackson rejects the unknown `"type"` property with `UnrecognizedPropertyException`
Additionally, even if deserialization succeeded, every method throws `UnsupportedOperationException`, and no code anywhere checks `instanceof FallbackConfig`.
### Affected classes
**High risk** (have `streamAll()` or bulk operations where one bad document kills everything):
| Interface | Collection | File |
|---|---|---|
| `EventProcessorConfig.FallbackConfig` | `event_definitions` | `EventProcessorConfig.java` |
| `JobDefinitionConfig.FallbackConfig` | `scheduler_job_definitions` | `JobDefinitionConfig.java` |
| `AuthServiceBackendConfig.FallbackConfig` | `auth_service_backends` | `AuthServiceBackendConfig.java` |
| `TeamSyncBackendConfig.FallbackConfig` | `team_sync_backend_configs` | `TeamSyncBackendConfig.java` |
**Lower risk** (only single-document or filtered reads):
| Interface | Collection | File |
|---|---|---|
| `ActionConfig.FallbackConfig` | N/A (not persisted) | `ActionConfig.java` |
| `ScannerConfig.FallbackConfig` | `vulnerability_scanners` | `ScannerConfig.java` |
| `AssetImportBackendConfig.FallbackConfig` | `asset_import_backend_configs` | `AssetImportBackendConfig.java` |
| `AssetSourceBackendConfig.FallbackConfig` | `asset_source_backend_configs` | `AssetSourceBackendConfig.java` |
| `AssetEventSubtypeConfig.FallbackConfig` | nested in `event_definitions` | `AssetEventSubtypeConfig.java` |
| `AssetEventProcessorState.FallbackConfig` | `asset_event_state` | `AssetEventProcessorState.java` |
| `RcfEventProcessorState.FallbackConfig` | unknown | `RcfEventProcessorState.java` |
### Proposed fix
**1. Fix all `FallbackConfig` classes so they can actually deserialize:**
- Add `@JsonIgnoreProperties(ignoreUnknown = true)`
- Store the type string so `type()` returns the actual unknown type instead of throwing
**2. Harden bulk read paths** (the four high-risk sites):
Filter out `FallbackConfig` instances in `streamAll()` consumers, or add a MongoDB-level `$in` filter on `config.type` to only fetch documents with known types.
### Workaround
Delete event definitions with unknown types from MongoDB, e.g.:
```javascript
db.event_definitions.deleteMany({"config.type": {$in: ["traffic-v1", "native-anomaly-v1"]}})
```
Contributor guide
Assessment
This issue has not been assessed yet.