Logging

07 Mar 2013

##Logging

Auditing and logging have always been of great importance to network administrators, especially to address the issue of accountability. These tools, when implemented at the application level can be very powerful investigation tools. They can help confirm that security policies are being enforced and that users are accountable for their actions. Logging usually refers to programmers outputting actions of interest in the code, whereas auditing is focused on accountability and implementation level events.

It is a good idea to log both successful and failed connection attempts. It’s common to log failed connection attempt as we often think it could be a malicious user trying out passwords, for example. However, it’s a good idea to log the successful attempts to make sure an intrusion doesn’t happen without anyone noticing.

Make sure you do not log user sensitive data. Encrypt and store the log in a secure place. Here is an example of overriding the default functionality of NSLog to provide more functionality. Here we get the line number and function that the log was called from.

#define NSLog(args...) _CFLog(@"DEBUG ", __FILE__,__LINE__,__PRETTY_FUNCTION__,args);

void _CFLog(NSString *prefix, const char *file, int lineNumber, const char *funcName, NSString *format,...)
{
    //local variables, setup current date and time, arguments and message
    va_list ap;
    va_start(ap, format);
    const char *formatString = "%s %s%50s:%3d - %s";
    format = [format stringByAppendingString:@"\n"];
    NSString *dateString = [[self dateFormatter] stringFromDate:[NSDate date]];
    NSString *msg = [[NSString alloc] initWithFormat:[NSString stringWithFormat:@"%@",format] arguments:ap];
    va_end (ap);
    
    //write to console file if enabled
#ifdef ENABLE_LOGGING_TO_CONSOLE
    fprintf(stderr, formatString, [dateString UTF8String], [prefix UTF8String], funcName, lineNumber, [msg UTF8String]);
#endif
    
    //save log in cache
    if (. . .validate the string)
    {
        char *charBuffer = NULL;
        size_t size;
        size = snprintf(NULL, 0, formatString, [dateString UTF8String], [prefix UTF8String], funcName, lineNumber, [msg UTF8String]);
        charBuffer = (char *)malloc(size + 1);
        if (charBuffer)
        {
            snprintf(charBuffer, size + 1, formatString, [dateString UTF8String], [prefix UTF8String], funcName, lineNumber, [msg UTF8String]);
            // -> Add code to save or send log here
        }
        free(charBuffer);
    }
}

If a server is down, make sure you rate limit the frequency and number of logs sent, network retries and error messages. Make sure the user can cancel the process so that a denial of service attack is less possible.