Video hosted by Apple at devstreaming-cdn.apple.com

Configure player

Close

WWDC Index does not host video files

If you have access to video files, you can configure a URL pattern to be used in a video player.

URL pattern

preview

Use any of these variables in your URL pattern, the pattern is stored in your browsers' local storage.

$id
ID of session: meet-with-apple-278
$eventId
ID of event: meet-with-apple
$eventContentId
ID of session without event part: 278
$eventShortId
Shortened ID of event: meet-with-apple
$year
Year of session: 2026
$extension
Extension of original filename: mp4
$filenameAlmostEvery
Filename from "(Almost) Every..." gist: ...

Meet with Apple • Session 278

Protect your app with Enhanced Security

2026-03-06 • 48:41

Learn how Enhanced Security in Xcode provides powerful tools to protect your apps from memory safety vulnerabilities. Explore how Apple applies defensive strategies across our platforms, including attack surface reduction, hardware mitigations, and containment with Enhanced Security Extensions. Discover how to enable these capabilities in your Xcode projects and establish an effective security engineering strategy.

This session was originally presented as part of the Meet with Apple event “Fortify your app: Essential strategies to strengthen security.” Watch the full video for more insights and related sessions.

Speakers: Mark Mitchell, Devin Coughlin

Open in Apple Developer site

Part of: Fortify your app: Essential strategies to strengthen security

Transcript

Good morning. I’m Mark Mitchell from Apple’s security, engineering and architecture team, along with my colleague Devin. I’m going to describe today a framework for how you can protect your apps from memory safety vulnerabilities, the careful layering and combination of the strategies that Devin and I will talk about today is what has earned iPhone its reputation as the most secure consumer device available. Throughout today’s sessions, we’ll talk about what these features are, what they’re for, and give you examples of how Apple uses them to protect our apps, the OS, and customers. With Xcode, you can now use the same technologies that Apple employs to protect users of your apps.

Apps touch many parts of our lives. They’re essential tools that everyone trusts with their private details, location, browsing, history, photos, messages, finances, and. At the same time, these apps and users are connected to the internet, and so security vulnerabilities in them can open users up to attack. The cost of these attacks range from fraud and identity theft through to blackmail, and even in rare circumstances, threats in the physical world. People expect their data to be kept private and secure, and it’s a violation of trust if that promise isn’t upheld. Security is the technical foundation that enables privacy.

I’ll begin with an overview of what memory safety means and the different types of vulnerabilities it can lead to. Next, I’ll provide a high level overview of some security engineering strategies that you can use to protect your apps and describe how we’ve successfully employed them in ours. And finally, Devin will show you how you can put these strategies into practice with Xcode using the enhanced security capability.

So what do we mean by memory safety? Well, memory safety bugs are one of the most common classes of vulnerability in software, where the attacker relies on memory corruption to change or subvert program behavior. At Apple, security engineers think about memory safety in terms of intended and unintended behavior in the program.

For typical usage, the program works the way the developer intends and only performs actions that make sense. So you can think of the flow through a program kind of like a maze. The path through the maze is the code. The developer intends to be used for some operation, and the other routes represent code paths that aren’t used or reachable. And the unreachable paths could be in frameworks that you’re not using that do things like turn on the camera or send an email.

Attackers can take advantage of those memory safety vulnerabilities to try to trick the program into an unexpected state that lets them perform very different actions than the developer actually intended. In this example, a memory safety vulnerability anywhere along the intended path leads to whole new ways to solve the maze or run code that aren’t intentional by making or taking new paths. And that could mean calling that code to force the app to turn on the camera or send an email.

Memory safety is foundational for security, and without it, we can’t guarantee the higher level security properties. For example, it doesn’t matter if how strong your password hashing scheme is. If an attacker can just gain access to the system by taking advantage of a memory safety vulnerability. Here’s an example. It’s a simple login function.

