Skip to content

fix: XML-escape dynamic values in launchd plist (#181) - #206

Open
leanworld7-netizen wants to merge 1 commit into
monk-io:mainfrom
leanworld7-netizen:fix/xml-escape-launchd-plist-181
Open

fix: XML-escape dynamic values in launchd plist (#181)#206
leanworld7-netizen wants to merge 1 commit into
monk-io:mainfrom
leanworld7-netizen:fix/xml-escape-launchd-plist-181

Conversation

@leanworld7-netizen

Copy link
Copy Markdown

Summary

The macOS start_with_launchd() function writes dynamic values ($agent_path, $auth_url, $auth_client_id, $auth_audience, $autospin_url, $MONK_AGENT_LOCAL, $MONK_PLUGIN_VERSION, $host, $agent_path_env) directly into the launchd plist XML using a heredoc without XML escaping.

If any of these values contain XML-special characters (&, <, >, ", '), the resulting plist is malformed XML that launchd silently rejects — the agent never starts and no error is surfaced to the user.

Fix

Adds an xml_escape() shell function that performs the five required XML entity replacements (&&amp;, <&lt;, >&gt;, "&quot;, '&apos;) and applies it to all dynamic values before they are interpolated into the plist heredoc.

The launchd_configured() grep checks are also updated to match against the escaped values, ensuring the idempotency check correctly detects an already-configured plist.

Testing

  • Verified that paths containing & (e.g., /tmp/agent&fixture/monk-agent) are properly escaped to /tmp/agent&amp;fixture/monk-agent in the plist XML
  • The escaped plist is valid XML that launchd accepts
  • Paths without special characters are unaffected (escaping is a no-op)

Fixes #181

Bounty eligibility: I have signed up at monk.io and used the product.

The macOS start_with_launchd() function writes dynamic values
($agent_path, $auth_url, $auth_client_id, $auth_audience,
$autospin_url, $MONK_AGENT_LOCAL, $MONK_PLUGIN_VERSION, $host,
$agent_path_env) directly into the launchd plist XML using a
heredoc without XML escaping.

If any of these values contain XML-special characters (&, <, >, ",
'), the resulting plist is malformed XML that launchd silently
rejects — the agent never starts and no error is surfaced.

This adds an xml_escape() shell function that performs the five
required XML entity replacements and applies it to all dynamic
values before they are interpolated into the plist heredoc.

The launchd_configured() grep checks are also updated to match
against the escaped values, ensuring the idempotency check
correctly detects an already-configured plist.

Fixes monk-io#181
@leanworld7-netizen

Copy link
Copy Markdown
Author

Linking to bounty issue #181. This fix addresses the reported vulnerability. Ready for review.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug bounty] macOS launcher writes unescaped values into its launchd plist

1 participant