Skip to content

Commit

Permalink
Refactor search term parsing
Browse files Browse the repository at this point in the history
  • Loading branch information
harleyjwilson committed Oct 4, 2023
1 parent 94369a1 commit db57c3d
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 36 deletions.
7 changes: 4 additions & 3 deletions pkg/apiresponse/apiresponse.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,10 @@ type Tag struct {
}

type Sandbox struct {
ID int `json:"id"`
SandboxTags []SandboxTag `json:"tags"`
Language string `json:"language"`
ID int `json:"id"`
SandboxTags []SandboxTag `json:"tags"`
Language string `json:"language"`
Technologies []string `json:"technologies"`
}

type SandboxTag struct {
Expand Down
20 changes: 15 additions & 5 deletions pkg/message/message.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,35 @@ package message

import (
"fmt"
"sandbox/pkg/globals"
"sandbox/pkg/sarif"
"sandbox/pkg/search"
"strings"
)

func generateHelpTextMessage(result search.SearchResult) string {
var builder strings.Builder
builder.WriteString("Explore and debug this vulnerability in [SecDim Sandbox](https://play.secdim.com/sandbox/")
builder.WriteString("Explore and debug the " + result.Title + " vulnerability on [SecDim Sandbox](" + globals.SANDBOX_URL)
urlSlug := ""

if len(result.ResultJson) == 1 {
for i := 0; i < len(result.ResultJson[0].Sandboxes); i++ {
if strings.Contains(strings.ToLower(result.RuleID), strings.ToLower(result.ResultJson[0].Sandboxes[i].Language)) {
lowerRuleID := strings.ToLower(result.RuleID)
lowerLanguage := strings.ToLower(result.ResultJson[0].Sandboxes[i].Language)

if strings.Contains(lowerRuleID, lowerLanguage) {
urlSlug = result.ResultJson[0].Slug + "/id/" + fmt.Sprintf("%d", result.ResultJson[0].Sandboxes[i].ID)
break
}

for _, tech := range result.ResultJson[0].Sandboxes[i].Technologies {
if strings.Contains(lowerRuleID, strings.ToLower(tech)) {
urlSlug = result.ResultJson[0].Slug + "/id/" + fmt.Sprintf("%d", result.ResultJson[0].Sandboxes[i].ID)
break
}
}
}
} else if len(result.ResultJson) > 1 {
} else if len(result.ResultJson) > 1 || urlSlug == "" {
urlSlug = "?search=" + strings.ReplaceAll(result.Title, " ", "%20")
}

Expand All @@ -29,7 +40,6 @@ func generateHelpTextMessage(result search.SearchResult) string {

func UpdateOutputSarifHelpMessage(outSarif sarif.Sarif, results []search.SearchResult) sarif.Sarif {
fmt.Printf("Updating output SARIF file with SecDim Sandbox information\n")
const HelpUri = "https://play.secdim.com/sandbox/"
for _, result := range results {
for _, run := range outSarif.Runs {
for i := 0; i < len(run.Tool.Driver.Rules); i++ {
Expand All @@ -39,7 +49,7 @@ func UpdateOutputSarifHelpMessage(outSarif sarif.Sarif, results []search.SearchR
} else if len(result.ResultJson) > 1 {
run.Tool.Driver.Rules[i].ShortDescription.Text = "SecDim Sandbox: " + result.Title
}
run.Tool.Driver.Rules[i].HelpUri = HelpUri
run.Tool.Driver.Rules[i].HelpUri = globals.SANDBOX_URL
run.Tool.Driver.Rules[i].Help.Text = generateHelpTextMessage(result) + run.Tool.Driver.Rules[i].Help.Text
run.Tool.Driver.Rules[i].Help.Markdown = generateHelpTextMessage(result) + run.Tool.Driver.Rules[i].Help.Markdown
}
Expand Down
8 changes: 4 additions & 4 deletions pkg/sarif/fileio.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@ func ReadSarifFile(file string) (Sarif, error) {
fmt.Printf("Reading SARIF file: %s\n", file)
data, err := os.ReadFile(file)
if err != nil {
fmt.Errorf("Error reading SARIF file: %v\n", err)
fmt.Printf("Error reading SARIF file: %v\n", err)
return Sarif{}, err
}
var sarifData Sarif
if err := json.Unmarshal(data, &sarifData); err != nil {
fmt.Errorf("Error unmarshaling file data: %v\n", err)
fmt.Printf("Error unmarshaling file data: %v\n", err)
return Sarif{}, err
}
fmt.Printf("Read SARIF file: %s\n", file)
Expand All @@ -26,12 +26,12 @@ func WriteSarifFile(file string, sarifData Sarif) error {
fmt.Printf("Writing SARIF file: %s\n", file)
jsonData, err := json.MarshalIndent(sarifData, "", " ")
if err != nil {
fmt.Errorf("Error marshaling file data: %v\n", err)
fmt.Printf("Error marshaling file data: %v\n", err)
return err
}
err = os.WriteFile(file, jsonData, 0644)
if err != nil {
fmt.Errorf("Error writing SARIF file: %v\n", err)
fmt.Printf("Error writing SARIF file: %v\n", err)
return err
}
fmt.Printf("Wrote SARIF file: %s\n", file)
Expand Down
58 changes: 34 additions & 24 deletions pkg/search/search.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,16 @@ import (
"io"
"net/http"
"sandbox/pkg/apiresponse"
"sandbox/pkg/globals"
"sandbox/pkg/sarif"
"strings"
)

type SearchTerm struct {
ID string
Description string
CWECode string
CWEDescription string
CWECode []string
CWEDescription []string
OWASPCode []string
OWASPDescription []string
}
Expand All @@ -39,17 +40,17 @@ func ParseSarifStruct(sarif sarif.Sarif) []SearchTerm {
for _, tag := range rule.Properties.Tags {
if strings.HasPrefix(tag, "CWE") {
substrings := strings.Split(tag, ":")
searchTerm.CWECode = substrings[0][4:]
searchTerm.CWECode = append(searchTerm.CWECode, substrings[0][4:])
if len(substrings) >= 2 {
searchTerm.CWEDescription = substrings[1][1:]
searchTerm.CWEDescription = append(searchTerm.CWEDescription, substrings[1][1:])
} else {
searchTerm.CWEDescription = ""
searchTerm.CWEDescription = append(searchTerm.CWEDescription, "")
}
} else if strings.HasPrefix(tag, "OWASP") {
substrings := strings.Split(tag, " ")
searchTerm.OWASPCode = append(searchTerm.OWASPCode, substrings[0][6:])
if len(substrings) >= 3 {
searchTerm.OWASPDescription = append(searchTerm.OWASPDescription, substrings[2])
searchTerm.OWASPDescription = append(searchTerm.OWASPDescription, strings.Join(substrings[2:], " "))
} else {
searchTerm.OWASPDescription = append(searchTerm.OWASPDescription, "")
}
Expand All @@ -64,18 +65,16 @@ func ParseSarifStruct(sarif sarif.Sarif) []SearchTerm {
}

func SearchAPI(searchTerm string) ([]byte, error) {
url := "https://play.secdim.com/api/v1/vuln/?search="

response, err := http.Get(url + searchTerm)
response, err := http.Get(globals.API_URL + searchTerm)
if err != nil {
fmt.Errorf("Error sending GET request: %v\n", err)
fmt.Printf("Error sending GET request: %v\n", err)
return nil, err
}
defer response.Body.Close()

body, err := io.ReadAll(response.Body)
if err != nil {
fmt.Errorf("Error reading response body: %v\n", err)
fmt.Printf("Error reading response body: %v\n", err)
return nil, err
}

Expand All @@ -86,39 +85,50 @@ func GetSearchResults(searchTerm SearchTerm) (SearchResult, error) {
fmt.Printf("Searching for SecDim Sandbox related to SARIF Rule ID: %s\n", searchTerm.ID)
var searchResult = SearchResult{
RuleID: searchTerm.ID,
Title: searchTerm.OWASPDescription[0],
Title: searchTerm.CWEDescription[0],
}

var jsonResponse []apiresponse.Vulnerability

// Initial API search, search CWE Description
response, err := SearchAPI(searchTerm.CWEDescription)
if err != nil {
fmt.Errorf("Error reading response body: %v\n", err)
return searchResult, err
}
for _, cweDescription := range searchTerm.CWEDescription {
response, err := SearchAPI(cweDescription)
if err != nil {
fmt.Printf("Error reading response body: %v\n", err)
return searchResult, err
}

var jsonResponse []apiresponse.Vulnerability
if err := json.Unmarshal(response, &jsonResponse); err != nil {
fmt.Errorf("Error unmarshaling SARIF: %v\n", err)
return searchResult, err
// var jsonResponse []apiresponse.Vulnerability
if err := json.Unmarshal(response, &jsonResponse); err != nil {
fmt.Printf("Error unmarshaling SARIF: %v\n", err)
return searchResult, err
}

// If API search isn't empty, return result
if len(jsonResponse) > 0 {
searchResult.ResultJson = jsonResponse
searchResult.Title = cweDescription
return searchResult, nil
}
}

// If initial API search is empty, search OWASP Description
if len(jsonResponse) == 0 {
for _, owaspDescription := range searchTerm.OWASPDescription {
response, err := SearchAPI(owaspDescription)
if err != nil {
fmt.Errorf("Error reading response body: %v\n", err)
fmt.Printf("Error reading response body: %v\n", err)
return searchResult, err
}

var jsonResponse []apiresponse.Vulnerability
if err := json.Unmarshal(response, &jsonResponse); err != nil {
fmt.Errorf("Error unmarshaling SARIF: %v\n", err)
fmt.Printf("Error unmarshaling SARIF: %v\n", err)
return searchResult, err
}
// If API search isn't empty, return result
if len(jsonResponse) > 0 {
searchResult.ResultJson = jsonResponse
searchResult.Title = owaspDescription
return searchResult, nil
}
}
Expand Down

0 comments on commit db57c3d

Please sign in to comment.