Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(plugins): add WRAP_RESPONSE_ERROR in config to avoid SSRF when testing connections #7080

Merged
merged 3 commits into from
Mar 1, 2024
Merged
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
15 changes: 15 additions & 0 deletions backend/core/plugin/plugin_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ limitations under the License.
package plugin

import (
"github.com/apache/incubator-devlake/core/context"
"github.com/apache/incubator-devlake/core/errors"
"github.com/apache/incubator-devlake/core/models/common"
"net/http"
Expand Down Expand Up @@ -71,3 +72,17 @@ type ApiResourceHandler func(input *ApiResourceInput) (*ApiResourceOutput, error
type PluginApi interface {
ApiResources() map[string]map[string]ApiResourceHandler
}

const wrapResponseError = "WRAP_RESPONSE_ERROR"

func WrapTestConnectionErrResp(basicRes context.BasicRes, err errors.Error) errors.Error {
if err == nil {
return err
}
if !basicRes.GetConfigReader().GetBool(wrapResponseError) {
return err
}
statusCode := err.GetType().GetHttpCode()
message := "Something went wrong when testing your connection, please check your connection details."
return errors.HttpStatus(statusCode).New(message)
}
12 changes: 10 additions & 2 deletions backend/plugins/ae/api/connection.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,11 @@ func TestConnection(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutput,
if err = api.Decode(input.Body, &connection, vld); err != nil {
return nil, errors.BadInput.Wrap(err, "could not decode request parameters")
}
return testConnection(context.TODO(), connection)
result, err := testConnection(context.TODO(), connection)
if err != nil {
return nil, plugin.WrapTestConnectionErrResp(basicRes, err)
}
return &plugin.ApiResourceOutput{Body: result, Status: http.StatusOK}, nil
}

// TestExistingConnection test ae connection
Expand All @@ -94,7 +98,11 @@ func TestExistingConnection(input *plugin.ApiResourceInput) (*plugin.ApiResource
if err := api.DecodeMapStruct(input.Body, connection, false); err != nil {
return nil, err
}
return testConnection(context.TODO(), connection.AeConn)
result, err := testConnection(context.TODO(), connection.AeConn)
if err != nil {
return nil, plugin.WrapTestConnectionErrResp(basicRes, err)
}
return &plugin.ApiResourceOutput{Body: result, Status: http.StatusOK}, nil
}

// @Summary create ae connection
Expand Down
4 changes: 2 additions & 2 deletions backend/plugins/bamboo/api/connection_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ func TestConnection(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutput,
// test connection
result, err := testConnection(context.TODO(), connection)
if err != nil {
return nil, err
return nil, plugin.WrapTestConnectionErrResp(basicRes, err)
}
return &plugin.ApiResourceOutput{Body: result, Status: http.StatusOK}, nil
}
Expand All @@ -96,7 +96,7 @@ func TestExistingConnection(input *plugin.ApiResourceInput) (*plugin.ApiResource
// test connection
result, err := testConnection(context.TODO(), connection.BambooConn)
if err != nil {
return nil, err
return nil, plugin.WrapTestConnectionErrResp(basicRes, err)
}
return &plugin.ApiResourceOutput{Body: result, Status: http.StatusOK}, nil
}
Expand Down
4 changes: 2 additions & 2 deletions backend/plugins/bitbucket/api/connection_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ func TestConnection(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutput,
// test connection
result, err := testConnection(context.TODO(), connection)
if err != nil {
return nil, err
return nil, plugin.WrapTestConnectionErrResp(basicRes, err)
}
return &plugin.ApiResourceOutput{Body: result, Status: http.StatusOK}, nil
}
Expand All @@ -110,7 +110,7 @@ func TestExistingConnection(input *plugin.ApiResourceInput) (*plugin.ApiResource
// test connection
result, err := testConnection(context.TODO(), connection.BitbucketConn)
if err != nil {
return nil, err
return nil, plugin.WrapTestConnectionErrResp(basicRes, err)
}
return &plugin.ApiResourceOutput{Body: result, Status: http.StatusOK}, nil
}
Expand Down
4 changes: 2 additions & 2 deletions backend/plugins/circleci/api/connection.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ func TestConnection(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutput,
// test connection
result, err := testConnection(context.TODO(), connection)
if err != nil {
return nil, err
return nil, plugin.WrapTestConnectionErrResp(basicRes, err)
}
return &plugin.ApiResourceOutput{Body: result, Status: http.StatusOK}, nil
}
Expand All @@ -106,7 +106,7 @@ func TestExistingConnection(input *plugin.ApiResourceInput) (*plugin.ApiResource
// test connection
result, err := testConnection(context.TODO(), connection.CircleciConn)
if err != nil {
return nil, err
return nil, plugin.WrapTestConnectionErrResp(basicRes, err)
}
return &plugin.ApiResourceOutput{Body: result, Status: http.StatusOK}, nil
}
Expand Down
4 changes: 2 additions & 2 deletions backend/plugins/feishu/api/connection.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ func TestConnection(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutput,
// test connection
result, err := testConnection(context.TODO(), connection)
if err != nil {
return nil, err
return nil, plugin.WrapTestConnectionErrResp(basicRes, err)
}
return &plugin.ApiResourceOutput{Body: result, Status: http.StatusOK}, nil
}
Expand All @@ -97,7 +97,7 @@ func TestExistingConnection(input *plugin.ApiResourceInput) (*plugin.ApiResource
// test connection
result, err := testConnection(context.TODO(), connection.FeishuConn)
if err != nil {
return nil, err
return nil, plugin.WrapTestConnectionErrResp(basicRes, err)
}
return &plugin.ApiResourceOutput{Body: result, Status: http.StatusOK}, nil
}
Expand Down
4 changes: 2 additions & 2 deletions backend/plugins/gitee/api/connection.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ func TestConnection(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutput,
// test connection
result, err := testConnection(context.TODO(), connection)
if err != nil {
return nil, err
return nil, plugin.WrapTestConnectionErrResp(basicRes, err)
}
return &plugin.ApiResourceOutput{Body: result, Status: http.StatusOK}, nil
}
Expand All @@ -114,7 +114,7 @@ func TestExistingConnection(input *plugin.ApiResourceInput) (*plugin.ApiResource
// test connection
result, err := testConnection(context.TODO(), connection.GiteeConn)
if err != nil {
return nil, err
return nil, plugin.WrapTestConnectionErrResp(basicRes, err)
}
return &plugin.ApiResourceOutput{Body: result, Status: http.StatusOK}, nil
}
Expand Down
4 changes: 2 additions & 2 deletions backend/plugins/github/api/connection_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ func TestConnection(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutput,
}
testConnectionResult, err := testConnection(context.TODO(), conn)
if err != nil {
return nil, errors.Convert(err)
return nil, plugin.WrapTestConnectionErrResp(basicRes, err)
}
return &plugin.ApiResourceOutput{Body: testConnectionResult, Status: http.StatusOK}, nil
}
Expand Down Expand Up @@ -394,7 +394,7 @@ func TestExistingConnection(input *plugin.ApiResourceInput) (*plugin.ApiResource
}
testConnectionResult, testConnectionErr := testExistingConnection(context.TODO(), connection.GithubConn)
if testConnectionErr != nil {
return nil, testConnectionErr
return nil, plugin.WrapTestConnectionErrResp(basicRes, testConnectionErr)
}
return &plugin.ApiResourceOutput{Body: testConnectionResult, Status: http.StatusOK}, nil
}
4 changes: 2 additions & 2 deletions backend/plugins/gitlab/api/connection_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ func TestConnection(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutput,
}
result, err := testConnection(context.TODO(), connection)
if err != nil {
return nil, err
return nil, plugin.WrapTestConnectionErrResp(basicRes, err)
}
return &plugin.ApiResourceOutput{Body: result, Status: http.StatusOK}, nil
}
Expand All @@ -110,7 +110,7 @@ func TestExistingConnection(input *plugin.ApiResourceInput) (*plugin.ApiResource
return nil, errors.Convert(err)
}
if result, err := testConnection(context.TODO(), connection.GitlabConn); err != nil {
return nil, err
return nil, plugin.WrapTestConnectionErrResp(basicRes, err)
} else {
return &plugin.ApiResourceOutput{Body: result, Status: http.StatusOK}, nil
}
Expand Down
4 changes: 2 additions & 2 deletions backend/plugins/jenkins/api/connection_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ func TestConnection(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutput,
// test connection
result, err := testConnection(context.TODO(), connection)
if err != nil {
return nil, err
return nil, plugin.WrapTestConnectionErrResp(basicRes, err)
}
return &plugin.ApiResourceOutput{Body: result, Status: http.StatusOK}, nil
}
Expand All @@ -112,7 +112,7 @@ func TestExistingConnection(input *plugin.ApiResourceInput) (*plugin.ApiResource
}
// test connection
if result, err := testConnection(context.TODO(), connection.JenkinsConn); err != nil {
return nil, err
return nil, plugin.WrapTestConnectionErrResp(basicRes, err)
} else {
return &plugin.ApiResourceOutput{Body: result, Status: http.StatusOK}, nil
}
Expand Down
4 changes: 2 additions & 2 deletions backend/plugins/jira/api/connection_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ func TestConnection(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutput,
// test connection
result, err := testConnection(context.TODO(), connection)
if err != nil {
return nil, err
return nil, plugin.WrapTestConnectionErrResp(basicRes, err)
}
return &plugin.ApiResourceOutput{Body: result, Status: http.StatusOK}, nil
}
Expand All @@ -157,7 +157,7 @@ func TestExistingConnection(input *plugin.ApiResourceInput) (*plugin.ApiResource
}
// test connection
if result, err := testConnection(context.TODO(), connection.JiraConn); err != nil {
return nil, err
return nil, plugin.WrapTestConnectionErrResp(basicRes, err)
} else {
return &plugin.ApiResourceOutput{Body: result, Status: http.StatusOK}, nil
}
Expand Down
12 changes: 10 additions & 2 deletions backend/plugins/opsgenie/api/connection.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,11 @@ func TestExistingConnection(input *plugin.ApiResourceInput) (*plugin.ApiResource
if err := api.DecodeMapStruct(input.Body, connection, false); err != nil {
return nil, err
}
return testOpsgenieConn(context.Background(), connection.OpsgenieConn)
testConnectionResult, testConnectionErr := testOpsgenieConn(context.Background(), connection.OpsgenieConn)
if testConnectionErr != nil {
return nil, plugin.WrapTestConnectionErrResp(basicRes, testConnectionErr)
}
return &plugin.ApiResourceOutput{Body: testConnectionResult, Status: http.StatusOK}, nil
}

