Skip to content

Add support for Pushover notifications#3591

Open
dguerri wants to merge 1 commit intosemaphoreui:developfrom
dguerri:develop
Open

Add support for Pushover notifications#3591
dguerri wants to merge 1 commit intosemaphoreui:developfrom
dguerri:develop

Conversation

@dguerri
Copy link
Copy Markdown

@dguerri dguerri commented Feb 5, 2026

Add support for Pushover notifications

Fixes #3693 and #2594

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
Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Open in Web View Automation 

Sent by Cursor Automation: Find vulnerabilities

Comment thread services/tasks/alert.go
Comment on lines +551 to +559
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,
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 }}",
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@dguerri
Copy link
Copy Markdown
Author

dguerri commented Apr 10, 2026

@fiftin I am puzzled by the CICD erorrs.
Should the CI workflow generate a test config via semaphore setup, or is there an expected fixture/config path for .dredd/server-wrapper.sh and the Dredd hooks that is currently missing in PR runs?

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.

Feature: Pushover Support

1 participant