Dunfey · Hotel WWDC as data, est. 1983
Front desk everything
Years
Topics

2020 Privacy & Security

WWDC20 · 38 min · Privacy & Security

Secure your app: threat modeling and anti-patterns

It’s more important than ever to consider vulnerabilities and potential threats and recognize where you should apply safeguards in your app. Understand how to identify potential risks through threat modeling and how to avoid common anti-patterns. Learn coding techniques and how to take advantage of platform-supplied protections to help you mitigate risk and protect people while they’re using your app.

Watch at developer.apple.com ↗

Transcript all transcripts

Code shown on screen · 5 snippets

Path traversal swift · at 16:34 ↗
func handleIncomingFile(_ incomingResourceURL: URL, with name: String, from fromID: String) {
    guard
         case let safeFileName = name.lastPathComponent, 
         safeFileName.count > 0,
         safeFileName != "..", safeFileName != "." else { return }

    let destinationFileURL = URL(fileURLWithPath: NSTemporaryDirectory())
                                 .appendingPathComponent(safeFileName)

    // Copy the file into a temporary directory
    try! FileManager.default.copyItem(at: incomingResourceURL, to: destinationFileURL)

}
State management swift · at 22:26 ↗
func handleSessionInviteAccepted(with message: RemoteMessage, from fromID: String) {
    guard session = sessionsByIdentifier[message.sessionIdentifier],
          session.state == .inviting,
          session.invitedFromIdentifiers.contains(fromID) else { return }

    session.state = .connected
    session.setupSocket(to: fromID) { socket in
        cameraController.send(to: socket)
    }
}
Safe dynamic allowedClasses objectivec · at 30:56 ↗
NSSet *classesWhichConformToProtocol(Protocol *protocol) {
    NSMutableSet *conformingClasses = [NSMutableSet set];
    
    unsigned int classesCount = 0;
    Class *classes = objc_copyClassList(&classesCount);
    if (classes != NULL) {
        for (unsigned int i = 0; i < classesCount; i++) {
            if (class_conformsToProtocol(classes[i], protocol)) {
                [conformingClasses addObject: classes[i]];
            }
        }
        free(classes);
    }
    return conformingClasses;
}
Buffer overflows objectivec · at 34:23 ↗
@implementation
- (BOOL)unpackTeaClubRecord:(CKRecord *)record {
    ...
    NSData *data = [record objectForKey:@"uuid"];
    if (data == nil ||
        ![data isKindOfClass:[NSData class]] ||
        data.length != sizeof(_uuid)) {
        return NO;
    }
    memcpy(&_uuid, data.bytes, data.length);
    ...
Integer overflows objectivec · at 36:06 ↗
@implementation
- (BOOL)unpackTeaClubRecord:(CKRecord *)record {
    ...
    NSData *name = [record objectForKey:@"name"];
    int32_t count = [[record objectForKey:@"nameCount"] unsignedIntegerValue];
    int32_t byteCount = 0;
    if (name == nil ||
        ![name isKindOfClass:[NSData class]] ||
        os_mul_overflow(count, sizeof(unichar), &byteCount) ||
        name.length != byteCount) {
        return NO;
    }
    _name = [[NSString alloc] initWithCharacters:name.bytes 
                                          length:count];
    ...

Resources