// TestConnection test opsgenie connection
Expand All @@ -93,7 +97,11 @@ func TestConnection(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutput,
if err != nil {
return nil, err
}
return testOpsgenieConn(context.Background(), connection)
testConnectionResult, testConnectionErr := testOpsgenieConn(context.TODO(), connection)
if testConnectionErr != nil {
return nil, plugin.WrapTestConnectionErrResp(basicRes, testConnectionErr)
}
return &plugin.ApiResourceOutput{Body: testConnectionResult, Status: http.StatusOK}, nil
}

// @Summary create opsgenie connection
Expand Down
12 changes: 10 additions & 2 deletions backend/plugins/pagerduty/api/connection.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,11 @@ func TestConnection(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutput,
if err != nil {
return nil, err
}
return testConnection(context.TODO(), connection)
testConnectionResult, testConnectionErr := testConnection(context.TODO(), connection)
if testConnectionErr != nil {
return nil, plugin.WrapTestConnectionErrResp(basicRes, testConnectionErr)
}
return &plugin.ApiResourceOutput{Body: testConnectionResult, Status: http.StatusOK}, nil
}

// TestExistingConnection test pagerduty connection
Expand All @@ -85,7 +89,11 @@ func TestExistingConnection(input *plugin.ApiResourceInput) (*plugin.ApiResource
if err := api.DecodeMapStruct(input.Body, connection, false); err != nil {
return nil, err
}
return testConnection(context.TODO(), connection.PagerDutyConn)
testConnectionResult, testConnectionErr := testConnection(context.TODO(), connection.PagerDutyConn)
if testConnectionErr != nil {
return nil, plugin.WrapTestConnectionErrResp(basicRes, testConnectionErr)
}
return &plugin.ApiResourceOutput{Body: testConnectionResult, Status: http.StatusOK}, nil
}