It takes a copy of the password in a text field from the user, checks if it’s a debug build, and skips authentication. So maybe the developer can test more quickly at their desk and calls a function to compare a copy of the password against some hardcoded secret, and returns the result of the login.

The particularly observant ones amongst. You might have noticed that giant red X. There is obviously a memory safety vulnerability in this code, and you really shouldn’t copy it here. The developer is allocating space for 32 characters on the stack to hold a copy of the password, but the copy API doesn’t know how much space is available, and it’ll copy as many characters as there are in that text field into the buffer that it’s given, and the result is a stack buffer overflow.

Behind the scenes in memory, this is roughly what’s happening. The local password storage is right before the memory used to hold the debug login flag. If the password is, say, 18 characters, of course it safely fits. But what if the attacker sends more than 32 characters? Well, in that case, because this program was written in a language that’s not memory safe, it will start to overwrite adjacent memory.

And here that’s that memory used to store the debug login flag And the result is that regardless of what the developer intended or passed into this function, when the program hits this if statement, if the value has been overwritten or changed by an attacker, they can force it to skip authentication and return true anyway.

But actually, there’s an even more serious problem in that code. Overwriting the debug flag can let the attacker log in without authentication, but in the memory, following the debug login flag is the address of the function pointer that the program will call to do its comparison. If an attacker supplies an even longer password, they can overflow out of the local password buffer over the debug login flag and change that that function pointer to anything they want.

And that means that when the program tries to call its compare function, it will actually be comparing. It’ll actually be calling any function of an attacker’s choosing. And now the attacker has full control over this process to reach any of these other code paths and potentially steal users data.

So that example is a buffer overflow, which is a violation of one of the properties of memory safety. But there are actually five axes bound. Safety ensures that all accesses to memory happen within the bounds of a memory allocation. Lifetime safety ensures that memory is only used whilst it’s valid and hasn’t been reused for something else. Type safety ensures that programmers can’t accidentally access memory through a different type than was intended. Guaranteed initialization ensures that memory is initialized before it’s used. And finally, thread safety ensures that different threads can’t stomp on each other’s memory.

So here’s what an attack tends to look like. Generally, an attacker targeting any app will be looking to not only access data from that app or compromise an and access data from that app, but we’ll use that as a step, first step in a chain of bugs that goes on to attack other system components, even elevate privileges to the kernel in order to undermine the platform security model, because they’re looking to not only access files from across the system, but also other assets like location data, photos, contacts, microphone. So apps are often the front door to the rest of the larger attack.

At the same time, modern applications offer so much functionality that many of them have been granted access to most of these assets in normal use. As the OS continues to evolve its security posture, it’s reasonable for us to expect that in the future, attackers might be content to just exploit your apps and collect the data that they’ve got access to from that environment, and not need to move on to the rest of the platform.

And that’s why it’s really important that we’re now all pushing forward together with security at the same time. Now I’m going to talk through the strategies in use at Apple to protect applications and services like messages, Safari and mail from memory safety vulnerabilities. In any sufficiently complicated code base. It’s accepted there will always be vulnerabilities. It’s gone too far.

And so at Apple, we rely on multiple layers of security engineering that layer and complement one another. There’ll be deep, deeper dives into many of the technologies that I’ll introduce throughout today, but I’m here to introduce the concepts, how Apple thinks about applying them, and some ways that you can assess their efficacy and the effort that will be required to use them in your applications. I’m going to talk about five strategies.

I’ll cover how to make memory safety vulnerabilities impossible in your code by using a memory usage language such as Swift. How to make vulnerabilities unreachable by reducing the available attack surface. Making vulnerabilities exploitable with mitigations. Containing the damage of an exploit if one happens. And finally, some techniques for finding and eliminating vulnerabilities from your code.

