AutoMapper 16.3.0 and 15.1.4 Released with Security Fixes
Today I pushed out AutoMapper 16.3.0 and 15.1.4. Both releases fix two security issues, so if you're on either 16.x or 15.x, you should upgrade.
Security
Back in March, 16.1.1 fixed a denial of service issue where mapping a deeply nested, self-referential object graph could exhaust the stack (GHSA-rvv3-g6hj-g44x). The fix applied a default MaxDepth of 64 to self-referential maps, and setting MaxDepth yourself was the recommended mitigation.
It turned out that several mapping paths still didn't enforce MaxDepth. Mapping deeply nested data through any of them could still throw a StackOverflowException. You can't catch that exception, so it takes down the whole process.
Constructor parameters (GHSA-6vhm-j9h7-f9gh). When the destination is built through its constructor, as with positional records, MaxDepth was ignored completely. That held for both the default and an explicit value. Thanks to @mcambria, who found it while writing a test to confirm the MaxDepth mitigation actually worked, and reported it responsibly.
Other recursion paths (GHSA-gpwp-5797-mjff). While investigating that report, we went looking for other ways around MaxDepth and found a few:
- derived maps (
Include/IncludeBase) didn't inheritMaxDepth - members typed as
objector an interface didn't get the default limit - nested
Dictionary<string, object>andExpandoObjectsources weren't depth-tracked at all - recursive
ConvertUsingignoredMaxDepth
With these releases, derived maps inherit MaxDepth and get the default limit. Recursion that MaxDepth can't bound now fails with an InsufficientExecutionStackException instead of crashing the process.
That last part is a behavior change. If you map extremely deep graphs through those paths, you'll now get an exception where before you'd have gotten a process crash. I'll take a catchable exception over a dead process any day. Polymorphic graphs are also now cut off at the base map's MaxDepth, so if yours legitimately go deeper than 64 levels, set MaxDepth explicitly.
Applications that map untrusted, deeply nested input through these paths are the ones at risk. See the advisories for full details and workarounds.
Other fixes in 16.3.0
16.3.0 also picks up everything that's landed since 16.2.0:
- a fix for
Context.Items are only available...exceptions with self-referential maps, which depended on registration or warmup order (also backported to 15.1.4) - a 30-day renewal grace period for license keys, which logs a warning instead of an error
- clearer license validation messages for malformed keys and IdentityModel version mismatches
ConditiononForAllMembersnow receives the source member value rather than the converted one when the types differ, matching the documented behavior. A null in a nullable source member now shows up as null instead of0orfalse. This is a behavior change, so check any conditions that relied on
the old value.
Release notes:
NuGet:
Enjoy!