Skip to content

Commit d0cd492

Browse files
committed
Apply more security extremism
1 parent f9f3496 commit d0cd492

File tree

3 files changed

+26
-16
lines changed

3 files changed

+26
-16
lines changed

cache.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,11 @@ type cacheEntry struct {
2525

2626
// turnData fetches Turn API data with caching.
2727
func (app *App) turnData(ctx context.Context, url string, updatedAt time.Time) (*turn.CheckResponse, bool, error) {
28+
// Validate URL before processing
29+
if err := validateURL(url); err != nil {
30+
return nil, false, fmt.Errorf("invalid URL: %w", err)
31+
}
32+
2833
// Create cache key from URL and updated timestamp
2934
key := fmt.Sprintf("%s-%s", url, updatedAt.Format(time.RFC3339))
3035
hash := sha256.Sum256([]byte(key))
@@ -93,11 +98,11 @@ func (app *App) turnData(ctx context.Context, url string, updatedAt time.Time) (
9398
if cacheData, marshalErr := json.Marshal(entry); marshalErr != nil {
9499
log.Printf("Failed to marshal cache data for %s: %v", url, marshalErr)
95100
} else {
96-
// Ensure cache directory exists
101+
// Ensure cache directory exists with secure permissions
97102
if dirErr := os.MkdirAll(filepath.Dir(cacheFile), 0o700); dirErr != nil {
98103
log.Printf("Failed to create cache directory: %v", dirErr)
99104
} else if writeErr := os.WriteFile(cacheFile, cacheData, 0o600); writeErr != nil {
100-
log.Printf("Failed to write cache file for %s: %v", url, writeErr)
105+
log.Printf("Failed to write cache file: %v", writeErr)
101106
}
102107
}
103108
}

github.go

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,8 @@ func (*App) githubToken(ctx context.Context) (string, error) {
4949
// First check for GITHUB_TOKEN environment variable
5050
if token := os.Getenv("GITHUB_TOKEN"); token != "" {
5151
token = strings.TrimSpace(token)
52-
const minTokenLength = 20
53-
if len(token) < minTokenLength {
54-
return "", fmt.Errorf("invalid GITHUB_TOKEN length: %d", len(token))
52+
if err := validateGitHubToken(token); err != nil {
53+
return "", fmt.Errorf("invalid GITHUB_TOKEN: %w", err)
5554
}
5655
log.Println("Using GitHub token from GITHUB_TOKEN environment variable")
5756
return token, nil
@@ -97,8 +96,11 @@ func (*App) githubToken(ctx context.Context) (string, error) {
9796
const executableMask = 0o111
9897
if info.Mode().IsRegular() && info.Mode()&executableMask != 0 {
9998
// Verify it's actually the gh binary by running version command
100-
cmd := exec.Command(path, "version") //nolint:noctx // Quick version check doesn't need context
99+
// Use timeout to prevent hanging
100+
versionCtx, cancel := context.WithTimeout(ctx, 2*time.Second)
101+
cmd := exec.CommandContext(versionCtx, path, "version")
101102
output, err := cmd.Output()
103+
cancel() // Call cancel immediately after command execution
102104
if err == nil && strings.Contains(string(output), "gh version") {
103105
log.Printf("Found and verified gh at: %s", path)
104106
ghPath = path
@@ -116,16 +118,12 @@ func (*App) githubToken(ctx context.Context) (string, error) {
116118
cmd := exec.CommandContext(ctx, ghPath, "auth", "token")
117119
output, err := cmd.CombinedOutput()
118120
if err != nil {
119-
log.Printf("gh command failed with output: %s", string(output))
120-
return "", fmt.Errorf("exec 'gh auth token': %w (output: %s)", err, string(output))
121+
log.Printf("gh command failed: %v", err)
122+
return "", fmt.Errorf("exec 'gh auth token': %w", err)
121123
}
122124
token := strings.TrimSpace(string(output))
123-
if token == "" {
124-
return "", errors.New("empty github token")
125-
}
126-
const minTokenLength = 20
127-
if len(token) < minTokenLength {
128-
return "", fmt.Errorf("invalid github token length: %d", len(token))
125+
if err := validateGitHubToken(token); err != nil {
126+
return "", fmt.Errorf("invalid token from gh CLI: %w", err)
129127
}
130128
log.Println("Successfully obtained GitHub token from gh CLI")
131129
return token, nil

main.go

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,13 @@ func main() {
130130
flag.DurationVar(&updateInterval, "interval", defaultUpdateInterval, "Update interval (e.g. 30s, 1m, 5m)")
131131
flag.Parse()
132132

133+
// Validate target user if provided
134+
if targetUser != "" {
135+
if err := validateGitHubUsername(targetUser); err != nil {
136+
log.Fatalf("Invalid target user: %v", err)
137+
}
138+
}
139+
133140
// Validate update interval
134141
if updateInterval < minUpdateInterval {
135142
log.Printf("Update interval %v too short, using minimum of %v", updateInterval, minUpdateInterval)
@@ -197,9 +204,9 @@ func main() {
197204
}
198205
app.currentUser = user
199206

200-
// Log if we're using a different target user
207+
// Log if we're using a different target user (sanitized)
201208
if app.targetUser != "" && app.targetUser != user.GetLogin() {
202-
log.Printf("Querying PRs for user '%s' instead of authenticated user '%s'", app.targetUser, user.GetLogin())
209+
log.Printf("Querying PRs for user '%s' instead of authenticated user", sanitizeForLog(app.targetUser))
203210
}
204211

205212
log.Println("Starting systray...")

0 commit comments

Comments
 (0)