You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
| `DESCRIBE PAGE` output will not re-parse for any page carrying a **pluggable widget**: `mxcli check` on it fails with `extraneous input ':'` / `extraneous input '('` from the first widget onward. Separately, a boolean property the author set is missing from the description entirely | Two independent defects in the same path. **Emit**: explicit properties were written with a raw `%s`, so every string lost its quotes — a JSON `spec: {"a": 1}` then broke the parse at its first brace. **Read**: `extractExplicitProperties` skipped any value of `"true"`/`"false"` as a "common default", so booleans never reached the output | `mdl/executor/cmd_pages_describe_output.go` (`explicitPropValue`, `isBareLiteral`), `mdl/executor/cmd_pages_describe_pluggable.go` (`buildPropertyValueTypeMap`, `extractExplicitProperties`), `mdl/executor/cmd_pages_describe.go` (`rawExplicitProp.ValueType`) | **Fixing one half alone is worse than the bug.** Quote without emitting booleans and the description re-parses cleanly while silently dropping a property — a wrong page that validates. Both halves ship together or neither. **Quote by the DECLARED type, never the value's shape**: `ValueType.Type` sits in the widget's `Type.ObjectType.PropertyTypes`, the same array `buildPropertyTypeKeyMap` already walks for `PropertyKey` and throws away; a String property holding `"30"` or `"true"` is indistinguishable from a number once it is a string in BSON, and must still come back quoted. Where no type is declared, fall back to the value's shape and quote anything not plainly numeric or boolean — quoting is the safe direction, since an unquoted arbitrary string may not parse at all. **The round trip is the test, not the output**: describe → `check` → `exec` → describe must be byte-identical and leave `mx check` at 0 errors. Tests `mdl/executor/cmd_pages_describe_pluggable_roundtrip_test.go`; example `mdl-examples/bug-tests/pluggable-describe-roundtrip.mdl`, verified end to end on 11.12.1. **Uncovered while verifying, NOT fixed**: giving a property in a conditionally shown group a non-default value writes a widget Mendix rejects with CE0463 — ProgressCircle's `showLabel: true` and `labelType: 'percentage'` both do it with no DESCRIBE involved, while the same widget's General-group properties take non-default values happily. Reported in mxcli-ledger FINDINGS #104 |
516
516
| `DESCRIBE PAGE` output will not re-parse for any page carrying a **pluggable widget**: `mxcli check` on it fails with `extraneous input ':'` / `extraneous input '('` from the first widget onward. Separately, a boolean property the author set is missing from the description entirely | Two independent defects in the same path. **Emit**: explicit properties were written with a raw `%s`, so every string lost its quotes — a JSON `spec: {"a": 1}` then broke the parse at its first brace. **Read**: `extractExplicitProperties` skipped any value of `"true"`/`"false"` as a "common default", so booleans never reached the output | `mdl/executor/cmd_pages_describe_output.go` (`explicitPropValue`, `isBareLiteral`), `mdl/executor/cmd_pages_describe_pluggable.go` (`buildPropertyValueTypeMap`, `extractExplicitProperties`), `mdl/executor/cmd_pages_describe.go` (`rawExplicitProp.ValueType`) | **Fixing one half alone is worse than the bug.** Quote without emitting booleans and the description re-parses cleanly while silently dropping a property — a wrong page that validates. Both halves ship together or neither. **Quote by the DECLARED type, never the value's shape**: `ValueType.Type` sits in the widget's `Type.ObjectType.PropertyTypes`, the same array `buildPropertyTypeKeyMap` already walks for `PropertyKey` and throws away; a String property holding `"30"` or `"true"` is indistinguishable from a number once it is a string in BSON, and must still come back quoted. Where no type is declared, fall back to the value's shape and quote anything not plainly numeric or boolean — quoting is the safe direction, since an unquoted arbitrary string may not parse at all. **The round trip is the test, not the output**: describe → `check` → `exec` → describe must be byte-identical and leave `mx check` at 0 errors. Tests `mdl/executor/cmd_pages_describe_pluggable_roundtrip_test.go`; example `mdl-examples/bug-tests/pluggable-describe-roundtrip.mdl`, verified end to end on 11.12.1. Reported in mxcli-ledger FINDINGS #104 |
517
517
| Authoring a pluggable widget property that lives in a **conditionally shown group** writes a widget Mendix rejects with **CE0463**, while the same widget's other properties take non-default values happily. On ProgressCircle both `showLabel: true` and `labelType: 'percentage'` do it; `showLabel: false` and General-group properties are clean. No DESCRIBE involved | Two gaps on the same axis. **Serialization**: #574 nulls the TextTemplate of a HIDDEN conditional property, but left a VISIBLE one null — and Mendix stores an empty `Forms$ClientTemplate` there. Null and empty are each invalid in the other's state, so nulling hidden ones was only half the rule. **Extraction**: the editorConfig reader did not understand a ternary's ELSE branch (`cond ? (…) : hidePropertiesIn([…])`), so the `showLabel` gate was never seen and `labelText` read as visible whenever `labelType` was `"text"` — its default | `mdl/backend/widgetobj/builder.go` (`ApplyVisibilityRules`, `bsonFieldIsNil`), `mdl/executor/editorconfig_extract.go` (`parseGuard` `:` case, `ternaryCondition`, `trailingExpr`) | **Fixing one gap alone inverts the bug rather than closing it** — filling visible templates without the missing gate made `showLabel: false` fail where `true` had, because mxcli still thought labelText was visible. Measured both ways round before and after; a fix that moves which case fails is not a fix. **Let Mendix say what the shape should be**: `mx update-widgets` on a COPY of the failing project reconciles the widget, and diffing that against mxcli's output named the single meaningful path (`Object/Properties[N]/Value/TextTemplate` null vs `Forms$ClientTemplate`) out of 969. **The good/bad control does the isolation for free**: authoring the same widget with the boolean both ways gave two documents differing in exactly ONE path, so no other candidate needed testing. **Only CONDITIONAL properties are filled** — Studio Pro's convention for an unset TextTemplate is not uniform (a DataGrid custom-content column stores null for `tooltip` and an empty template for `exportValue`, per `emptyClientTemplateRules`), so filling every unset one would trade this bug for its mirror image. **The extractor's preamble matters**: the ternary is preceded by a whole `switch`, and walking back past the `?` to the function start yields a fragment with an unbalanced `}` that parses to nothing and looks like "unsupported shape" — hence `trailingExpr`. Regression signal: the widgetdemo showcase applies with **0 CE0463** (its 4 CE1613 are a pre-existing attribute reference). Tests `mdl/backend/widgetobj/widget_visibility_test.go`, `mdl/executor/editorconfig_extract_test.go`; example `mdl-examples/bug-tests/pluggable-describe-roundtrip.mdl` now exercises the group. Reported in mxcli-ledger FINDINGS #104 follow-on |
518
+
| Windows Defender flags the mxcli **Windows** release binary as `Trojan:Script/Sabsik.EN.A!ml`; enterprise EDR (Defender for Endpoint, CrowdStrike, SentinelOne) blocks it harder. Not the generic unsigned-Go-binary false positive of #185 | The binary genuinely embedded **chisel**, a dual-use tunnelling/pivoting tool (SSH over WebSocket), on every platform — although the tunnel only ever runs inside a Linux container. `run --hub` linked `chisel/client`, `tunnel-hub` linked `chisel/server`, so windows/darwin carried 32 packages incl. the whole `x/crypto/ssh` stack for a feature they cannot use | `cmd/mxcli/docker/tunnel_linux.go` + `tunnel_other.go` (client seam), `cmd/mxcli/tunnelhub/control_linux.go` + `control_other.go` (server seam), `scripts/check-tunnel-deps.sh` (guard) | **Never obfuscate, pack or rename to dodge the scanner** — attacker tradecraft, and it makes the binary less trustworthy, not more. **Code signing does not fix this class**: a signed binary containing chisel is still flagged behaviourally; signing only addresses #185's generic false positive. The fix is to stop shipping the capability where it is unused: one interface per seam, `_linux.go` impl + `!linux` stub, commands still registered everywhere but failing with an actionable message. **Prove absence three ways, and know that `go tool nm` is not one of them** — release ldflags `-s -w` strip the symbol table, so nm reports "no symbols" whether or not the code is linked and would give a false pass; use `go list -deps`, `go version -m`, and `strings` (nm only on a deliberately unstripped build). **Guard against the transitive path, not the name**: match the module list (`x/crypto/ssh`, `gorilla/websocket`, `armon/go-socks5`, `jpillora/*`) so re-entry without the word "chisel" still trips it, and assert a **positive control** (chisel IS in the linux graph) so the check cannot pass vacuously. Verified by re-adding the import and watching the guard fail on all four windows/darwin targets. Result: -13.5 MB (-14.7%) on windows+darwin, linux unchanged. See ADR-0009 |
Copy file name to clipboardExpand all lines: CHANGELOG.md
+4Lines changed: 4 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -8,6 +8,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
8
8
9
9
### Changed
10
10
11
+
- **The embedded tunnel now ships in the Linux build only** (`mxcli run --hub`, `mxcli tunnel-hub`). The tunnel embeds [chisel](https://github.com/jpillora/chisel), a dual-use tunnelling tool that appears in threat intelligence as a pivoting component. It only ever runs inside a Linux container, but every platform linked it — so Microsoft Defender flagged the Windows binary (`Trojan:Script/Sabsik.EN.A!ml`) and enterprise EDR flags this class of payload harder still, blocking mxcli on the managed corporate endpoints most Mendix developers use. Both chisel imports now sit behind a one-interface, Linux-only seam; a CI guard (`scripts/check-tunnel-deps.sh`, `make check-tunnel-deps`) fails the build if chisel or its SSH/websocket/socks dependencies reappear in a windows/darwin dependency graph. **Windows and macOS release binaries are 13.5 MB smaller (-14.7%)** and contain no tunnelling code. The Linux build is unchanged. On other platforms the two commands remain registered and documented but fail with an actionable message. Note that this is a *different* problem from the `Wacatac.C!ml` report in [#185](https://github.com/mendixlabs/mxcli/issues/185), which was a genuine generic Go-binary false positive: here the capability really was in the binary, and code signing would not have addressed it. We did not obfuscate or repack anything — the fix is not shipping the capability where it is unused. ([#890](https://github.com/mendixlabs/mxcli/issues/890), [ADR-0009](docs/13-decisions/0009-tunnel-is-linux-only.md))
12
+
-**Breaking, narrow:**`mxcli tunnel-hub` can no longer be hosted on Windows or macOS — move the hub to a Linux host. Developers on native Windows/macOS installs must run mxcli inside the project's devcontainer to use `--hub`.
13
+
-`tunnelhub.ServerOptions.ChiselAddr` is renamed to `ControlAddr` (it addresses the platform-agnostic control server).
14
+
11
15
-**Go toolchain 1.26.5 → 1.26.6** for GO-2026-6218 (`net/url`), GO-2026-6090 (`crypto/tls`), GO-2026-6089 (`net/http`), GO-2026-6088 (`encoding/xml`), GO-2026-5972 (`encoding/asn1`) and GO-2026-5026 (`net/http`, via `golang.org/x/net/idna`). All six are standard-library advisories fixed in go1.26.6; no mxcli code changed. Bumped in `go.mod` and in all three workflows (`push-test`, `release`, `nightly`) together, so released binaries are not still linked against the vulnerable standard library.
0 commit comments