The importance of `final` for security

When creating a Swift class or actor, if you don't intend to override any of the functions in that class you should use the final keyword. Here's an example of why this is important:

Notice that the attacker did not even need to match the function name. Swift uses a dynamic lookup table for non-final classes to identify where the implementation of a function is located.

Since world() is the first function of the Hello class, and notSoFast() is the first function of the Hack class, when the hello instance type is changed to Hack and we call the world() function on it, underneath Swift will retrieve the first function implementation of the dynamic lookup table of the Hack class, and end up executing notSoFast() instead of world().

When you use final(), Swift will directly refer to the implementation of world() and skip the dynamic lookup table. Making your code safer from attackers.


Edit: As pointed out by several in the community, this "trick" is mostly prevented by Swift Whole Module optimization (-wmo or -whole-module-optimization). Provided your libraries and your application have the right build settings, the role of final keyword is mostly to prevent other developers from extending your classes.

I greatly appreciate the interest this generated in the community. And hopefully this allowed many of you to learn more about Swift dynamic lookup and class handling.

You can read more about Whole Module Optimization at https://www.swift.org/blog/whole-module-optimizations/