diff --git a/pkg/datastore/mysql/target.go b/pkg/datastore/mysql/target.go index 256d59a..4a0a5a2 100644 --- a/pkg/datastore/mysql/target.go +++ b/pkg/datastore/mysql/target.go @@ -51,8 +51,8 @@ func (m *MySQL) GetTarget(ctx context.Context, id uuid.UUID) (*datastore.Target, // GetTargetByScope get a target from scope func (m *MySQL) GetTargetByScope(ctx context.Context, scope string) (*datastore.Target, error) { var t datastore.Target - query := fmt.Sprintf(`SELECT uuid, scope, github_token, token_expired_at, resource_type, provider_url, status, status_description, created_at, updated_at FROM targets WHERE scope = "%s"`, scope) - if err := m.Conn.GetContext(ctx, &t, query); err != nil { + query := `SELECT uuid, scope, github_token, token_expired_at, resource_type, provider_url, status, status_description, created_at, updated_at FROM targets WHERE scope = ?` + if err := m.Conn.GetContext(ctx, &t, query, scope); err != nil { if errors.Is(err, sql.ErrNoRows) { return nil, datastore.ErrNotFound } diff --git a/pkg/datastore/mysql/target_test.go b/pkg/datastore/mysql/target_test.go index 64a3da8..f6c2c3f 100644 --- a/pkg/datastore/mysql/target_test.go +++ b/pkg/datastore/mysql/target_test.go @@ -320,6 +320,25 @@ func TestMySQL_GetTargetByScope(t *testing.T) { }, err: false, }, + { + // scope contains SQL meta characters, must be treated as a literal value (not injected) + input: `owner/repo" OR "1"="1`, + want: nil, + prepare: func() error { + return testDatastore.CreateTarget(context.Background(), datastore.Target{ + UUID: testTargetID, + Scope: testScopeRepo, + GitHubToken: testGitHubToken, + TokenExpiredAt: testTime, + ResourceType: datastore.ResourceTypeNano, + ProviderURL: sql.NullString{ + String: testProviderURL, + Valid: true, + }, + }) + }, + err: true, + }, } for _, test := range tests { @@ -328,9 +347,12 @@ func TestMySQL_GetTargetByScope(t *testing.T) { } got, err := testDatastore.GetTargetByScope(context.Background(), test.input) - if err != nil { + if !test.err && err != nil { t.Fatalf("failed to get target: %+v", err) } + if test.err && !errors.Is(err, datastore.ErrNotFound) { + t.Fatalf("want datastore.ErrNotFound, but got: %+v", err) + } if got != nil { got.CreatedAt = time.Time{} got.UpdatedAt = time.Time{}