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

Feature 3390 enable project data in client #3409

Merged
merged 20 commits into from
Sep 6, 2024
Merged
Show file tree
Hide file tree
Changes from 12 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
214 changes: 161 additions & 53 deletions sechub-cli/src/mercedes-benz.com/sechub/cli/false-positives.go

Large diffs are not rendered by default.

235 changes: 223 additions & 12 deletions sechub-cli/src/mercedes-benz.com/sechub/cli/false-positives_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
package cli

import (
"encoding/json"
"fmt"
"os"
"path/filepath"
Expand Down Expand Up @@ -44,7 +45,7 @@ func TestFalsePositivesSaveWritesAFile(t *testing.T) {
sechubTestUtil.AssertFileExists(expected, t)
}

func Example_defineFalsePositives() {
func Example_defineFalsePositivesJobData() {
/* prepare */
definedFalsePositives := []FalsePositivesJobData{
{JobUUID: "11111111-1111-1111-1111-111111111111", FindingID: 1, Comment: "test1"},
Expand All @@ -68,11 +69,11 @@ func Example_defineFalsePositives() {
fmt.Printf("Remove: %+v\n", falsePositivesToRemove)

// Output:
// Add: {APIVersion:1.0 Type:falsePositiveJobDataList JobData:[{JobUUID:33333333-3333-3333-3333-333333333333 FindingID:3 Comment:test3} {JobUUID:55555555-5555-5555-5555-555555555555 FindingID:5 Comment:test5}]}
// Remove: {APIVersion:1.0 Type:falsePositiveJobDataList JobData:[{JobUUID:44444444-4444-4444-4444-444444444444 FindingID:4 Comment:}]}
// Add: {APIVersion:1.0 Type:falsePositiveJobDataList JobData:[{JobUUID:33333333-3333-3333-3333-333333333333 FindingID:3 Comment:test3} {JobUUID:55555555-5555-5555-5555-555555555555 FindingID:5 Comment:test5}] ProjectData:[]}
// Remove: {APIVersion:1.0 Type:falsePositiveJobDataList JobData:[{JobUUID:44444444-4444-4444-4444-444444444444 FindingID:4 Comment:}] ProjectData:[]}
}

func Example_defineFalsePositivesEmptyInputList() {
func Example_defineFalsePositivesJobDataEmptyInputList() {
// An empty input list will remove all defined false-positives

/* prepare */
Expand All @@ -92,11 +93,11 @@ func Example_defineFalsePositivesEmptyInputList() {
fmt.Printf("Remove: %+v\n", falsePositivesToRemove)

// Output:
// Add: {APIVersion:1.0 Type:falsePositiveJobDataList JobData:[]}
// Remove: {APIVersion:1.0 Type:falsePositiveJobDataList JobData:[{JobUUID:11111111-1111-1111-1111-111111111111 FindingID:1 Comment:} {JobUUID:22222222-2222-2222-2222-222222222222 FindingID:2 Comment:}]}
// Add: {APIVersion:1.0 Type:falsePositiveJobDataList JobData:[] ProjectData:[]}
// Remove: {APIVersion:1.0 Type:falsePositiveJobDataList JobData:[{JobUUID:11111111-1111-1111-1111-111111111111 FindingID:1 Comment:} {JobUUID:22222222-2222-2222-2222-222222222222 FindingID:2 Comment:}] ProjectData:[]}
}

func Example_defineFalsePositivesEmptyServerList() {
func Example_defineFalsePositivesJobDataEmptyServerList() {
// An empty server list will simply add all defined false-positives

/* prepare */
Expand All @@ -116,8 +117,122 @@ func Example_defineFalsePositivesEmptyServerList() {
fmt.Printf("Remove: %+v\n", falsePositivesToRemove)

// Output:
// Add: {APIVersion:1.0 Type:falsePositiveJobDataList JobData:[{JobUUID:11111111-1111-1111-1111-111111111111 FindingID:1 Comment:test1} {JobUUID:22222222-2222-2222-2222-222222222222 FindingID:2 Comment:test2}]}
// Remove: {APIVersion:1.0 Type:falsePositiveJobDataList JobData:[]}
// Add: {APIVersion:1.0 Type:falsePositiveJobDataList JobData:[{JobUUID:11111111-1111-1111-1111-111111111111 FindingID:1 Comment:test1} {JobUUID:22222222-2222-2222-2222-222222222222 FindingID:2 Comment:test2}] ProjectData:[]}
// Remove: {APIVersion:1.0 Type:falsePositiveJobDataList JobData:[] ProjectData:[]}
}

func Example_defineFalsePositivesProjectData() {
/* prepare */
definedFalsePositives := []FalsePositivesProjectData{
{ID: "test1", Comment: "test1", WebScan: FalsePositivesProjectDataForWebScan{CweID: 1, UrlPattern: "https://example1/*", Methods: []string{"GET", "PUT"}}},
{ID: "test2", Comment: "test2", WebScan: FalsePositivesProjectDataForWebScan{CweID: 2, UrlPattern: "https://example2/*"}},
{ID: "test3", Comment: "test3", WebScan: FalsePositivesProjectDataForWebScan{CweID: 3, UrlPattern: "https://example3/*"}},
{ID: "test5", Comment: "test5", WebScan: FalsePositivesProjectDataForWebScan{CweID: 5, UrlPattern: "https://example5/*"}},
}
falsePositivesDefinitionList := FalsePositivesConfig{APIVersion: CurrentAPIVersion, Type: falsePositivesListType, ProjectData: definedFalsePositives}

falsePositivesServerList := []FalsePositiveDefinition{
{ProjectData: FalsePositivesProjectData{ID: "test1", Comment: "test1", WebScan: FalsePositivesProjectDataForWebScan{CweID: 1, UrlPattern: "https://example1/*", Methods: []string{"GET", "POST"}}}},
{ProjectData: FalsePositivesProjectData{ID: "test2", Comment: "test2 old", WebScan: FalsePositivesProjectDataForWebScan{CweID: 2, UrlPattern: "https://example2/*"}}},
{ProjectData: FalsePositivesProjectData{ID: "test4", Comment: "test4", WebScan: FalsePositivesProjectDataForWebScan{CweID: 4, UrlPattern: "https://example4/*"}}},
}

/* execute */
falsePositivesToAdd, falsePositivesToRemove := defineFalsePositives(falsePositivesDefinitionList, falsePositivesServerList)

/* test */
fmt.Printf("Add: %+v\n", falsePositivesToAdd)
fmt.Printf("Remove: %+v\n", falsePositivesToRemove)

// Output:
// Add: {APIVersion:1.0 Type:falsePositiveJobDataList JobData:[] ProjectData:[{ID:test1 Comment:test1 WebScan:{CweID:1 UrlPattern:https://example1/* Methods:[GET PUT]}} {ID:test2 Comment:test2 WebScan:{CweID:2 UrlPattern:https://example2/* Methods:[]}} {ID:test3 Comment:test3 WebScan:{CweID:3 UrlPattern:https://example3/* Methods:[]}} {ID:test5 Comment:test5 WebScan:{CweID:5 UrlPattern:https://example5/* Methods:[]}}]}
// Remove: {APIVersion:1.0 Type:falsePositiveJobDataList JobData:[] ProjectData:[{ID:test4 Comment:test4 WebScan:{CweID:4 UrlPattern:https://example4/* Methods:[]}}]}
}

func Example_defineFalsePositivesProjectDataEmptyInputList() {
// An empty input list will remove all defined false-positives

/* prepare */
definedFalsePositives := []FalsePositivesProjectData{}
falsePositivesDefinitionList := FalsePositivesConfig{APIVersion: CurrentAPIVersion, Type: falsePositivesListType, ProjectData: definedFalsePositives}

falsePositivesServerList := []FalsePositiveDefinition{
{ProjectData: FalsePositivesProjectData{ID: "test1"}},
{ProjectData: FalsePositivesProjectData{ID: "test2"}},
}

/* execute */
falsePositivesToAdd, falsePositivesToRemove := defineFalsePositives(falsePositivesDefinitionList, falsePositivesServerList)

/* test */
fmt.Printf("Add: %+v\n", falsePositivesToAdd)
fmt.Printf("Remove: %+v\n", falsePositivesToRemove)

// Output:
// Add: {APIVersion:1.0 Type:falsePositiveJobDataList JobData:[] ProjectData:[]}
// Remove: {APIVersion:1.0 Type:falsePositiveJobDataList JobData:[] ProjectData:[{ID:test1 Comment: WebScan:{CweID:0 UrlPattern: Methods:[]}} {ID:test2 Comment: WebScan:{CweID:0 UrlPattern: Methods:[]}}]}
}

func Example_defineFalsePositivesProjectDataEmptyServerList() {
// An empty server list will simply add all defined false-positives

/* prepare */
definedFalsePositives := []FalsePositivesProjectData{
{ID: "test1", Comment: "test1", WebScan: FalsePositivesProjectDataForWebScan{CweID: 1, UrlPattern: "https://example1/*", Methods: []string{"GET", "PUT"}}},
{ID: "test2", Comment: "test2", WebScan: FalsePositivesProjectDataForWebScan{CweID: 2, UrlPattern: "https://example2/*"}},
}
falsePositivesDefinitionList := FalsePositivesConfig{APIVersion: CurrentAPIVersion, Type: falsePositivesListType, ProjectData: definedFalsePositives}

falsePositivesServerList := []FalsePositiveDefinition{}

/* execute */
falsePositivesToAdd, falsePositivesToRemove := defineFalsePositives(falsePositivesDefinitionList, falsePositivesServerList)

/* test */
fmt.Printf("Add: %+v\n", falsePositivesToAdd)
fmt.Printf("Remove: %+v\n", falsePositivesToRemove)

// Output:
// Add: {APIVersion:1.0 Type:falsePositiveJobDataList JobData:[] ProjectData:[{ID:test1 Comment:test1 WebScan:{CweID:1 UrlPattern:https://example1/* Methods:[GET PUT]}} {ID:test2 Comment:test2 WebScan:{CweID:2 UrlPattern:https://example2/* Methods:[]}}]}
// Remove: {APIVersion:1.0 Type:falsePositiveJobDataList JobData:[] ProjectData:[]}
}

func Example_defineFalsePositivesWhenIdenticalToServerList() {
// When both lists are identical then no changes shall be made

/* prepare */
definedFalsePositivesJobData := []FalsePositivesJobData{
{JobUUID: "11111111-1111-1111-1111-111111111111", FindingID: 1},
{JobUUID: "22222222-2222-2222-2222-222222222222", FindingID: 2},
}
definedFalsePositivesProjectData := []FalsePositivesProjectData{
{ID: "test1", Comment: "test1", WebScan: FalsePositivesProjectDataForWebScan{CweID: 1, UrlPattern: "https://example1/*", Methods: []string{"GET", "PUT"}}},
{ID: "test2", Comment: "test2", WebScan: FalsePositivesProjectDataForWebScan{CweID: 2, UrlPattern: "https://example2/*"}},
}
falsePositivesDefinitionList := FalsePositivesConfig{
APIVersion: CurrentAPIVersion,
Type: falsePositivesListType,
JobData: definedFalsePositivesJobData,
ProjectData: definedFalsePositivesProjectData,
}

falsePositivesServerList := []FalsePositiveDefinition{
{JobData: FalsePositivesJobData{JobUUID: "11111111-1111-1111-1111-111111111111", FindingID: 1}},
{JobData: FalsePositivesJobData{JobUUID: "22222222-2222-2222-2222-222222222222", FindingID: 2}},
{ProjectData: FalsePositivesProjectData{ID: "test1", Comment: "test1", WebScan: FalsePositivesProjectDataForWebScan{CweID: 1, UrlPattern: "https://example1/*", Methods: []string{"GET", "PUT"}}}},
{ProjectData: FalsePositivesProjectData{ID: "test2", Comment: "test2", WebScan: FalsePositivesProjectDataForWebScan{CweID: 2, UrlPattern: "https://example2/*"}}},
}

/* execute */
falsePositivesToAdd, falsePositivesToRemove := defineFalsePositives(falsePositivesDefinitionList, falsePositivesServerList)

/* test */
fmt.Printf("Add: %+v\n", falsePositivesToAdd)
fmt.Printf("Remove: %+v\n", falsePositivesToRemove)

// Output:
// Add: {APIVersion:1.0 Type:falsePositiveJobDataList JobData:[] ProjectData:[]}
// Remove: {APIVersion:1.0 Type:falsePositiveJobDataList JobData:[] ProjectData:[]}
}

func Example_getFalsePositivesUploadChunk1() {
Expand All @@ -141,7 +256,103 @@ func Example_getFalsePositivesUploadChunk1() {
/* test */

// Output:
// {APIVersion:1.0 Type:falsePositiveJobDataList JobData:[{JobUUID:11111111-1111-1111-1111-111111111111 FindingID:1 Comment:test1} {JobUUID:22222222-2222-2222-2222-222222222222 FindingID:2 Comment:test2}]}
// {APIVersion:1.0 Type:falsePositiveJobDataList JobData:[{JobUUID:33333333-3333-3333-3333-333333333333 FindingID:3 Comment:test3}]}
// {APIVersion:1.0 Type:falsePositiveJobDataList JobData:[]}
// {APIVersion:1.0 Type:falsePositiveJobDataList JobData:[{JobUUID:11111111-1111-1111-1111-111111111111 FindingID:1 Comment:test1} {JobUUID:22222222-2222-2222-2222-222222222222 FindingID:2 Comment:test2}] ProjectData:[]}
// {APIVersion:1.0 Type:falsePositiveJobDataList JobData:[{JobUUID:33333333-3333-3333-3333-333333333333 FindingID:3 Comment:test3}] ProjectData:[]}
// {APIVersion:1.0 Type:falsePositiveJobDataList JobData:[] ProjectData:[]}
}

func Example_newFalsePositivesListFromBytes_jobData() {
/* prepare */
fpJSON := `
{
"apiVersion": "1.0",
"type": "falsePositiveDataList",
"jobData": [
{
"jobUUID": "6cfa2ccf-da13-4dee-b529-0225ed9661bd",
"findingId": 1,
"comment": "Meaningful comment"
},
{
"jobUUID": "6cfa2ccf-da13-4dee-b529-0225ed9661bd",
"findingId": 2
}
]
}
`

inputfile := []byte(fpJSON)

/* execute */
fpList := newFalsePositivesListFromBytes(inputfile)

/* test */
jsonBlob, _ := json.Marshal(fpList)
fmt.Println(string(jsonBlob))

// Output:
// {"apiVersion":"1.0","type":"falsePositiveDataList","jobData":[{"jobUUID":"6cfa2ccf-da13-4dee-b529-0225ed9661bd","findingId":1,"comment":"Meaningful comment"},{"jobUUID":"6cfa2ccf-da13-4dee-b529-0225ed9661bd","findingId":2,"comment":""}],"projectData":null}
}

func Example_newFalsePositivesListFromBytes_projectData() {
/* prepare */
fpJSON := `
{
"apiVersion": "1.0",
"type": "falsePositiveDataList",
"projectData": [
{
"id": "my-id",
"comment": "text1",
"webScan": {
"cweId": 89,
"urlPattern": "https://myapp-*.example.com:80*/rest/*/search?*",
"methods": [ "GET", "DELETE" ]
}
}
]
}
`

inputfile := []byte(fpJSON)

/* execute */
fpList := newFalsePositivesListFromBytes(inputfile)

/* test */
jsonBlob, _ := json.Marshal(fpList)
fmt.Println(string(jsonBlob))

// Output:
// {"apiVersion":"1.0","type":"falsePositiveDataList","jobData":null,"projectData":[{"id":"my-id","comment":"text1","webScan":{"cweId":89,"urlPattern":"https://myapp-*.example.com:80*/rest/*/search?*","methods":["GET","DELETE"]}}]}
}

func Example_newFalsePositivesListFromBytes_projectDataWithoutCWE() {
/* prepare */
fpJSON := `
{
"apiVersion": "1.0",
"type": "falsePositiveDataList",
"projectData": [
{
"id": "my-id",
"webScan": {
"urlPattern": "https://myapp-*.example.com/rest/login?*"
}
}
]
}
`

inputfile := []byte(fpJSON)

/* execute */
fpList := newFalsePositivesListFromBytes(inputfile)

/* test */
jsonBlob, _ := json.Marshal(fpList)
fmt.Println(string(jsonBlob))

// Output:
// {"apiVersion":"1.0","type":"falsePositiveDataList","jobData":null,"projectData":[{"id":"my-id","comment":"","webScan":{"cweId":0,"urlPattern":"https://myapp-*.example.com/rest/login?*","methods":null}}]}
}
5 changes: 5 additions & 0 deletions sechub-cli/src/mercedes-benz.com/sechub/cli/urlbuilder.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,11 @@ func buildFalsePositiveAPICall(context *Context) string {
return buildAPIUrl(&context.config.server, &apiPart)
}

func buildFalsePositiveProjectDataAPICall(context *Context) string {
apiPart := fmt.Sprintf("project/%s/false-positive/project-data", context.config.projectID)
return buildAPIUrl(&context.config.server, &apiPart)
}

func buildAPIUrl(server *string, apiPart *string) string {
return fmt.Sprintf("%s/api/%s", *server, *apiPart)
}
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ See also <<section-client-interactiveMarkFalsePositives-mark,example for interac
Instead of creating a json file to unmark false positives, you can also do this interactively:
Go to the project directory containing `sechub.json` and run `sechub interactiveUnmarkFalsePositives`

{sechub} client will download the current false posisitves list and interactively ask each entry: `"Do you want to remove this false positive?"`
{sechub} client will download the current false posisitives list and interactively ask each entry: `"Do you want to remove this false positive?"`
Your choices are:

- `y` Yes - Unmark this false positive.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"comment": "It was verified that there is no SQL-injection vulnerability at this location",
"webScan": { //<9>
"cweId": 89, //<10>
"urlPattern": "https://*.example.com/rest/products/search*", //<11>
"urlPattern": "https://*.example.com/rest/products/search?*", //<11>
"methods": [ "GET", "DELETE" ] //<12>
}
}
Expand Down
Loading
Loading