The most comprehensive approach to defending from memory safety vulnerabilities is to use a language that makes them almost impossible to create in the first place. Apple has invested heavily in Swift both as a secure and performant language, and it offers memory safety out of the box. It powers not only many of your applications, but also parts of our operating systems, and that includes more and more code bases that are critical to security, such as WebKit. Complex parsing, and even embedded environments like the Secure Enclave processes firmware.

Of course, many apps have large existing code bases written in the C family of languages. They are not memory safe. Enhanced security does provide tools such as F band safety and its annotations for C and C++ standard library hardening to help you reduce the risk of band safety errors. But think of them as a stepping stone on the way towards memory safety. They’re not the final goal because they don’t address those other four axes.

Comparing C based languages and Swift across those five axes, the C based languages offer none of these protections, whereas Swift provides bound safety through the use of bounds checked arrays and other swift standard library abstractions. It provides lifetime safety with automated reference counting and ownership. It guarantees type safety by requiring that casts are checked at runtime. Swift guarantees initialization by requiring you to initialize your variables before they’re used, and with swift concurrency, it provides thread safety by preventing data races.

So that’s a really quick tour on how to make memory safety vulnerabilities impossible. Check out the Writing Security Sensitive code in Swift session later for more information. The second strategy that Apple employs heavily in security critical code bases is known as attack surface reduction. And the theory here is that as developers and security engineers, you can’t know where all of the vulnerabilities in your code and the frameworks that you rely on might be. But you can limit the amount of code that an attacker can potentially reach to the minimum set required for your functionality. And that greatly reduces the chances that a vulnerability exists in the code that’s actually used in your app.

Apple uses this technique throughout the system in order to reduce the space an attacker has available to work in, and that ranges from technologies which restrict which complex document formats can be parsed to conditional functionality based on. If a counterparty is trusted through to disabling entire features in lockdown mode.

As an example of format restrictions, if you know that your app is only ever going to send and receive Jpeg images, then allowing your receiver side code to handle images of any other format exposes millions of lines of parsing code for an attacker to look for vulnerabilities in that it just doesn’t need to. So in that case, the best way to have an immediate impact and improve security would be checking for a well-formed Jpeg or configuring Core Graphics to only parse that format for your process and just drop the traffic if it doesn’t match what you expect.

Another place your app might be unintentionally exposing attack surface that isn’t strictly necessary is when rendering web content through web views that you use directly for things like in-app browsing and through frameworks that you might import from third parties like advertising SDKs. Starting in iOS 26.4, there are two powerful new options to WebKit called Enhanced Security Webviews, and these modes allow you to control your app, control the way that your app handles content from the web, with some additional security hardening.

By default, WebView offers all the power, functionality, and performance of WebKit right inside your app, while still providing all of Safari’s security mitigations and architecture. The first new mode restriction mode, Maximize compatibility maintains the full web compatibility that WebKit currently supports, whilst removing a large percentage of the complex framework code and increasing the use of the latest hardware security mitigations.

The second of these new modes, restriction mode lockdown, goes even further, and it gives you the ability to opt your apps K web views into the same extreme level of protection as lockdown mode, and it removes rarely used web technologies and further reduces options for an attacker. At Apple, we’ve begun adopting these enhanced security webviews throughout the OS, including for mail. Quick look. Captive portal shortcuts and Apple ads in iOS 26.4. And that’s a really good time for you to try them out to.

Attack surface reduction offers a huge return for security investment. But the assumption must still be that memory safety vulnerabilities will exist in any remaining code written in an unsafe language. In those cases, the next most effective defensive strategy is to impact the ability for a malicious actor to exploit those vulnerabilities.

We do that using a combination of technologies known as security mitigations and mitigations is a concept. Excuse me. Mitigations as a concept aren’t new. They’ve evolved and existed over the last 30 or 40 years, and Apple is constantly working to invent and provide new ones, and many have been available to your apps. And when we’re confident that they’re safe to use, even defaulted on in many cases without you having to do anything.

