Fix SQL injection and refresh scheduling in convoy panel

- Add convoyID validation with regex pattern ^hq-[a-zA-Z0-9-]+$
  to prevent SQL injection in getTrackedIssueStatus (gt-ur4c4)
- Fix duplicate refresh scheduling: tick schedules fetch, fetch
  schedules next tick (gt-yqfrx)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
gastown/crew/gus
2025-12-30 23:23:12 -08:00
committed by Steve Yegge
parent d37bd53a90
commit 4178940d39
2 changed files with 15 additions and 2 deletions

View File

@@ -6,6 +6,7 @@ import (
"fmt"
"os/exec"
"path/filepath"
"regexp"
"sort"
"strings"
"time"
@@ -13,6 +14,9 @@ import (
"github.com/charmbracelet/lipgloss"
)
// convoyIDPattern validates convoy IDs to prevent SQL injection
var convoyIDPattern = regexp.MustCompile(`^hq-[a-zA-Z0-9-]+$`)
// Convoy represents a convoy's status for the dashboard
type Convoy struct {
ID string `json:"id"`
@@ -145,9 +149,15 @@ type trackedStatus struct {
// getTrackedIssueStatus queries tracked issues and their status
func getTrackedIssueStatus(beadsDir, convoyID string) []trackedStatus {
// Validate convoyID to prevent SQL injection
if !convoyIDPattern.MatchString(convoyID) {
return nil
}
dbPath := filepath.Join(beadsDir, "beads.db")
// Query tracked dependencies from SQLite
// convoyID is validated above to match ^hq-[a-zA-Z0-9-]+$
cmd := exec.Command("sqlite3", "-json", dbPath,
fmt.Sprintf(`SELECT depends_on_id FROM dependencies WHERE issue_id = '%s' AND type = 'tracks'`, convoyID))

View File

@@ -190,11 +190,14 @@ func (m *Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
case convoyUpdateMsg:
if msg.state != nil {
// Fresh data arrived - update state and schedule next tick
m.convoyState = msg.state
m.updateViewContent()
cmds = append(cmds, m.convoyRefreshTick())
} else {
// Tick fired - fetch new data
cmds = append(cmds, m.fetchConvoys())
}
// Schedule next refresh
cmds = append(cmds, m.fetchConvoys(), m.convoyRefreshTick())
case tickMsg:
cmds = append(cmds, tick())