Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion api/integration.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,12 @@ func (c *IntegrationController) ReceiveIntegration(w http.ResponseWriter, r *htt
}

if integration.ProjectID != project.ID {
panic("")
log.WithFields(log.Fields{
"context": "integrations",
"project_id": project.ID,
"integrationId": integration.ID,
}).Error("integration project mismatch")
continue
}

err = c.integrationService.FillIntegration(&integration)
Expand Down
21 changes: 17 additions & 4 deletions api/login.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,14 @@
var l *ldap.Conn
var err error
if util.Config.LdapNeedTLS {
l, err = ldap.DialTLS("tcp", util.Config.LdapServer, &tls.Config{
InsecureSkipVerify: true,
// Enforce proper certificate verification for TLS LDAP connections
// Extract hostname for SNI/verification when server is provided as host:port
serverName := util.Config.LdapServer
if i := strings.LastIndex(serverName, ":"); i > -1 {
serverName = serverName[:i]
}
l, err = ldap.DialTLS("tcp", util.Config.LdapServer, &tls.Config{ // #nosec G402 - explicit secure config

Check warning on line 60 in api/login.go

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

api/login.go#L60

`MinVersion` is missing from this TLS configuration.
ServerName: serverName,
Copy link

Choose a reason for hiding this comment

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

Bug: LDAP TLS ServerName Extraction Fails

The TLS ServerName for LDAP connections is incorrectly extracted from LdapServer by trimming the port using strings.LastIndex(":"). This fails for bracketed IPv6 addresses, leaving brackets in the ServerName. The resulting invalid ServerName causes TLS SNI/hostname verification to fail, preventing successful LDAP logins.

Fix in Cursor Fix in Web

})
} else {
l, err = ldap.Dial("tcp", util.Config.LdapServer)
Expand Down Expand Up @@ -203,7 +209,12 @@
"session": newSession.ID,
})
if err != nil {
panic(err)
log.WithError(err).WithFields(log.Fields{
"user_id": user.ID,
"context": "session",
}).Error("Failed to encode session cookie")
helpers.WriteErrorStatus(w, "Failed to create session", http.StatusInternalServerError)
return
}

http.SetCookie(w, &http.Cookie{
Expand Down Expand Up @@ -518,7 +529,9 @@
b := make([]byte, 16)
_, err := rand.Read(b)
if err != nil {
panic(err)
log.WithError(err).Error("Failed to generate OAuth state")
// Fallback to time-based state to keep flow usable
b = []byte(fmt.Sprintf("%d", tz.Now().UnixNano()))
}
oauthState := base64.URLEncoding.EncodeToString(b)
cookie := http.Cookie{Name: "oauthstate", Value: oauthState, Expires: expiration}
Expand Down
31 changes: 21 additions & 10 deletions db/sql/SqlDb.go
Original file line number Diff line number Diff line change
Expand Up @@ -467,7 +467,16 @@

defer conn.Close() //nolint:errcheck

_, err = conn.Exec("create database " + cfg.GetDbName())
// Create database with dialect-appropriate identifier quoting
dbName := cfg.GetDbName()
switch cfg.Dialect {
case util.DbDriverMySQL:
_, err = conn.Exec("create database `" + dbName + "`")

Check failure on line 474 in db/sql/SqlDb.go

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

db/sql/SqlDb.go#L474

Detected string concatenation with a non-literal variable in a "database/sql" Go SQL statement.

Check failure on line 474 in db/sql/SqlDb.go

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

db/sql/SqlDb.go#L474

SQL Injection is a critical vulnerability that can lead to data or system compromise.
case util.DbDriverPostgres:
_, err = conn.Exec("create database \"" + dbName + "\"")

Check failure on line 476 in db/sql/SqlDb.go

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

db/sql/SqlDb.go#L476

Detected string concatenation with a non-literal variable in a "database/sql" Go SQL statement.

Check failure on line 476 in db/sql/SqlDb.go

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

db/sql/SqlDb.go#L476

SQL Injection is a critical vulnerability that can lead to data or system compromise.
default:
_, err = conn.Exec("create database " + dbName)

Check failure on line 478 in db/sql/SqlDb.go

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

db/sql/SqlDb.go#L478

Detected string concatenation with a non-literal variable in a "database/sql" Go SQL statement.

Check failure on line 478 in db/sql/SqlDb.go

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

db/sql/SqlDb.go#L478

SQL Injection is a critical vulnerability that can lead to data or system compromise.
}
if err != nil {
log.Warn(err.Error())
}
Expand Down Expand Up @@ -759,13 +768,9 @@
}

func (d *SqlDb) CreateObject(props db.ObjectProps, object any) (newObject any, err error) {
// err = newObject.Validate()
// Validation can be added here if needed

if err != nil {
return
}

template, args := InsertTemplateFromType(newObject)
template, args := InsertTemplateFromType(object)
insertID, err := d.insert(
"id",
"insert into "+props.TableName+" "+template, args...)
Expand All @@ -774,10 +779,16 @@
}

newObject = object

v := reflect.ValueOf(newObject)
field := v.FieldByName("ID")
field.SetInt(int64(insertID))
if v.Kind() == reflect.Pointer {
v = v.Elem()
}
if v.IsValid() && v.CanSet() {
field := v.FieldByName("ID")
if field.IsValid() && field.CanSet() && field.Kind() == reflect.Int {
field.SetInt(int64(insertID))
}
}

return
}
Expand Down
10 changes: 5 additions & 5 deletions db/sql/migration.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@ package sql

import (
"fmt"
"github.com/go-gorp/gorp/v3"
"github.com/semaphoreui/semaphore/pkg/tz"
"path"
"regexp"
"strings"

"github.com/go-gorp/gorp/v3"
"github.com/semaphoreui/semaphore/pkg/tz"

"github.com/semaphoreui/semaphore/db"
log "github.com/sirupsen/logrus"
)
Expand Down Expand Up @@ -159,7 +160,7 @@ func (d *SqlDb) ApplyMigration(migration db.Migration) error {

queries := getVersionSQL(getVersionPath(migration), false)
for i, query := range queries {
fmt.Printf("\r [%d/%d]", i+1, len(query))
fmt.Printf("\r [%d/%d]", i+1, len(queries))

if len(query) == 0 {
continue
Expand All @@ -173,8 +174,7 @@ func (d *SqlDb) ApplyMigration(migration db.Migration) error {
_, err = tx.Exec(q)
if err != nil {
handleRollbackError(tx.Rollback())
log.Warnf("\n ERR! Query: %s\n\n", q)
log.Fatal(err.Error())
log.WithError(err).Warnf("\n ERR! Query: %s\n\n", q)
return err
}
}
Expand Down
12 changes: 8 additions & 4 deletions services/runners/job_pool.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ func (p *JobPool) Unregister() (err error) {
return fmt.Errorf("runner is not registered")
}

client := &http.Client{}
client := &http.Client{Timeout: 15 * time.Second}

url := util.Config.WebHost + "/api/internal/runners"

Expand All @@ -140,6 +140,10 @@ func (p *JobPool) Unregister() (err error) {
return
}

if resp != nil {
defer resp.Body.Close() //nolint:errcheck
}

if util.Config.Runner.TokenFile != "" {
err = os.Remove(util.Config.Runner.TokenFile)
}
Expand Down Expand Up @@ -240,7 +244,7 @@ func (p *JobPool) sendProgress() {

logger := JobLogger{Context: "sending_progress"}

client := &http.Client{}
client := &http.Client{Timeout: 15 * time.Second}

url := util.Config.WebHost + "/api/internal/runners"

Expand Down Expand Up @@ -338,7 +342,7 @@ func (p *JobPool) tryRegisterRunner(configFilePath *string) (ok bool) {
return
}

client := &http.Client{}
client := &http.Client{Timeout: 15 * time.Second}

url := util.Config.WebHost + "/api/internal/runners"

Expand Down Expand Up @@ -489,7 +493,7 @@ func (p *JobPool) checkNewJobs() {
return
}

client := &http.Client{}
client := &http.Client{Timeout: 15 * time.Second}

url := util.Config.WebHost + "/api/internal/runners"

Expand Down
12 changes: 8 additions & 4 deletions services/tasks/RemoteJob.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@ import (
"bytes"
"encoding/json"
"fmt"
"github.com/semaphoreui/semaphore/pkg/tz"
log "github.com/sirupsen/logrus"
"net/http"
"time"

"github.com/semaphoreui/semaphore/pkg/tz"
log "github.com/sirupsen/logrus"

"github.com/semaphoreui/semaphore/db"
"github.com/semaphoreui/semaphore/pkg/task_logger"
"github.com/semaphoreui/semaphore/util"
Expand Down Expand Up @@ -52,7 +53,7 @@ func callRunnerWebhook(runner *db.Runner, tsk *TaskRunner, action string) (err e
return
}

client := &http.Client{}
client := &http.Client{Timeout: 15 * time.Second}

var req *http.Request
req, err = http.NewRequest("POST", runner.Webhook, bytes.NewBuffer(jsonBytes))
Expand All @@ -67,6 +68,9 @@ func callRunnerWebhook(runner *db.Runner, tsk *TaskRunner, action string) (err e
if err != nil {
return
}
if resp != nil {
defer resp.Body.Close() //nolint:errcheck
}

if resp.StatusCode != 200 && resp.StatusCode != 204 {
err = fmt.Errorf("webhook returned incorrect status")
Expand Down Expand Up @@ -152,7 +156,7 @@ func (t *RemoteJob) Run(username string, incomingVersion *string, alias string)
break
}

time.Sleep(1_000_000_000)
time.Sleep(time.Second)
tsk = t.taskPool.GetTask(t.Task.ID)
if tsk.Task.Status == task_logger.TaskSuccessStatus ||
tsk.Task.Status == task_logger.TaskStoppedStatus ||
Expand Down
32 changes: 25 additions & 7 deletions services/tasks/alert.go
Original file line number Diff line number Diff line change
Expand Up @@ -179,9 +179,12 @@ func (t *TaskRunner) sendTelegramAlert() {
t.Log("Can't send telegram alert! Error: " + err.Error())
} else if resp.StatusCode != 200 {
t.Log("Can't send telegram alert! Response code: " + strconv.Itoa(resp.StatusCode))
} else {
t.Log("Sent successfully telegram alert")
}
if resp != nil {
defer resp.Body.Close() //nolint:errcheck
}

t.Log("Sent successfully telegram alert")
}

func (t *TaskRunner) sendSlackAlert() {
Expand Down Expand Up @@ -241,6 +244,9 @@ func (t *TaskRunner) sendSlackAlert() {
} else {
t.Log("Sent successfully slack alert")
}
if resp != nil {
defer resp.Body.Close() //nolint:errcheck
}
}

func (t *TaskRunner) sendRocketChatAlert() {
Expand Down Expand Up @@ -297,9 +303,12 @@ func (t *TaskRunner) sendRocketChatAlert() {
t.Log("Can't send rocketchat alert! Error: " + err.Error())
} else if resp.StatusCode != 200 {
t.Log("Can't send rocketchat alert! Response code: " + strconv.Itoa(resp.StatusCode))
} else {
t.Log("Sent successfully rocketchat alert")
}
if resp != nil {
defer resp.Body.Close() //nolint:errcheck
}

t.Log("Sent successfully rocketchat alert")
}

func (t *TaskRunner) sendMicrosoftTeamsAlert() {
Expand All @@ -317,7 +326,7 @@ func (t *TaskRunner) sendMicrosoftTeamsAlert() {
alert := Alert{
Name: t.Template.Name,
Author: author,
Color: t.alertColor("micorsoft-teams"),
Color: t.alertColor("microsoft-teams"),
Task: alertTask{
ID: strconv.Itoa(t.Task.ID),
URL: t.taskLink(),
Expand Down Expand Up @@ -356,9 +365,12 @@ func (t *TaskRunner) sendMicrosoftTeamsAlert() {
t.Log("Can't send microsoft teams alert! Error: " + err.Error())
} else if resp.StatusCode != 200 && resp.StatusCode != 202 {
t.Log("Can't send microsoft teams alert! Response code: " + strconv.Itoa(resp.StatusCode))
} else {
t.Log("Sent successfully microsoft teams alert")
}
if resp != nil {
defer resp.Body.Close() //nolint:errcheck
}

t.Log("Sent successfully microsoft teams alert")
}

func (t *TaskRunner) sendDingTalkAlert() {
Expand Down Expand Up @@ -418,6 +430,9 @@ func (t *TaskRunner) sendDingTalkAlert() {
} else {
t.Log("Sent successfully dingtalk alert")
}
if resp != nil {
defer resp.Body.Close() //nolint:errcheck
}
}

func (t *TaskRunner) sendGotifyAlert() {
Expand Down Expand Up @@ -480,6 +495,9 @@ func (t *TaskRunner) sendGotifyAlert() {
} else {
t.Log("Sent successfully gotify alert")
}
if resp != nil {
defer resp.Body.Close() //nolint:errcheck
}
}

func (t *TaskRunner) alertInfos() (string, string) {
Expand Down
Loading