App extensions, share sheets, widgets, custom keyboards, notification service extensions, let your app do more, and each one is a separate piece of code with its own security considerations. They run apart from your main app and usually share data with it through an App Group, which raises the same shared-storage concerns, and some, like custom keyboards with full access, carry privacy risks of their own. The right approach is least privilege: share the minimum, request only the access an extension needs, and treat its input as untrusted. Here is what app extensions are and how to keep them secure.
Short answer
iOS app extensions, such as share, action, widget, keyboard, and notification service extensions, run separately from your main app and typically share data with it through an App Group, which means the same shared-storage rules apply: do not over-share, and keep secrets in a shared Keychain rather than shared UserDefaults. Per Apple's documentation, specific extensions carry their own risks, notably custom keyboards that request full access, which can send data over the network, so request it only when needed and never to exfiltrate keystrokes. Apply least privilege, share the minimum between the app and its extensions, request only the access each extension requires, and treat extension input as untrusted.
What you should know
- Extensions run separately: from your main app, with their own code.
- They share data via App Groups: so shared-storage rules apply.
- Keyboard full access is sensitive: it can send data over the network.
- Apply least privilege: share the minimum, request only needed access.
- Treat extension input as untrusted: validate what comes in.
What are app extensions, and what is the shared-data angle?
They are focused pieces of functionality that run outside your main app, in their own processes, to extend the system, a share extension that receives content from other apps, a widget, a custom keyboard, a notification service extension that processes incoming notifications. Because they are separate from the main app, they cannot directly access its data, so they typically communicate through an App Group, sharing a container, shared UserDefaults, and a shared Keychain access group. That shared-data path is where the security considerations begin: anything you place in the shared container is reachable by the app and all its extensions, shared UserDefaults is not encrypted, and secrets shared across the group belong in the shared Keychain. So an extension inherits the App Group rules, and over-sharing or putting secrets in the wrong place exposes them across the whole group.
What are the extension-specific risks?
A few extensions raise risks beyond shared data. The table lists the main ones.
| Extension or aspect | Risk |
|---|---|
| Custom keyboard with full access | Can send typed data, including sensitive input, over the network |
| Shared App Group container | Over-shared data is reachable by all group members |
| Shared UserDefaults | Unencrypted; secrets there are exposed |
| Notification service extension | Handles incoming content, including any secrets, that it must protect |
| Share or action extension input | Receives content from other apps, which is untrusted |
The standout is the custom keyboard. A keyboard extension that requests full access gains network capability, which is necessary for some features but means it could transmit what the user types, so users are warned, and a keyboard should request full access only when a feature genuinely needs it and must never exfiltrate keystrokes. The others come back to shared-data hygiene and treating content an extension receives from other apps as untrusted input.
How do you secure extensions?
Least privilege across sharing, access, and input. Share only what an extension genuinely needs through the App Group, keep secrets in the shared Keychain rather than shared UserDefaults or files, and do not place more in the shared container than the sharing requires. For a custom keyboard, request full access only if a feature needs it, and if you do, be transparent and never transmit or log the user's keystrokes beyond the stated purpose. For a notification service extension that fetches or decrypts content, handle any secrets it needs through the shared Keychain and protect the content it processes. Treat input an extension receives, shared content, notification payloads, as untrusted and validate it. And request only the entitlements each extension actually uses, since over-provisioning an extension widens its attack surface just as it does the main app. The principle is to give each extension the minimum data, access, and trust it needs.
What to watch out for
The first trap is a custom keyboard requesting full access it does not need, or worse transmitting keystrokes, which is a serious privacy problem; request it only when necessary. The second is over-sharing through the App Group or putting secrets in shared UserDefaults, which exposes them across the group; use the shared Keychain and share minimally. The third is trusting content an extension receives from other apps. A pre-submission scan such as PTKD.com (https://ptkd.com) reads the compiled IPA against OWASP MASVS and surfaces entitlements, App Group usage, and how data is stored, which helps you confirm your extensions share and store data securely. The extension design you handle in the app.
What to take away
- iOS app extensions run separately from the main app and share data via App Groups, so the shared-storage rules apply: do not over-share, and keep secrets in the shared Keychain.
- Custom keyboards with full access can send data over the network, so request full access only when needed and never exfiltrate keystrokes.
- Apply least privilege: share the minimum, request only the entitlements and access each extension needs, and treat extension input as untrusted.
- Use a pre-submission scan such as PTKD.com to confirm your extensions' entitlements, App Group usage, and data storage are secure.



