1

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?

jordiz
  • 279
  • 3
  • 8
  • 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 Jun 27 '18 at 16:12
  • 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 Jun 28 '18 at 06:43
  • 1
    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 Jun 28 '18 at 06:48
  • 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 Jun 28 '18 at 06:56
  • mmmm oky thanks! could you put a example when the attacker can do something over predicateWithFormat? – jordiz Jun 28 '18 at 07:06
  • If you obtain the format string (not the arguments but the actual format string) from user entry or some API, then you may have a problem. If the format string is hardcoded in your code or from a data file that is part of your app and fully in your control, then there is no problem. – rmaddy Jun 28 '18 at 07:13
  • Thanks maddy! Now i understand you! – jordiz Jun 28 '18 at 07:36

1 Answers1

0

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]];
jordiz
  • 279
  • 3
  • 8