Mitigations range from early defenses against buffer overflows like clang stack protector to non-executable stacks and aslr right through to modern hardware assisted technologies like kernel integrity protection and fast permission restrictions. In Xcode 26, there are. There are new powerful software and hardware assisted mitigations that you can use to protect your apps.

Pointer authentication is a hardware technology assisted by the compiler. It can detect and prevent entire classes of vulnerabilities from being exploited, and provides enforcement that even if an exploit does occur, your app’s code flow integrity is maintained. Memory Integrity Enforcement, which launched with iPhone 17 and iPhone 17 Pro, is the result of five years of research, modeling and engineering and is built on the robust foundations provided by the secure allocators, coupled with enhanced memory tagging, extensions and security policies known as tag confidentiality enforcement.

That’s a lot, and there will be a lot more on those sessions. That will be a lot more on those mitigations in the Adopt memory integrity enforcement and pointer auth session later. And you can read all about me on the security.apple.com blog. Apple believe that memory integrity enforcement represents the most significant upgrade to memory safety in the history of consumer operating systems.

In rare circumstances, though, sophisticated attackers might still be able to find a vulnerability that can be reached and exploited despite our mitigations. In those cases, our final line of defense is known as containment. Consider the chain from earlier. In the scenario where the attacker has found and exploited a memory safety vulnerability in the app. They now have full control of it. The ideal goal would be to trap the attacker in an environment like this, so they can’t touch app data or the rest of the platform.

Now, since the very early days of iPhone, apps have run in a sandbox that helps to prevent malicious access and protect user data. The app, of course, can still access its own data and use system services that provide that power. The frameworks that the apps using against a highly sophisticated attacker, though an even more extreme level of isolation, is needed, it wouldn’t be possible to just disconnect a full app from the system like this.

They require too much access to do things like draw the UI or access resources to function in that kind of environment. And so a new approach is necessary in security critical apps like Messages and Safari. Apple has designed a multi-process architecture that moves processing of complex attacker supplied data into a heavily sandboxed environment with almost no access to system resources such as other services or even the kernel.

The result of that is that we can move the risk of unknown vulnerabilities into a place that, even in the event of a successful compromise, traps the attacker in an environment that’s devoid of assets like messages or cookies. The environment also has very few opportunities for finding options to elevate privileges and access user data with enhanced security. In Xcode 26, your apps can also make use of these, make use of these heavily constrained secure environments, and they’re called enhanced security extensions. I’ll go over how messages uses this architecture when it receives a photo.

So messages calls it security extension. The blast door and the security policy is simple. Treat all assets that are received as malicious until they’ve been parsed and broken down into primitive types or detonated inside the blast door. And this policy means that the messages app, which is higher privileged, only has to validate the simple types that it receives back from blast door, and the complex risky parsing happens at the lowest privilege.

So message arrives in over the internet into the messages app, which, without attempting to do any parsing or processing on it, sends it directly to blast door inside that secure blast door process. It’s time to begin to process and parse the image, which, remember, might have been sent by an attacker. Obviously, in the vast majority of cases, the image is valid and messages transcodes it from a potentially complex type into much simpler format that can be validated and used to display to the user.

In the case where the image is invalid, a failure occurs. A message is just drops the traffic. If an attacker is able to successfully exploit a vulnerability in blast, although that contained within that second process, which has no access to the messages database or the rest of the system.

So blast now needs to return its image to messages. And the important thing to remember here is that we should consider that security containment process might be compromised. And so any data leaving it and being returned to messages isn’t trustworthy. It could be the image that was successfully transcoded, or it could be entirely malicious data under the control of an attacker.

For that reason, the most important thing about this architecture is that message is safely and securely validates that the data it receives is a well-formed image and of the format that we expect, and that combines the previous strategies of both memory safe, swift and attack surface reduction. To do that validation safely and expose the minimum amount of code that’s necessary. Once the image has been validated, it’s safe to go ahead and show it in the transcript.

