Skip to content

fix: 11 bugs including critical data-loss and security issues#3974

Closed
mishrarenu066-beep wants to merge 1 commit intoMHSanaei:mainfrom
mishrarenu066-beep:fix/comprehensive-bugfixes
Closed

fix: 11 bugs including critical data-loss and security issues#3974
mishrarenu066-beep wants to merge 1 commit intoMHSanaei:mainfrom
mishrarenu066-beep:fix/comprehensive-bugfixes

Conversation

@mishrarenu066-beep
Copy link
Copy Markdown

Summary

This PR fixes 11 bugs found through a comprehensive deep scan of the entire codebase, including 4 critical issues that cause data loss or security vulnerabilities.


🔴 Critical Fixes

1. DATA LOSS: 5 functions silently delete all other clients when updating one

Files: web/service/inbound.go
Functions: SetClientTelegramUserID, ToggleClientEnableByEmail, ResetClientIpLimitByEmail, ResetClientExpiryTimeByEmail, ResetClientTrafficLimitByEmail

All five functions had the same copy-paste bug: they built a newClients slice by only appending the client matching the target email, then replaced the entire client list with just that one client. Every other client in the inbound was silently deleted.

// BEFORE (buggy) - discards all non-matching clients:
var newClients []any
for _, c := range clients {
    if c["email"] == targetEmail {
        c["field"] = newValue
        newClients = append(newClients, c)  // ONLY matching client added
    }
}
settings["clients"] = newClients  // ALL OTHER CLIENTS LOST!

// AFTER (fixed) - updates in place:
for i, c := range clients {
    if c["email"] == targetEmail {
        c["field"] = newValue
        clients[i] = c
        break
    }
}
settings["clients"] = clients  // all clients preserved

2. DATA LOSS: ResetSettings() never deletes user credentials

File: web/service/setting.go

The function called .Where("1 = 1").Error instead of .Delete(model.User{}).Error. This only reads the error from a query that does nothing — users were never deleted on reset.

3. SECURITY: WebSocket CheckOrigin allows cross-origin hijacking

File: web/controller/websocket.go

The fallback || originHost == "" || requestHost == "" accepted any origin with a missing host component, allowing WebSocket hijacking from malicious sites. Removed the fallback and added proper host normalization.

4. GRACEFUL SHUTDOWN: Server.Stop() uses cancelled context

Files: web/web.go, sub/sub.go

s.cancel() was called before s.httpServer.Shutdown(s.ctx), making the context already-done. Shutdown returned immediately (forced kill) instead of gracefully draining connections. Moved s.cancel() to end and used context.WithTimeout(10s).


🟡 Medium Fixes

5. Wrong success messages on error paths (~11 endpoints)

File: web/controller/inbound.go

When validation failed, endpoints returned messages like "inboundUpdateSuccess" alongside the error. Fixed to use "somethingWentWrong" for all error paths.

6. resetAllTraffics/resetAllClientTraffics trigger restart on error

SetToNeedRestart() was in an else block that ran even on failure. Restructured to only call after confirming success.

7. disableInvalidClients has duplicate unreachable error check

Same "User %s not found" string check was nested twice. Removed the inner duplicate.

8. DelInbound logs uninitialized tag variable

The else branch logged the empty tag variable instead of the actual inbound id.

9. check_cpu_usage.go index-out-of-range panic

cpu.Percent() can return an empty slice. Added len(percent) > 0 guard.

10. Dead code: cron.Remove(entry) on never-added entry

var entry cron.EntryID defaults to 0; cron.Remove(0) is a no-op.

11. checkEmailExistForInbound duplicates checkEmailsExistForClients

Refactored to delegate to existing function instead of reimplementing.


Files Changed

  • web/controller/inbound.go — error messages + flow fixes
  • web/controller/websocket.go — CheckOrigin security fix
  • web/service/inbound.go — 5 client-discard fixes + refactor
  • web/service/setting.go — ResetSettings fix
  • web/web.go — graceful shutdown + dead code removal
  • sub/sub.go — graceful shutdown fix
  • web/job/check_cpu_usage.go — panic guard

## Critical Fixes

### 1. DATA LOSS: 5 functions discard all other clients when updating one
Functions affected:
- SetClientTelegramUserID
- ToggleClientEnableByEmail
- ResetClientIpLimitByEmail
- ResetClientExpiryTimeByEmail
- ResetClientTrafficLimitByEmail

All five built a `newClients` slice by only appending the client
matching the target email, then replaced the entire client list.
Every other client in the inbound was silently deleted.
Fix: update client in-place with break instead of building new slice.

### 2. DATA LOSS: ResetSettings never deletes user credentials
ResetSettings() called `.Where("1 = 1").Error` instead of
`.Delete(model.User{}).Error`. The reset command did nothing to users.

### 3. SECURITY: WebSocket CheckOrigin allows cross-origin hijacking
The fallback `(originHost == "" || requestHost == "")` accepted
any origin with a missing host component. Removed the fallback and
added proper host normalization for IPv6/ports.

### 4. GRACEFUL SHUTDOWN: Server.Stop() uses cancelled context
s.cancel() was called before s.httpServer.Shutdown(s.ctx), making
the context already-done. Shutdown returned immediately (forced kill)
instead of waiting 10 seconds. Moved s.cancel() to end and used
context.WithTimeout(10s) for shutdown. Same fix applied to sub.go.

## Medium Fixes

### 5. Wrong success messages on error paths (~11 endpoints)
When validation failed, endpoints returned messages like
"inboundUpdateSuccess" alongside the error. Fixed to use
"somethingWentWrong" for all error paths.

### 6. resetAllTraffics/resetAllClientTraffics trigger restart on error
SetToNeedRestart() was called in else branch that ran even on failure.
Restructured to only call after confirming success.

### 7. disableInvalidClients has duplicate unreachable error check
Same "User %s not found" string check was nested twice.
Removed the inner duplicate.

### 8. DelInbound logs uninitialized tag variable
The else branch logged empty tag variable instead of actual inbound id.

### 9. check_cpu_usage.go index-out-of-range panic
cpu.Percent() can return empty slice. Added len(percent) > 0 guard.

### 10. Dead code: cron.Remove(entry) on never-added entry
var entry cron.EntryID defaults to 0; cron.Remove(0) is a no-op.

### 11. checkEmailExistForInbound duplicates checkEmailsExistForClients
Refactored to delegate to existing function instead of reimplementing.
chatgpt-codex-connector[bot]

This comment was marked as outdated.

This comment was marked as outdated.

@MHSanaei MHSanaei closed this Apr 19, 2026
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.

3 participants