For our technology stack, the answer is Fluent. Our localizations are as safe as the code that uses them, and we put all the learnings we have over the past 20 years into Fluent. Including a DOM creation logic that works on a whitelist of content. That said, even then you could write code that reads a string from localized content, and then does all kinds of tricks to circumvent our innerHTML protections, and shoot ourselves in the foot. Which goes to Dan's point earlier, don't assume that strings from l10n are safe, as a general engineering practice. Even more so perhaps with Fluent, because it's safe by default.
The migration of Firefox on to Fluent could happen quicker, but for that it probably would need to make it through product planning to get priority. Right now, it's not listed as a priority. If you'd like to help Romain to get it prioritized, that'd be great. In the past, we've delayed Fluent accepting the risks outlined in this bug. Notably, in December 2016 we (folks no longer at Mozilla) decided to pull Fluent out of the scope of Quantum.
As long as we have XUL documents loading DTDs, there's very little we can do. In particular, there's little we can do without breaking existing translations.
I agree with Dan that the main risk here comes from language packs generated in the wild and uploaded to AMO. As outlined above, our in-product hooks are already safe against those.
I have a few ideas:
Squat out space: The attacker uploaded a modified German language pack. Maybe we should look for ways to block people to submit language packs that look like ours. We have almost 100 languages, and if we only leave room for Valencian or Tatar, we seriously limit the ability for attackers to social engineer users to install malicious langpacks.
Harden the addons linter: That's a bit of an arms race, sadly. In particular hard to win, as the code of that linter is publicly available. Any attacker can just download the latest version and improve their obfuscation logic until they pass locally, and then upload. This is also tricky due to how Firefox is written. For DTDs, we know pretty well how the attack vectors look. But for .properties, we have a few of little or not-so-little js libraries that build stuff on top.