That’s just one example of how Apple uses containment in our most security sensitive code bases. Finally, the fifth option available is to find and eliminate as many vulnerabilities from code as possible whilst pursuing those other strategies on its own. That’s not sufficient to prevent attacks, but it can be effective at finding the weakest spots and identifying the lowest hanging fruit like attackers do.

At Apple, we employ a combination of manual and automated techniques to help us find vulnerabilities in our code. We conduct audits of code during development and retrospectively, and use the clang static analyzer to both aid human review and in continuous integration workflows. We make use of fuzzing, a technique where tools automatically generate many, many inputs to a program in an attempt to stumble across vulnerabilities, and tools like address sanitizer and thread sanitizer can help with not only debugging code, but also to proactively find vulnerabilities both during development and in conjunction with techniques like fuzzing.

So there’s a framework of how Apple thinks about layering approaches to memory safe code. And you can use all of the tools that I’ve just talked about to ideally make the bugs impossible by using a memory safe language like Swift make vulnerabilities unreachable by reducing the attack surface that’s available. Make vulnerabilities exploitable by applying mitigations to your code.

Contain the damage of an exploit if one happens by using an enhanced security extension to do your complex parsing. And finally, identify and eliminate as many of the bugs in your code as possible whilst you pursue those other strategies. Now I’ll hand over to Devon, who leads Apple’s development of languages and tools for security. Thank you.

Thanks, Mark. Hi, I’m Devin Coughlin. I lead the developer Security Tools Group at Apple. Xcode provides a carefully selected array of protections to give your app state of the art security. I’ll detail those individual protections, how to enable them, and describe how to combine them together to provide maximum protection.

Security is about navigating trade offs for memory safety. The most critical trade offs are the security benefit and the engineering effort, such as code changes and testing. Think about the trade off as a graph with benefit on the vertical axis and ease of adoption on the horizontal. Some protections are easy to apply but provide less benefit. Others are harder but give more security.

Navigating the trade offs is about expanding the least amount of effort while gaining the most benefit. That’s the sweet spot in the upper right hand corner. At Apple, our goal is to tightly co-design the hardware, the operating system and programming languages to provide protections near that sweet spot, all while maintaining good performance. For example, memory integrity enforcement has strong security at vastly lower adoption costs and higher performance than software only protections.

I’ll describe four different classes of protections. Bug finding tools that help you find security bugs before they even ship and prepare the way for stronger security adoptions. Whole app protections, which increase the security of your entire app, often with just the click of a button. Code hardening for C and C++, which will help you add bound safety to your existing unsafe code bases, and Swift, which provides full memory safety.

These are the same strategies that Mark described, but I’ll go into the actual technologies that you can use to run them. Mark ordered them from highest to lowest for new code bases. That’s where to start. Highest protection for the entire app from the beginning. But when retrofitting security onto an existing app that’s already under attack, it’s important to be strategic about which protections you can apply now and which will take some time. I will talk about them in order of adoption from quick security wins that are easier to deploy to. Incredibly strong protections that will take longer to put into practice. I’m here to help you navigate these different technologies so you can make your app as secure as possible.

I’ll start with bug finding tools. These aren’t active protections running in your released app. Instead, they’re used at build and debugging time to help you find bugs before they ship. They also pave the way for stronger adoption of technologies by finding bugs early. These tools lie in the lower right quadrant.

They’re easy to use. Just run them and start fixing the problems. They find actionable bugs, but they cannot find all of them. So although they’re an excellent preventative practice. It’s critical to adopt the other protections I’ll talk about later. The good news is that running these tools makes it easier to do that.

The first bug finding tools I’ll go over are the sanitizers. They recompile your app with extra instrumentation that helps find bugs as the app runs. They work for C based languages and Swift. And what’s great about the sanitizers is that they have very few false positives. If the sanitizers report a bug, there is a bug.

