Dependencies should be nailed to versions and upgraded conservatively. The default shouldn't be the latest and greatest, it should be the last thing that worked.
If semantic versioning always behaved as it should be, the default shouldn't be the last thing that worked but rather the major/minor version of the last thing that worked followed by the latest and greatest patch version.
The exploit in question specifically relied on this expectation, by creating a new patch release for the exploit. Even if you could trust well-intentioned maintainers to use it correctly, there's always this risk.
Stack (https://docs.haskellstack.org/en/stable/README/) for Haskell solves this problem by maintaining sets of curated version numbers that are known to work together.