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 ↗Code shown on screen · 5 snippets
Path traversal
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
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
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
@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
@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
Related sessions
-
36 min