Address sanitizer finds memory safety bugs by tracking which memory locations are valid and invalid. It’s great at finding the buffer overflows of the kind that Mark showed earlier and use after free bugs, where the programmer frees memory but accidentally leaves a dangling pointer. It finds memory corruption on the heap and stack, as well as in globals.

It also provides backtraces where the memory was allocated and deallocated. To help you fix the bug quickly. Thread sanitizer finds data races which happen when one thread interferes with memory accessed by another thread without synchronization between the two. This can cause memory corruption even under automated reference counting.

Next is the clang static analyzer. It finds bugs without even needing to run your app. Instead, it simulates possible paths through the program. This means you don’t need to have test coverage to find a bug. But the trade off is that the tool may have false positives. That is, it may report a bug when there isn’t one. The analyzer supports C, C++, and Objective-C. It finds many security sensitive bugs, including buffer overflows, use after freeze, use of uninitialized memory, and insecure API use. Enable these checks in your target’s build settings and then run the analyzer by choosing analyze from the product menu.

When the analyzer finds a bug, it will display the issue and the control flow path along which it manifests. The arrows show each step in the program path leading up to the bug and notes describe key events along the path. For example, in a use. After free, the path shows where the memory is allocated, freed, and later used. This makes it easy to understand and fix the vulnerability.

Address sanitizer, thread sanitizer and the Clang Static analyzer are key bug finding tools to help you develop your code. Use them at build and test time. They’ll find some, but not all of your bugs. Running these tools are a great first step to make it easier to adopt stronger protections in your app. And to be clear, more needs to be done. But they do pave the way to adding additional essential protections.

Next, I’ll cover whole app protections. These provide an excellent baseline level of hardening for your entire app, including your code, libraries, and system frameworks. They’re easy to add and provide a very strong boost to security. I’ll cover five different whole app protections the typed allocator hardware, memory tagging, pointer authentication, read only memory and enhance security extensions.

The first whole app protection is the typed allocator. It’s a new system allocator that protects against use after free attacks. It’s fantastic because it lies near the sweet spot in the upper right corner. It has good protection and is extremely easy to adopt. Use after. Free bugs are a form of memory corruption, where the program allocates memory and then freeze it, but accidentally leaves a dangling pointer behind. The type of that freed memory is called the victim.

An attacker exploits the dangling pointer by manipulating the program to allocate another type. The aggressor in that same location, and then causing the victim pointer to access data from the aggressor as if it were of the victim type. This is type confusion. If the aggressor is able to trick the victim into retreating attacker attacker controlled data as a pointer, they can modify unintended memory or even call unexpected code.

With the typed allocator, the compiler and operating system work together to prevent type confusion by probabilistically allocating different types in different buckets of memory. The victim in aggressor allocations will likely be placed in different buckets, so attackers can’t rely on type confusion. There is an excellent post on the Apple Security Research blog towards the next generation of Xnu memory safety that goes into great detail about applying this approach to the kernel. To enable the typed allocator. Go to the Signing and Capabilities editor. Add the enhanced security capability and enable the build settings. Turn it on today. It provides very strong protection against use after free vulnerabilities. It’s as easy as checking a checkbox and recompiling your app.

The second type of whole app protections is hardware memory tagging. It’s extremely powerful against buffer overflows and use after free bugs and heap allocated memory. It’s a CPU feature designed to compose with the typed allocator and the kernel’s tag confidentiality to provide memory integrity enforcement. It’s available on iPhone 17, iPhone air, as well as M5 based Macs and Vision Pro. Hardware. Memory tagging lies very close to that sweet spot in the top right. It has high protection and is easy to adopt, all while maintaining low performance overhead.

Here’s how it protects against memory corruption. The typed allocator associates a tag with each pointer and each allocation. The CPU then ensures that the tag and the pointer and the tag in the memory match. If not, that indicates a use after free bug or a buffer overrun, so the hardware safely traps rather than allowing memory corruption.

