CVE-2016-6190 (Objective-C, published 2017-02-17T17:59Z)
Description: value: SOGo before 2.3.12 and 3.x before 3.1.1 does not restrict access to the UID and DTSTAMP attributes, which allows remote authenticated users to obtain sensitive information about appointments with the "View the Date & Time" restriction, as demonstrated by correlating UIDs and DTSTAMPs between all users.
Severity: MEDIUM (CVSS v3 base score: 4.3)
Weakness: CWE-200 \u2014 Exposure of Sensitive Information to an Unauthorized Actor
The product exposes sensitive information to an actor that is not explicitly authorized to have access to that information.
Repository: https://github.com/inverse-inc/sogo
Files changed:
SoObjects/Appointments/SOGoCalendarComponent.m
SoObjects/SOGo/SOGoUserSettings.h
SoObjects/SOGo/SOGoUserSettings.m
Commit message: (fix) improved previous commit for attributes stripping and UID generation (fixes #3695 and #3696)


Vulnerable code:
  NSString *type, *summary, *tag;
  NSArray *children;
  int classification, i;
  [component setSummary: summary];
  [component setComment: @""];
  [component setUserComment: @""];
  [component setLocation: @""];
  [component setCategories: [NSArray array]];
  [component setUrl: @""];
  [component setOrganizer: nil];
  [component removeAllAttendees];
  [component removeAllAlarms];

  // We strip all X- tags
  children = [component children];

  for (i = 0; i < [children count]; i++)
      tag = [[children objectAtIndex: i] tag];
      if ([[tag uppercaseString] hasPrefix: @"X-"])
        [component removeChild: [children objectAtIndex: i]];
 * Copyright (C) 2009-2014 Inverse inc.
 * Copyright (C) 2009-2014 Inverse inc.

Fixed code:
#import <SOGo/NSString+Crypto.h>
#import <SOGo/SOGoUserSettings.h>
  NSString *type, *summary, *tag, *uid;
  SOGoUserSettings *settings;
  SOGoUser *calendarOwner;
  NSEnumerator *children;
  CardElement *element;
  NSArray *tags;
  int classification;
  calendarOwner = [SOGoUser userWithLogin: [self ownerInContext: context]];
  settings = [calendarOwner userSettings];


  tags = [NSArray arrayWithObjects: @"DTSTAMP", @"DTSTART", @"DTEND", @"DUE", @"EXDATE", @"EXRULE", @"RRULE", nil];
  uid = [[component uid] asCryptedPassUsingScheme: @"ssha256"
                                         withSalt: [[settings userSalt] dataUsingEncoding: NSASCIIStringEncoding]
                                      andEncoding: encHex];

  children = [[[[component children] copy] autorelease] objectEnumerator];

  while ((element = [children nextObject]))
      tag = [element tag];
      if (![tags containsObject: [tag uppercaseString]])
        [component removeChild: element];

  [component setSummary: summary];
  [component setUid: uid];
 * Copyright (C) 2009-2016 Inverse inc.
- (NSString *) userSalt;
 * Copyright (C) 2009-2016 Inverse inc.
#import <Foundation/NSProcessInfo.h>
#import "NSString+Crypto.h"
- (NSString *) userSalt
{
  NSMutableDictionary *values;
  NSString *salt;

  salt = [[self dictionaryForKey: @"General"] objectForKey: @"Salt"];

  if (!salt)
    {
      salt = [[[NSProcessInfo processInfo] globallyUniqueString] asSHA1String];
      values = [self objectForKey: @"General"];

      if (!values)
        values = [NSMutableDictionary dictionary];

      [values setObject: salt  forKey: @"Salt"];
      [self setObject:  values forKey: @"General"];
      [self synchronize];
    }

  return salt;
}