Version in base suite: 7.0.30-1 Base version: tryton-server_7.0.30-1 Target version: tryton-server_7.0.30-1+deb13u1 Base file: /srv/ftp-master.debian.org/ftp/pool/main/t/tryton-server/tryton-server_7.0.30-1.dsc Target file: /srv/ftp-master.debian.org/policy/pool/main/t/tryton-server/tryton-server_7.0.30-1+deb13u1.dsc changelog | 21 +++++++ patches/03_traceback_in_RPC.patch | 60 ++++++++++++++++++++++ patches/04_enforce_access_check_html_editor.patch | 43 +++++++++++++++ patches/05_enforce_access_check_export_data.patch | 47 +++++++++++++++++ patches/series | 3 + 5 files changed, 174 insertions(+) diff -Nru tryton-server-7.0.30/debian/changelog tryton-server-7.0.30/debian/changelog --- tryton-server-7.0.30/debian/changelog 2025-04-28 07:07:47.000000000 +0000 +++ tryton-server-7.0.30/debian/changelog 2025-11-25 11:32:14.000000000 +0000 @@ -1,3 +1,24 @@ +tryton-server (7.0.30-1+deb13u1) trixie-security; urgency=high + * Add 03_traceback_in_RPC.patch, + 04_enforce_access_check_html_editor.patch, + 05_enforce_access_check_export_data.patch + + Fixes for security issues: + + Enforce access check in HTML editor route + https://bugs.debian.org/1121241 (s.a. #1121241) + -> https://foss.heptapod.net/tryton/tryton/-/issues/14364 + + Include the traceback only in RPC responses in development mode + https://bugs.debian.org/1121242 (s.a. #1121242) + -> https://foss.heptapod.net/tryton/tryton/-/issues/14354 + + Enforce access check in export_data + https://bugs.debian.org/1121243 (s.a. #1121243) + -> https://foss.heptapod.net/tryton/tryton/-/issues/14366 + + -- Mathias Behrle Tue, 25 Nov 2025 12:32:14 +0100 + tryton-server (7.0.30-1) unstable; urgency=medium * Merging upstream version 7.0.30. diff -Nru tryton-server-7.0.30/debian/patches/03_traceback_in_RPC.patch tryton-server-7.0.30/debian/patches/03_traceback_in_RPC.patch --- tryton-server-7.0.30/debian/patches/03_traceback_in_RPC.patch 1970-01-01 00:00:00.000000000 +0000 +++ tryton-server-7.0.30/debian/patches/03_traceback_in_RPC.patch 2025-11-25 11:19:44.000000000 +0000 @@ -0,0 +1,60 @@ +Description: Include the traceback only in RPC responses in development mode. + Supplying unexpected keys in a JSON-RPC create request (e.g., _debug) + causes a KeyError in the server, and the full Python traceback is + returned in the JSON-RPC error response. This leaks internal implementation + details (file paths, function names, library layout,) + which can assist an attacker in further exploitation/reconnaissance. +Author: Cédric Krier +Bug-Debian: https://bugs.debian.org/1121242 +Last-Update: 2025-11-25 +Bug-Upstream: https://foss.heptapod.net/tryton/tryton/-/issues/14354 + +--- a/bin/trytond ++++ b/bin/trytond +@@ -74,6 +74,7 @@ + 'txt', 'html', 'xhtml']: + path = os.path.join(info['directory'], '**', '*.' + ext) + extra_files.extend(glob.glob(path, recursive=True)) ++ app.dev = options.dev + + if options.coroutine: + from gevent.pywsgi import WSGIServer +--- a/trytond/protocols/jsonrpc.py ++++ b/trytond/protocols/jsonrpc.py +@@ -169,7 +169,9 @@ + response['error'] = data.args + elif isinstance(data, Exception): + # report exception back to server +- response['error'] = (str(data), data.__format_traceback__) ++ response['error'] = ( ++ str(data), ++ getattr(data, '__format_traceback__', '')) + else: + response['result'] = data + else: +--- a/trytond/wsgi.py ++++ b/trytond/wsgi.py +@@ -56,6 +56,7 @@ + }) + self.protocols = [JSONProtocol, XMLProtocol] + self.error_handlers = [] ++ self.dev = False + + def route(self, string, methods=None, defaults=None): + def decorator(func): +@@ -114,10 +115,11 @@ + except Exception as e: + logger.debug( + "Exception when processing %s", request, exc_info=True) +- tb_s = ''.join(traceback.format_exception(*sys.exc_info())) +- for path in sys.path: +- tb_s = tb_s.replace(path, '') +- e.__format_traceback__ = tb_s ++ if self.dev: ++ tb_s = ''.join(traceback.format_exception(*sys.exc_info())) ++ for path in sys.path: ++ tb_s = tb_s.replace(path, '') ++ e.__format_traceback__ = tb_s + response = e + for error_handler in self.error_handlers: + rv = error_handler(self, request, e) diff -Nru tryton-server-7.0.30/debian/patches/04_enforce_access_check_html_editor.patch tryton-server-7.0.30/debian/patches/04_enforce_access_check_html_editor.patch --- tryton-server-7.0.30/debian/patches/04_enforce_access_check_html_editor.patch 1970-01-01 00:00:00.000000000 +0000 +++ tryton-server-7.0.30/debian/patches/04_enforce_access_check_html_editor.patch 2025-11-25 11:19:44.000000000 +0000 @@ -0,0 +1,43 @@ +Description: Enforce access check in HTML editor route + Use .read and .write instead of .browse and .save when editing field via the + HTML editor. +Author: Cédric Krier +Bug-Debian: https://bugs.debian.org/1121241 +Last-Update: 2025-11-25 +Bug-Upstream: https://foss.heptapod.net/tryton/tryton/-/issues/14364 + +--- a/trytond/ir/routes.py ++++ b/trytond/ir/routes.py +@@ -53,20 +53,21 @@ + with transaction.set_context(language=language): + Model = pool.get(model) + record = Model(record) ++ values = Model.read([record.id], ['rec_name', field.name])[0] + + status = HTTPStatus.OK + error = '' + if request.method == 'POST': + setattr(record, field.name, request.form['text']) + if request.form['_csrf_token'] == get_token(record): +- record.save() ++ Model.write([record], {field.name: request.form['text']}) + return redirect(request.url) + else: + status = HTTPStatus.BAD_REQUEST + error = gettext('ir.msg_html_editor_save_fail') + + csrf_token = get_token(record) +- text = getattr(record, field.name) or '' ++ text = values[field.name] or '' + if isinstance(text, bytes): + try: + text = text.decode('utf-8') +@@ -77,7 +78,7 @@ + abort(HTTPStatus.BAD_REQUEST) + title = '%(model)s "%(name)s" %(field)s - %(title)s' % { + 'model': field.model.name, +- 'name': record.rec_name, ++ 'name': values['rec_name'], + 'field': field.field_description, + 'title': request.args.get('title', "Tryton"), + } diff -Nru tryton-server-7.0.30/debian/patches/05_enforce_access_check_export_data.patch tryton-server-7.0.30/debian/patches/05_enforce_access_check_export_data.patch --- tryton-server-7.0.30/debian/patches/05_enforce_access_check_export_data.patch 1970-01-01 00:00:00.000000000 +0000 +++ tryton-server-7.0.30/debian/patches/05_enforce_access_check_export_data.patch 2025-11-25 11:22:34.000000000 +0000 @@ -0,0 +1,47 @@ +Description: Enforce access check in export_data + As the method is using instances to construct the exported data, the access + must be checked explicitly. +Author: Cédric Krier +Bug-Debian: https://bugs.debian.org/1121243 +Last-Update: 2025-11-25 +Bug-Upstream: https://foss.heptapod.net/tryton/tryton/-/issues/14366 + +--- a/trytond/model/modelstorage.py ++++ b/trytond/model/modelstorage.py +@@ -699,6 +699,11 @@ + @staticmethod + def __export_row(record, fields_names): + pool = Pool() ++ ModelAccess = pool.get('ir.model.access') ++ ModelFieldAccess = pool.get('ir.model.field.access') ++ Rule = pool.get('ir.rule') ++ IrModel = pool.get('ir.model') ++ + lines = [] + data = ['' for x in range(len(fields_names))] + done = [] +@@ -717,6 +722,24 @@ + field_name, descriptor = field_name.split('.') + eModel = pool.get(value.__name__) + field = eModel._fields[field_name] ++ ++ ModelAccess.check(eModel.__name__, 'read') ++ ModelFieldAccess.check(eModel.__name__, [field_name], 'read') ++ domain = Rule.domain_get(eModel.__name__, mode='read') ++ if (domain ++ and not eval_domain( ++ domain, EvalEnvironment(value, eModel))): ++ clause, clause_global = Rule.get( ++ eModel.__name__, mode='read') ++ rules = [] ++ rules.extend(clause.keys()) ++ rules.extend(clause_global.keys()) ++ raise AccessError(gettext( ++ 'ir.msg_read_rule_error', ++ ids=str(value.id), ++ model=IrModel.get_name(eModel.__name__), ++ rules='\n'.join(r.name for r in rules))) ++ + if field.states and 'invisible' in field.states: + invisible = _record_eval_pyson( + value, field.states['invisible']) diff -Nru tryton-server-7.0.30/debian/patches/series tryton-server-7.0.30/debian/patches/series --- tryton-server-7.0.30/debian/patches/series 2025-04-28 07:07:46.000000000 +0000 +++ tryton-server-7.0.30/debian/patches/series 2025-11-25 11:02:13.000000000 +0000 @@ -1,2 +1,5 @@ 01_avoid_call_to_pypi.patch 02_canonical_timezone.patch +03_traceback_in_RPC.patch +04_enforce_access_check_html_editor.patch +05_enforce_access_check_export_data.patch