Here’s an example with a buffer overflow. The victim pointer has a tag that matches the memory it points to, and the aggressor pointer does as well. With the buffer overrun, the attacker overflows via the aggressor pointer into the victim memory. But since the aggressor pointer has one tag and the victim memory has another, the CPU detects the mismatch rather than allowing the attack to continue.

Memory tag mismatches crash your app. So before enabling the protection test with memory tagging diagnostics enabled and also under Address Sanitizer and Thread sanitizer, then fix any memory corruption. To learn more about how to enable hardware memory tagging, watch Secure your App with Memory Integrity Enforcement on developer.apple.com.

Now, even with the secure allocator and hardware memory tagging enabled, some memory corruption bugs will still be exploitable. The third type of whole app protection is pointer authentication. With pointer authentication, the hardware, compiler, and operating system all work together to provide in-depth defense by enforcing the integrity of control in the app. It’s available on iPhone ten S and newer and in all Apple Silicon Macs.

In a control flow integrity attack, attackers hijack control of the app by taking advantage of memory corruption. This puts the program in an unexpected state the developer never intended. Recall the stack buffer overflow Mark described earlier, where the attacker overflowed a password buffer to overwrite a nearby function pointer.

By supplying an extra long password, the attacker could change the value of the function pointer to anything that they wanted. They could then call any function in the program, leading to an unexpected state. With pointer authentication. The CPU cryptographically signs pointers and authenticates them before they’re used. If the signature of the pointer doesn’t match what’s expected, the hardware will safely trap rather than calling unexpected code In the buffer overflow example. This will prevent attackers from calling an arbitrary function.

Pointer authentication composes nicely with memory integrity enforcement as a backstop of protection. It sits solidly in the center of the benefit adoption chart. It has good protection, but may require some work to adopt, especially in complex C++ code bases. So test your app thoroughly after enabling to make sure you don’t have crashes. And since it’s most effective when used in combination with the typed allocator and hardware memory tagging, adopt those first before tackling pointer authentication.

It requires building a universal binary one that has both arm64 and arm64 e slices so that your app can run on older devices without hardware support. This means that all libraries in your app must be universal as well. So if you depend on a binary library or framework from a vendor, you’ll need to work with them to get a universal version of the dependency.

The fourth protection is read only platform memory. The dynamic loader is responsible for loading code in your app and its libraries. It’s a very attractive target to attackers if they’re able to compromise the dynamic loaders metadata. They can use it to fully control your application. Read only platform memory prevents attackers from modifying that data, so only the dynamic loader itself can change it. It provides valuable security protection and is extremely easy to adopt. Most apps will not need to make changes to be compatible to ensure compatibility. Use system APIs to modify De Wilde and Objective-C runtime metadata. Don’t modify them directly.

The last type of whole app protection is the Out-of-process Enhanced Security extension. As Mark described, this approach is a form of containment. It provides a very strong security benefit, although it requires some investment to implement. Apply it by moving code that processes untrusted data into the extension. Then use secure system APIs to shuttle data from your main app. Process that untrusted data in the extension, pass the result back to the main app and make sure to validate it.

Now. Containment assumes that the attacker is able to take advantage of memory corruption to compromise the extension. The goal is to contain that attacker to the process, so they will not get access to data in the main application. To adopt, assess which parts of your app process untrusted data.

Refactor your code base to separate those parts into a different process and validate the response from the extension. Don’t trust it. Now this is a complement to other protection strategies. It’s not a substitute for them. So adopt after enabling memory integrity enforcement for your whole app. And since factoring out may take some time. Pursue it in parallel with pointer authentication.

Whole app protections are just a few of the steps. Or just take a few steps to adopt in Xcode. enable the typed allocator hardware, memory tagging, pointer authentication, and read only memory. By adopting the enhanced security capability, then create an enhanced security extension. Adopt these whole app protections to provide a strong baseline level of security for your entire app.

