Package: release.debian.org
Severity: normal
Tags: trixie
X-Debbugs-Cc: [email protected], [email protected]
Control: affects -1 + src:sogo
User: [email protected]
Usertags: pu

[ Reason ]
This applies a security fix introduced by upstream release
5.12.7 to version 5.12.1 distributed with Trixie. I am not aware of any
CVE identifier for it. Upstream recommends to update immediately
provided one of the following setups is used [0]:

1. At least one user source is a PostgreSQL database.

2. a) At least one user source is an SQL database (MariaDB or PostgreSQL)
   b) Passwords are stored in plain text

[ Impact ]
Unfortunately upstream does not provide any information on what type of
issue is addressed and what the implications are. Luckily there are only
four non-merge commits between version 5.12.6 and 5.12.7 and two of them
handle i18n stuff. Combining the information in the release notes with the
commit history, I consider it highly likely that the relevant commit fixing
the issue referred to above is [1]. I am not familiar enough with the 
codebase to fully understand all details of this commit but it seems that
at least part of the fix addresses a (second order) SQL injection
vulnerability in the credentials handling part of the code.

[ Tests ]
Given the uncertainties mentioned above, it is difficult to perform
meaningful tests to verify that the patched version actually fixes the
issue.

I am running version 5.12.7 provided by upstream for a couple of weeks
in production - without any issues, but I did not have a vulnerable
setup (user source is LDAP rather than SQL database). Therefore this is
only of limited informative value.

[ Risks ]
As indicated in the patch header, the applied patch is cherry-picked from
the upstream repository. Upstream distributes the fix for more than a month
now. Therefore I consider it likely that it has already been deployed by a
sizable number of sites obtaining packages from upstream.

Given the urgency of the warning in the release notes doing nothing obviously
also comes with a risk for affected sites.

[ Checklist ]
  [x] *all* changes are documented in the d/changelog
  [x] I reviewed all changes and I approve them
  [x] attach debdiff against the package in (old)stable
  [x] the issue is verified as fixed in unstable

[ Changes ]
Applying changes from upstream commit [1] as explained above.

[ Other info ]
After a discussion with a security team member it was suggested to address
this issue via an upload to s-p-u.

I do not plan to address the issue in bookworm (which is also vulnerable)
because the upstream fix cannot be applied to version 5.8.0 without adaptions.
Given the test situation described above I do not want to blindly backport it.

Best regards,

Peter

[0] https://www.sogo.nu/news/2026/sogo-v5127-released.html

[1] 
https://github.com/Alinto/sogo/commit/1f7e5d2b2c2047c44a6a9e05f73c36491cb96d21
diff -Nru sogo-5.12.1/debian/changelog sogo-5.12.1/debian/changelog
--- sogo-5.12.1/debian/changelog        2025-12-31 11:33:39.000000000 +0100
+++ sogo-5.12.1/debian/changelog        2026-05-08 16:18:12.000000000 +0200
@@ -1,3 +1,10 @@
+sogo (5.12.1-3+deb13u2) trixie; urgency=medium
+
+  * Non-maintainer upload.
+  * Add patch to ensure proper SQL adaptor is used for user source
+
+ -- Peter Wienemann <[email protected]>  Fri, 08 May 2026 16:18:12 +0200
+
 sogo (5.12.1-3+deb13u1) trixie; urgency=high
 
   * Non-maintainer upload by the Security Team.
diff -Nru 
sogo-5.12.1/debian/patches/fix-sql-use-proper-sql-adaptor-for-usr-source.patch 
sogo-5.12.1/debian/patches/fix-sql-use-proper-sql-adaptor-for-usr-source.patch
--- 
sogo-5.12.1/debian/patches/fix-sql-use-proper-sql-adaptor-for-usr-source.patch  
    1970-01-01 01:00:00.000000000 +0100
+++ 
sogo-5.12.1/debian/patches/fix-sql-use-proper-sql-adaptor-for-usr-source.patch  
    2026-05-08 16:18:12.000000000 +0200
