Imported OpenVPN configs can carry script directives into root execution #197

Closed
opened 2026-08-28 18:22:12 -04:00 by mysticalsoap · 0 comments
Owner

Found while researching #82. Removing the custom-scripts feature closes the GUI channel, but imported OpenVPN configs are a second path to the same place: the root service runs openvpn on whatever config an import produced, and a config can carry script-security 2 itself plus any of up/down/route-up/route-pre-down/ipchange/client-connect. OpenVPN honors config-file script-security unless a later command-line option overrides it, so those directives execute as root on connect.

aqomui's own script use is narrow and known: the bypass appends script-security 2 + route-up bypass_up.sh when building its config (tunnel.py), and hop connections pass --script-security 2 + --up/--down hop.sh on the command line. Nothing aqomui needs lives in an imported config.

WireGuard is already covered: wireguard.py deliberately avoids wg-quick and rejects extension keys, so PostUp/PreDown in an imported wg config never execute. This issue is OpenVPN-only.

Precedent: NetworkManager deliberately ignores PostUp/PreDown when importing wg-quick configs — an import channel granting root exec is treated as a bug, and the sanctioned path is a privilege-symmetric one (dispatcher scripts). Same reasoning as #82.

Possible shapes (picking one is part of the work):

  • Sanitize on import: strip script-type directives and script-security from imported configs, logging what was dropped. aqomui appends its own directives after this point, so an allowlist isn't even needed.
  • Pin on the command line: always pass an explicit --script-security after --config at the level that connection type needs, so a config-file directive can't raise it. Neutralizes rather than removes — and the CLI-overrides-config ordering must be verified against the openvpn versions target distros ship.
  • Refuse the import with a clear error naming the offending directive, making the user remove it deliberately.

Sanitize-on-import matches the NM precedent best and keeps the config a user sees on disk equal to what runs.

Found while researching #82. Removing the custom-scripts feature closes the GUI channel, but imported OpenVPN configs are a second path to the same place: the root service runs openvpn on whatever config an import produced, and a config can carry `script-security 2` itself plus any of `up`/`down`/`route-up`/`route-pre-down`/`ipchange`/`client-connect`. OpenVPN honors config-file `script-security` unless a later command-line option overrides it, so those directives execute as root on connect. aqomui's own script use is narrow and known: the bypass appends `script-security 2` + `route-up bypass_up.sh` when building its config (tunnel.py), and hop connections pass `--script-security 2` + `--up/--down hop.sh` on the command line. Nothing aqomui needs lives in an *imported* config. WireGuard is already covered: wireguard.py deliberately avoids wg-quick and rejects extension keys, so `PostUp`/`PreDown` in an imported wg config never execute. This issue is OpenVPN-only. Precedent: NetworkManager deliberately ignores `PostUp`/`PreDown` when importing wg-quick configs — an import channel granting root exec is treated as a bug, and the sanctioned path is a privilege-symmetric one (dispatcher scripts). Same reasoning as #82. Possible shapes (picking one is part of the work): - **Sanitize on import**: strip script-type directives and `script-security` from imported configs, logging what was dropped. aqomui appends its own directives after this point, so an allowlist isn't even needed. - **Pin on the command line**: always pass an explicit `--script-security` after `--config` at the level that connection type needs, so a config-file directive can't raise it. Neutralizes rather than removes — and the CLI-overrides-config ordering must be verified against the openvpn versions target distros ship. - **Refuse the import** with a clear error naming the offending directive, making the user remove it deliberately. Sanitize-on-import matches the NM precedent best and keeps the config a user sees on disk equal to what runs.
Sign in to join this conversation.
No milestone
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
mysticalsoap/aqomui#197
No description provided.