Those protections are great, but you need more protection if your app has Attack Surface written in C based languages. After adopting whole app protections, apply even stronger approaches for unsafe code bases that process untrusted input. Xcode provides protections for both C and C++. I’ll start with C++. Most code bases use the standard library for container classes and other widely used abstractions.

C++ standard library hardening protects against out-of-bounds accesses in classes like standard span and vector. It safely traps rather than allowing for memory corruption for code bases extensively using the standard library, hardening lies in the lower right quadrant of the security adoption trade off. It’s very easy to adopt and provides solid protection. For even more protection. Xcode’s bound safe buffer usage in C++ option provides a stronger guarantee. In this mode, the compiler rejects unsafe raw pointer arithmetic. Instead, it requires the use of idiomatic library abstractions like standard span, string, and vector.

In this way, the combination of compile time checks to prevent raw pointer arithmetic and runtime protections, and the hardened C++ standard library bring bound safety to the language. Now, unlike C++, C doesn’t have the high level language features such as operator overloading for easy to use library abstractions for bound safe pointer arithmetic. To fill this gap, Apple created a new language extension for C that bakes in bound safety directly and is pursuing incorporating this extension into the language standard.

Here’s how it works. Safely indexing into a pointer requires information about the bounds of the memory pointing to. So to ensure safety, the compiler prevents indexing into that with an error when it can’t determine the pointers bounce. You can then add bounds to annotations, telling the compiler how to determine the bounds, and it will insert bounds checks to safely trap at runtime on an out of bounds access. In this way, the combination of programmer provided annotations and compiler generated runtime bounds checks brings bounds safety to see.

Xcode C and C++ bounds safety features reside in the upper left corner of the quadrant. They provide strong guarantees, eliminating an entire class of vulnerabilities, but they do require code changes to the source. Apply them after you’ve already adopted whole app protections like memory integrity enforcement, to layer in even more security for your most sensitive C and C++ code.

Now, up until this point, I’ve talked about tools that are designed to retrofit protections onto your unsafe C, C++, and Objective-C code bases. These are strong protections, but full memory safety requires a memory safe language. Swift is memory safe and takes advantage of the platform security protections at the OS hardware and language level.

Swift six two provides a new lightweight family of library abstractions designed for low level use and parsers, and other cases where security and performance are critical. For example, the new span family of types allows access to continuous unowned memory. Span is fully memory safe. It uses advanced features and the Swift Standard Library to guarantee both lifetime and bound safety. Span is also fast. It’s great if you need to guarantee zero overhead runtime overhead for lifetime safety and highly optimized bounds checks. With Swift Span, the combination of compile time checks for lifetime safety and runtime checks for bound safety provides both security and low overhead.

There are two strategies to secure your app, with Swift adopting a new code and writing rewriting existing security sensitive code. Use both strategies. Swift makes it easy to write memory safe code. If you’re not already writing new code in Swift, start now. The code you write today will become what attackers target in the future. So. Right. New features in Swift.

And when you’re refactoring or modernizing existing subsystems. Take that opportunity to write those in Swift as well. For your security surface. Don’t wait for an opportunistic refactor. Instead, proactively rewrite those components in Swift. The most critical areas to focus on are parsers, especially for media and protocols, complex state machines, controlling object lifecycle, and anything that processes untrusted input.

Now you know how to protect your app from malicious attackers. These are the same protections Apple uses for its own apps. They’re carefully crafted when layered and applied at key places in your code base. They’ll give you best in class security. To adopt them. Enable enhanced security in Xcode, including memory integrity, enforcement, and pointer authentication, to provide a baseline level of protection for your whole app.

Contain processing of untrusted input and an enhanced security extension, and protect your unsafe C and C++ code bases with bound safety extensions. And use Swift, which is fully memory safe for all new code and and targeted rewrites of security surface. Security is more important now than ever. Take these steps today to protect your app, your users, and their sensitive data. Thank you.