PSPDFKit SDK Security

PSPDFKit has been implemented using the latest and best security practices and is used in security-conscious applications.

  • PSPDFKit supports iOS Data Protection.
  • Encrypted PDFs are supported and cannot be accessed without the matching password.
  • PDF passwords are never persisted.
  • The PSPDFAESCryptoDataProvider allows accessing encrypted documents where only parts currently needed to render the page are dynamically decrypted in memory instead of always the whole file.
  • PSPDFDocument can be initialized with an NSData object for custom encryption.
  • Signatures are saved in the secure keychain.
  • Customers are using PSPDFKit with GOOD, Mobile Iron and AirWatch.
  • Code commits are always peer-reviewed and have to pass our large test case set before being merged.
  • We use a large set of compiler warnings and the latest version of Clang Analyzer to detect and fix potential problems before the product is released.

Permissions

PSPDFKit has optional features such as adding images or recording sound annotations. If you allow these in your app, make sure to set the required permissions in your Info.plist.

Security Exceptions

Client applications can implement a custom PSPDFApplicationPolicy class that manages security related callbacks. PSPDFKit by default will use a standard implementation that allows all special actions, however you can modify this if you are in an restricted environment. Following security actions are currently tracked:

Copy
1
2
3
4
5
6
7
8
9
10
11
public let PSPDFPolicyEventOpenIn: String
public let PSPDFPolicyEventPrint: String
public let PSPDFPolicyEventEmail: String
public let PSPDFPolicyEventMessage: String
public let PSPDFPolicyEventQuickLook: String
public let PSPDFPolicyEventAudioRecording: String
public let PSPDFPolicyEventCamera: String
public let PSPDFPolicyEventPhotoLibrary: String
public let PSPDFPolicyEventPasteboard: String // includes Copy/Paste
public let PSPDFPolicyEventSubmitForm: String
public let PSPDFPolicyEventNetwork: String
Copy
1
2
3
4
5
6
7
8
9
10
11
PSPDF_EXPORT NSString *const PSPDFPolicyEventOpenIn;
PSPDF_EXPORT NSString *const PSPDFPolicyEventPrint;
PSPDF_EXPORT NSString *const PSPDFPolicyEventEmail;
PSPDF_EXPORT NSString *const PSPDFPolicyEventMessage;
PSPDF_EXPORT NSString *const PSPDFPolicyEventQuickLook;
PSPDF_EXPORT NSString *const PSPDFPolicyEventAudioRecording;
PSPDF_EXPORT NSString *const PSPDFPolicyEventCamera;
PSPDF_EXPORT NSString *const PSPDFPolicyEventPhotoLibrary;
PSPDF_EXPORT NSString *const PSPDFPolicyEventPasteboard; // includes Copy/Paste
PSPDF_EXPORT NSString *const PSPDFPolicyEventSubmitForm;
PSPDF_EXPORT NSString *const PSPDFPolicyEventNetwork;
Copy
1
2
3
4
5
6
7
8
9
10
class DisallowCopyApplicationPolicy: NSObject, PSPDFApplicationPolicy {

    func hasPermission(forEvent event: String, isUserAction: Bool) -> Bool {
        if event == PSPDFPolicyEventPasteboard {
            return false
        }
        return true
    }

}
Copy
1
2
3
4
5
6
7
8
9
10
11
12
@interface PSCDisallowCopyApplicationPolicy : NSObject <PSPDFApplicationPolicy> @end

@implementation PSCDisallowCopyApplicationPolicy

- (BOOL)hasPermissionForEvent:(NSString *)event isUserAction:(BOOL)isUserAction {
    if ([event isEqualToString:PSPDFPolicyEventPasteboard]) {
        return NO;
    }
    return YES;
}

@end

You can register custom PSPDFApplicationPolicy instance by calling +[PSPDFKit setLicenseKey:options:]. PSPDFKit expects your instance to be set in options dictionary under PSPDFApplicationPolicyKey key.

Cache

Rendered pages will be cached to disk by default to ensure fast display and browsing. The disk cache can be customized on a per-document level and for a data provider, and it can also be disabled globally by setting its allowedDiskSpace to 0.

There are also specific hooks to add a custom crypto layer into the disk cache. See decryptionHelper and encryptionHelper.

Implementing a custom crypto layer might decrease performance slightly, but is hardly noticeable on modern devices. PSPDFCatalog contains sample code using the open source RNCryptor.

Security related considerations

  • PSPDFKit might keep parts of extracted text, annotations or password in memory to perform the requested operations. If rogue code has access to your application's memory there is nothing you can do and the device has already been compromised, for example, jailbroken devices.
  • Taking a screenshot cannot be prevented on iOS. There is a UIApplicationUserDidTakeScreenshotNotification notification that is sent when the user takes a screenshot using the Lock+Home Button combination, however there are other ways to make screenshots that won't emit such notification (like using Xcode's Device Manager).
  • Using PSPDFDocument with data in memory using PSPDFDataContainerProvider will only work for documents that fit into the process memory space. This is device and state dependent. When saving annotations, the NSData object is mutated and you can use the document delegate pdfDocument:didSaveAnnotations: to save back the data object to your (encrypted) disk store. However, it is strongly recommended to use PSPDFAESCryptoDataProvider or a custom implementation of PSPDFDataProviding to avoid loading the whole file in memory.

Network Access

PSPDFKit only performs network access when required for following actions:

  • Submitting a PDF form
  • Accessing images/videos/audio from the gallery
  • Simple analytics for demo, nightly and beta builds/licenses.
  • Via the inline web browser, if an URL was tapped. (PSPDFWebViewController)

Production license verification happens offline and does not ping our servers.

Copy Text

PDF documents have a flag that indicates if copying text is allowed, which is reflected in the PSPDFDocumentPermissionsExtract flag in the permissions property of PSPDFDocument. This is a readonly property that cannot be changed.

To disable text copy when the PDF allows it, implement the PSPDFApplicationPolicy protocol in a custom class as explained above.