50 lines
2.6 KiB
Markdown
50 lines
2.6 KiB
Markdown
## Tryton (trytond) 5-MOAD Scan — 2026-03-31
|
|
|
|
Target: https://github.com/tryton/trytond (depth=1)
|
|
Focus: trytond/model/, trytond/ir/, trytond/res/, trytond/protocols/
|
|
|
|
### MOAD-0001 (CWE-407) — 1 PRE-EXISTING DEFECT (tryton-0001)
|
|
|
|
Tryton uses sets and dicts throughout hot paths. Specific checks:
|
|
|
|
- `ir/model.py` `fill_models()`: uses a list for visited-set dedup but the list is
|
|
bounded by the number of models in a single access check (typically 1-10) and is
|
|
only called at access-check time, not in a per-record inner loop. Low severity.
|
|
- `model/tree.py` `check_recursion()`: `visited = set()` throughout. O(1) lookup.
|
|
- `model/modelsql.py`: field membership checks use dicts/sets. O(1) throughout.
|
|
- `ir/translation.py`: `trans_reports` and `strings` are dicts. O(1) lookups.
|
|
- `ir/rule.py`: domain building uses `defaultdict(list)`, no membership scans.
|
|
- `model/modelstorage.py` `_save_values()`: pre-existing defect — `previous` list
|
|
O(T*P) in one2many/many2many save. Fixed in tryton-0001.
|
|
|
|
### MOAD-0002 (Intertangle) — CLEAN
|
|
|
|
`Pool` is our class registry (model, wizard, report types per database). It is
|
|
intentionally a registry/locator pattern, not a god object coupling subsystems.
|
|
Modules load independently via `load_modules`. Transaction, Pool, Cache and Model
|
|
layers are cleanly separated. No shared mutable state coupling unrelated subsystems.
|
|
|
|
### MOAD-0003 (Leaked Context) — CLEAN
|
|
|
|
`Transaction._local = threading.local()` is an intentional per-thread transaction
|
|
stack for the WSGI worker thread model. The `_request` context key is explicitly
|
|
stripped from cache keys (`cache.py` `_key()` strips `_request`). The transaction
|
|
carries user ID, database name, and context, which are properly scoped to each
|
|
thread's request lifetime and cleared on `stop()`. This is a standard WSGI
|
|
thread-per-request pattern, not a leaked identity defect.
|
|
|
|
### MOAD-0004 (CWE-312) — CLEAN
|
|
|
|
`protocols/dispatcher.py` routes `common.db.login` to its own `login()` function
|
|
that does NOT call `_safe_repr` or any logger with the `parameters` dict containing
|
|
the password. `security.login()` logs only username and remote address on success
|
|
or failure, never the password or session token. No SMTP or LDAP password logged
|
|
in any logger call found in trytond core.
|
|
|
|
### MOAD-0005 (Thundering Herd) — CLEAN
|
|
|
|
`MemoryCache` uses a per-transaction `_database_cache` (defaultdict of LRUDict).
|
|
The transaction isolation model means each transaction sees a consistent snapshot.
|
|
Cache invalidation uses PostgreSQL `NOTIFY` channels or a polling timeout, not
|
|
concurrent get+compute+set without synchronization. No unsynchronized
|
|
cache stampede pattern found.
|