Add support for Pushover notifications#3591
Add support for Pushover notifications#3591dguerri wants to merge 1 commit intosemaphoreui:developfrom
Conversation
Add Pushover alert integration to enable task status notifications through the Pushover service. This includes configuration options in the interactive setup, alert sending functionality, and template support for customized alert messages. The implementation follows the existing pattern used for other notification providers like Gotify and Microsoft Teams
There was a problem hiding this comment.
Security Review — Add support for Pushover notifications
1 medium-severity finding identified.
Summary
This PR adds Pushover notification support following the same pattern used by existing alert integrations (Telegram, Gotify, Slack, etc.). The overall implementation is straightforward. One concrete security concern was identified related to credential exposure through error logging.
| # | Severity | Finding | Location |
|---|---|---|---|
| 1 | Medium | Pushover credentials leaked in task logs on HTTP errors | services/tasks/alert.go (new sendPushoverAlert) |
A second, lower-confidence observation about JSON injection via text/template is noted inline but is a pre-existing codebase-wide pattern rather than a regression specific to this PR.
Sent by Cursor Automation: Find vulnerabilities
| t.Log("Attempting to send pushover alert") | ||
|
|
||
| resp, err := http.Post( | ||
| fmt.Sprintf( | ||
| "https://api.pushover.net/1/messages.json?user=%s&token=%s", | ||
| util.Config.PushoverUserKey, | ||
| util.Config.PushoverToken), | ||
| "application/json", | ||
| body, |
There was a problem hiding this comment.
Severity: Medium — Secret leakage via error logs
The Pushover user key and token are embedded in the URL query string. When http.Post fails (DNS error, TLS failure, timeout, connection refused, etc.), Go's net/http includes the full URL in the returned error message. That error is then passed to t.Log() on line 563, which broadcasts it to all project users via WebSocket and persists it in the task log database.
This leaks server-level configuration secrets to any user with access to the project.
// Current — credentials in URL, leaked on error:
t.Log("Can't send pushover alert! Error: " + err.Error())
// err.Error() → `Post "https://api.pushover.net/1/messages.json?user=SECRET&token=SECRET": dial tcp: ...`The Pushover API accepts user and token as fields in the JSON POST body, so there is no need to put them in the URL. Recommended fix: move user and token into the JSON template body and POST to the bare endpoint https://api.pushover.net/1/messages.json.
// Fixed — credentials in body, not URL:
resp, err := http.Post(
"https://api.pushover.net/1/messages.json",
"application/json",
body,
)And add to pushover.tmpl:
{
"user": "{{.PushoverUserKey}}",
"token": "{{.PushoverToken}}",
...
}(Note: the same pattern exists in the Gotify and Telegram alert senders, but those APIs require the token in the URL path/query. Pushover does not.)
| "html": 1, | ||
| "priority": {{ if eq .Task.Status "error" }}1{{ else }}0{{ end }}, | ||
| "title": "Task: {{ .Name }}", | ||
| "message": "Execution #: {{ .Task.ID }}\n<font color=\"{{ .Color }}\"><b>{{ .Task.Result }}</b></font>\n{{ if .Task.Version }}Version: {{ .Task.Version }}\n{{ end }}\nDescription: {{ .Task.Desc }}\nAuthor: {{ .Author }}", |
There was a problem hiding this comment.
Observation (Low, codebase-wide pattern) — JSON injection via text/template
User-controlled values (.Name from template name, .Task.Desc from task message, .Author from username) are interpolated into JSON using Go's text/template, which performs no escaping. A " character in any of these fields breaks the JSON structure.
For example, a task message of pwned", "priority": 2, "retry": 30, "expire": 86400, "x": " would inject an emergency-priority notification that repeats every 30 seconds.
This is the same pattern used by all other alert templates in this codebase (telegram, slack, rocketchat, etc.), so it is not a regression unique to this PR. Flagging for awareness — the proper fix would be to use encoding/json marshaling or a custom template function for JSON-safe escaping across all alert senders.
|
@fiftin I am puzzled by the CICD erorrs. |


Add support for Pushover notifications
Fixes #3693 and #2594