// @Summary create pagerduty connection
Expand Down
4 changes: 2 additions & 2 deletions backend/plugins/slack/api/connection.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ func TestConnection(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutput,
// test connection
result, err := testConnection(context.TODO(), connection)
if err != nil {
return nil, err
return nil, plugin.WrapTestConnectionErrResp(basicRes, err)
}
return &plugin.ApiResourceOutput{Body: result, Status: http.StatusOK}, nil
}
Expand All @@ -97,7 +97,7 @@ func TestExistingConnection(input *plugin.ApiResourceInput) (*plugin.ApiResource
// test connection
result, err := testConnection(context.TODO(), connection.SlackConn)
if err != nil {
return nil, err
return nil, plugin.WrapTestConnectionErrResp(basicRes, err)
}
return &plugin.ApiResourceOutput{Body: result, Status: http.StatusOK}, nil
}
Expand Down
12 changes: 10 additions & 2 deletions backend/plugins/sonarqube/api/connection_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,11 @@ func TestConnection(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutput,
if err = api.Decode(input.Body, &connection, vld); err != nil {
return nil, err
}
return testConnection(context.TODO(), connection)
testConnectionResult, testConnectionErr := testConnection(context.TODO(), connection)
if testConnectionErr != nil {
return nil, plugin.WrapTestConnectionErrResp(basicRes, testConnectionErr)
}
return &plugin.ApiResourceOutput{Body: testConnectionResult, Status: http.StatusOK}, nil
}

