1
votes

I have a predicate for query in core data base but i don't know what is the correct way to validate its params?

- (void) queryToDatabaseWithStoreId:(NSInteger) storeId {
   [NSPredicate predicateWithFormat:@"store.storeId = %d", storeId];
}

My question is how can i validate storeId param or what i need to use for that vulnerability to dissapear?

And if i have a list:

- (void) queryToDataBaseWithListStore:(NSArray<Store *> *) storeList {
   [NSPredicate predicateWithFormat:@"store.storeId IN %@", [storeList valueForObject:@"storeId"]];
}

https://developer.apple.com/library/archive/documentation/Security/Conceptual/SecureCodingGuide/Articles/ValidatingInput.html#//apple_ref/doc/uid/TP40007246-SW3

I need avoid that:

The following commonly-used functions and methods are subject to format-string attacks:

Standard C

printf and other functions listed on the printf(3) manual page sscanf and other functions listed on the scanf(3) manual page syslog and vsyslog

Carbon

AEBuildDesc and vAEBuildDesc AEBuildParameters and vAEBuildParameters AEBuildAppleEvent and vAEBuildAppleEvent Core Foundation CFStringCreateWithFormat CFStringCreateWithFormatAndArguments CFStringAppendFormat CFStringAppendFormatAndArguments

Cocoa

stringWithFormat:, initWithFormat:, and other NSString methods that take formatted strings as arguments appendFormat: in the NSMutableString class alertWithMessageText:defaultButton:alternateButton:otherButton:informativeTextWithFormat: in NSAlert predicateWithFormat:, predicateWithFormat:arguments:, and predicateWithFormat:argumentArray: in NSPredicate raise:format: and raise:format:arguments: in NSException NSRunAlertPanel and other AppKit functions that create or return panels or sheets

What is the best way to avoid this attack?

1
There is no vulnerability in the code you posted in your question. Read the link you posted. It clearly explains under what conditions a string format can be a problem. Your use is not one of them.rmaddy
The security audit report me that: predicate = [NSPredicate predicateWithFormat:@"sectionId = %d", [binnacleNote.sectionId intValue]]; I think that variable can change in execution time, but i don't sure about that.jordiz
Any vulnerability in a format arises when you don't have any control over the actual format string. Since you have hardcoded a specific format string into your predicate, there is no problem.rmaddy
His advice is: Verify the format, length, type and range of data, but i don't sure about that because If the attacker can modify my variable, then the attacker can modify verification too.jordiz
mmmm oky thanks! could you put a example when the attacker can do something over predicateWithFormat?jordiz

1 Answers

0
votes

I have programmed this class but i don't know if it is enough.

@implementation StringUtils

+ (BOOL) isEmpty:(id) text {
    if ([text isKindOfClass:[NSNull class]]) {
        return YES;
    } else {
        if (text) {
            if ([text isKindOfClass:[NSString class]]) {
                NSString *textStr = [NSString stringWithFormat:@"%@", text];
                return [textStr isEqualToString:@""];
            }
            return YES;
        } else {
            return YES;
        }
    }
}

+ (NSString *) validateField:(id) text {

    NSInteger numErrors = 0;
    NSString *pattern = @"[^A-Za-z0-9-]+";
    NSError *error = nil;

    NSString *textValidated = @"";
    if ([text isKindOfClass:[NSNumber class]]) {
        textValidated = [text stringValue];
    } else if ([text isKindOfClass:[NSString class]]) {
        textValidated = text;
    } else {
        @try {
            textValidated = [text stringValue];
        } @catch (NSException *exception) {
            numErrors=+1;
        }
    }

    //Only numbers && chars && -
    NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:pattern options:0 error:&error];
    NSRange textRange = NSMakeRange(0, textValidated.length);
    NSRange matchRange = [regex rangeOfFirstMatchInString:textValidated options:NSMatchingReportProgress range:textRange];
    if (matchRange.location != NSNotFound) {
        numErrors+=1;
    }

    //Not empty string
    if ([StringUtils isEmpty:textValidated]) {
        numErrors+=1;
    }

    if (numErrors == 0) {
        return textValidated;
    }
    return @"";
}

+ (NSArray *) validateArrayFields:(NSArray *) list {

    NSInteger *numErrors = 0;
    for (id obj in list) {
        if ([StringUtils isEmpty:[StringUtils validateField:obj]]) {
            numErrors+=1;
        }
    }

    if (numErrors == 0) {
        return list;
    }

    return [[NSArray alloc] init];
}

@end

For use normal:

[NSPredicate predicateWithFormat:@"store.storeId = %@", [StringUtils validateField:storeId]];

For use with array:

[NSPredicate predicateWithFormat:@"store.storeId IN %@", [StringUtils validateArrayFields:storeId]];