@@ -0,0 +1,176 @@
+From: Hivert Quentin <[email protected]>
+Date: Tue, 24 Mar 2026 15:26:37 +0100
+Subject: fix(sql): use proper sql adaptor for usr source
+
+Origin: 
https://github.com/Alinto/sogo/commit/1f7e5d2b2c2047c44a6a9e05f73c36491cb96d21.diff
+---
+ SoObjects/SOGo/SQLSource.m | 70 ++++++++++++++++++++++++++++++++--------------
+ 1 file changed, 49 insertions(+), 21 deletions(-)
+
+diff --git a/SoObjects/SOGo/SQLSource.m b/SoObjects/SOGo/SQLSource.m
+index 93e8a81..2a4a950 100644
+--- a/SoObjects/SOGo/SQLSource.m
++++ b/SoObjects/SOGo/SQLSource.m
+@@ -225,9 +225,16 @@
+  */
+ - (NSString *) _encryptPassword: (NSString *) plainPassword
+ {
+-  NSString *pass;
++  NSString *pass, *passwordScheme;
+   NSString* result;
+ 
++  // if ([_userPasswordAlgorithm caseInsensitiveCompare: @"none"] == 
NSOrderedSame ||
++  //     [_userPasswordAlgorithm caseInsensitiveCompare: @"plain"] == 
NSOrderedSame ||
++  //     [_userPasswordAlgorithm caseInsensitiveCompare: @"cleartext"] == 
NSOrderedSame)
++  // {
++  //   pass = [pass stringByReplacingString: @"'"  withString: @"''"];
++  // }
++
+   pass = [plainPassword asCryptedPassUsingScheme: _userPasswordAlgorithm
+                                          keyPath: _keyPath];
+ 
+@@ -272,6 +279,7 @@
+               grace: (int *) _grace
+   disablepasswordPolicyCheck: (BOOL) _disablepasswordPolicyCheck
+ {
++  EOAdaptor *adaptor;
+   EOAdaptorChannel *channel;
+   EOQualifier *qualifier;
+   GCSChannelManager *cm;
+@@ -281,11 +289,13 @@
+ 
+   rc = NO;
+ 
+-  _login = [_login stringByReplacingString: @"'"  withString: @"''"];
+   cm = [GCSChannelManager defaultChannelManager];
+   channel = [cm acquireOpenChannelForURL: _viewURL];
+   if (channel)
+     {
++      EOAdaptorContext *adaptorCtx;
++      adaptorCtx = [channel adaptorContext];
++      adaptor = [adaptorCtx adaptor];
+       if (_loginFields)
+         {
+           NSMutableArray *qualifiers;
+@@ -324,7 +334,8 @@
+                                               nil];
+           [qualifier autorelease];
+         }
+-      [qualifier appendSQLToString: sql];
++      [qualifier appendSQLToString: sql
++                       withAdaptor: adaptor];
+ 
+       ex = [channel evaluateExpressionX: sql];
+       if (!ex)
+@@ -430,9 +441,11 @@
+ {
+   BOOL didChange, isOldPwdOk, isPolicyOk;
+   EOAdaptorChannel *channel;
++  EOAdaptor *adaptor;
++  EOQualifier *qualifier_login, *qualifier_pwd;
+   GCSChannelManager *cm;
+   NSException *ex;
+-  NSString *sqlstr;
++  NSMutableString *sqlstr;
+ 
+   *perr = -1;
+   isOldPwdOk = NO;
+@@ -455,16 +468,28 @@
+         return NO;
+ 
+       // Save new password
+-      login = [login stringByReplacingString: @"'"  withString: @"''"];
++      // login = [login stringByReplacingString: @"'"  withString: @"''"];
+       cm = [GCSChannelManager defaultChannelManager];
+       channel = [cm acquireOpenChannelForURL: _viewURL];
+       if (channel)
+         {
+-          sqlstr = [NSString stringWithFormat: (@"UPDATE %@"
+-                                                @" SET c_password = '%@'"
+-                                                @" WHERE c_uid = '%@'"),
+-                             [_viewURL gcsTableName], encryptedPassword, 
login];
+-
++          EOAdaptorContext *adaptorCtx;
++          adaptorCtx = [channel adaptorContext];
++          adaptor = [adaptorCtx adaptor];
++          sqlstr = [NSMutableString stringWithFormat: @"UPDATE %@ SET ",
++                                              [_viewURL gcsTableName]];
++                
++          qualifier_pwd = [[EOKeyValueQualifier alloc] initWithKey: 
@"c_password"
++                                              operatorSelector: 
EOQualifierOperatorEqual
++                                                         value: 
encryptedPassword];
++          [qualifier_pwd appendSQLToString: sqlstr
++                          withAdaptor: adaptor];
++          [sqlstr appendString: @" WHERE "];
++          qualifier_login = [[EOKeyValueQualifier alloc] initWithKey: @"c_uid"
++                                              operatorSelector: 
EOQualifierOperatorEqual
++                                                         value: login];
++          [qualifier_login appendSQLToString: sqlstr
++                          withAdaptor: adaptor];
+           ex = [channel evaluateExpressionX: sqlstr];
+           if (!ex)
+             {
+@@ -998,7 +1023,9 @@
+                           inDomain: (NSString *)domain
+                              limit: (int)limit
+ {
++  EOAdaptor *adaptor;
+   EOAdaptorChannel *channel;
++  EOQualifier *qualifier;
+   NSEnumerator *criteriaList;
+   NSMutableArray *fields, *results;
+   GCSChannelManager *cm;
+@@ -1014,12 +1041,14 @@
+       channel = [cm acquireOpenChannelForURL: _viewURL];
+       if (channel)
+         {
++          EOAdaptorContext *adaptorCtx;
++          adaptorCtx = [channel adaptorContext];
++          adaptor = [adaptorCtx adaptor];
+           fields = [NSMutableArray array];
+           if ([filter length])
+             {
+-              lowerFilter = [filter lowercaseString];
+-              lowerFilter = [lowerFilter asSafeSQLLikeString];
+-              filterFormat = [NSString stringWithFormat: @"LOWER(%%@) LIKE 
'%%%%%@%%%%'", lowerFilter];
++              filter = [[filter asSafeSQLString] stringByReplacingString: 
@"\%" withString: @"%%"];
++              filterFormat = [NSString stringWithFormat: @"(%%@ 
isCaseInsensitiveLike: '*%@*')", filter];
+               if (criteria)
+                 criteriaList = [criteria objectEnumerator];
+               else
+@@ -1044,7 +1073,9 @@
+           if ([fields count])
+             {
+               qs = [[[fields uniqueObjects] stringsWithFormat: filterFormat] 
componentsJoinedByString: @" OR "];
+-              [sql appendString: qs];
++              qualifier = [EOQualifier qualifierWithQualifierFormat: qs];
++              [qualifier appendSQLToString: sql
++                             withAdaptor: adaptor];
+             }
+           else
+             [sql appendString: @"1 = 1"];
+@@ -1108,7 +1139,7 @@
+                           andSortOrdering: (EOSortOrdering *) ordering
+                                  inDomain: (NSString *) domain
+ {
+-  static EOAdaptor *adaptor = nil;
++  EOAdaptor *adaptor;
+   NSException *ex;
+   NSMutableArray *results;
+   NSMutableString *sql;
+@@ -1123,12 +1154,9 @@
+       channel = [cm acquireOpenChannelForURL: _viewURL];
+       if (channel)
+         {
+-          if (!adaptor)
+-            {
+-              EOAdaptorContext *adaptorCtx;
+-              adaptorCtx = [channel adaptorContext];
+-              adaptor = [adaptorCtx adaptor];
+-            }
++          EOAdaptorContext *adaptorCtx;
++          adaptorCtx = [channel adaptorContext];
++          adaptor = [adaptorCtx adaptor];
+           sql = [NSMutableString stringWithFormat: @"SELECT c_name FROM %@ 
WHERE (", [_viewURL gcsTableName]];
+ 
+           if (qualifier)
diff -Nru sogo-5.12.1/debian/patches/series sogo-5.12.1/debian/patches/series
--- sogo-5.12.1/debian/patches/series   2025-12-31 11:33:39.000000000 +0100
+++ sogo-5.12.1/debian/patches/series   2026-05-08 16:18:12.000000000 +0200
@@ -17,3 +17,4 @@
 upstream_use_openid_libcurl.patch
 CVE-2025-63499.patch
 CVE-2025-63498.patch
+fix-sql-use-proper-sql-adaptor-for-usr-source.patch

Reply via email to