// TestExistingConnection test sonarqube connection options
Expand All @@ -108,7 +112,11 @@ func TestExistingConnection(input *plugin.ApiResourceInput) (*plugin.ApiResource
return nil, errors.Convert(err)
}
// test connection
return testConnection(context.TODO(), connection.SonarqubeConn)
testConnectionResult, testConnectionErr := testConnection(context.TODO(), connection.SonarqubeConn)
if testConnectionErr != nil {
return nil, plugin.WrapTestConnectionErrResp(basicRes, testConnectionErr)
}
return &plugin.ApiResourceOutput{Body: testConnectionResult, Status: http.StatusOK}, nil
}

// PostConnections create sonarqube connection
Expand Down
4 changes: 2 additions & 2 deletions backend/plugins/tapd/api/connection.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ func TestConnection(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutput,
// test connection
result, err := testConnection(context.TODO(), connection)
if err != nil {
return nil, err
return nil, plugin.WrapTestConnectionErrResp(basicRes, err)
}
return &plugin.ApiResourceOutput{Body: result, Status: http.StatusOK}, nil
}
Expand All @@ -110,7 +110,7 @@ func TestExistingConnection(input *plugin.ApiResourceInput) (*plugin.ApiResource
// test connection
result, err := testConnection(context.TODO(), connection.TapdConn)
if err != nil {
return nil, err
return nil, plugin.WrapTestConnectionErrResp(basicRes, err)
}
return &plugin.ApiResourceOutput{Body: result, Status: http.StatusOK}, nil
}
Expand Down
4 changes: 2 additions & 2 deletions backend/plugins/teambition/api/connection.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ func TestConnection(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutput,
// test connection
result, err := testConnection(context.TODO(), connection)
if err != nil {
return nil, err
return nil, plugin.WrapTestConnectionErrResp(basicRes, err)
}
return &plugin.ApiResourceOutput{Body: result, Status: http.StatusOK}, nil
}
Expand All @@ -123,7 +123,7 @@ func TestExistingConnection(input *plugin.ApiResourceInput) (*plugin.ApiResource
}
testConnectionResult, testConnectionErr := testConnection(context.TODO(), connection.TeambitionConn)
if testConnectionErr != nil {
return nil, testConnectionErr
return nil, plugin.WrapTestConnectionErrResp(basicRes, testConnectionErr)
}
return &plugin.ApiResourceOutput{Body: testConnectionResult, Status: http.StatusOK}, nil
}
Expand Down
4 changes: 2 additions & 2 deletions backend/plugins/trello/api/connection.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ func TestConnection(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutput,
// test connection
result, err := testConnection(context.TODO(), connection)
if err != nil {
return nil, err
return nil, plugin.WrapTestConnectionErrResp(basicRes, err)
}
return &plugin.ApiResourceOutput{Body: result, Status: http.StatusOK}, nil
}
Expand All @@ -109,7 +109,7 @@ func TestExistingConnection(input *plugin.ApiResourceInput) (*plugin.ApiResource
}
testConnectionResult, testConnectionErr := testConnection(context.TODO(), connection.TrelloConn)
if testConnectionErr != nil {
return nil, testConnectionErr
return nil, plugin.WrapTestConnectionErrResp(basicRes, testConnectionErr)
}
return &plugin.ApiResourceOutput{Body: testConnectionResult, Status: http.StatusOK}, nil
}
Expand Down
4 changes: 2 additions & 2 deletions backend/plugins/zentao/api/connection.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ func TestConnection(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutput,
// test connection
result, err := testConnection(context.TODO(), connection)
if err != nil {
return nil, err
return nil, plugin.WrapTestConnectionErrResp(basicRes, err)
}
return &plugin.ApiResourceOutput{Body: result, Status: http.StatusOK}, nil
}
Expand All @@ -116,7 +116,7 @@ func TestExistingConnection(input *plugin.ApiResourceInput) (*plugin.ApiResource
}
testConnectionResult, testConnectionErr := testConnection(context.TODO(), connection.ZentaoConn)
if testConnectionErr != nil {
return nil, testConnectionErr
return nil, plugin.WrapTestConnectionErrResp(basicRes, testConnectionErr)
}
return &plugin.ApiResourceOutput{Body: testConnectionResult, Status: http.StatusOK}, nil
}
Expand Down
5 changes: 5 additions & 0 deletions env.example
Original file line number Diff line number Diff line change
Expand Up @@ -62,3 +62,8 @@ ENCRYPTION_SECRET=
# Set if skip verify and connect with out trusted certificate when use https
##########################
IN_SECURE_SKIP_VERIFY=

##########################
# Set if response error when requesting /connections/{connection_id}/test should be wrapped or not
##########################
WRAP_RESPONSE_ERROR=
Loading