Replace remote-query id with original query id on dowloaded SARIFs

This commit is contained in:
Alvaro Muñoz
2023-09-13 12:16:29 +02:00
parent 21bd3a405b
commit 4aa9205a6f
3 changed files with 30 additions and 27 deletions

View File

@@ -103,6 +103,7 @@ func downloadArtifacts() {
if errors.Is(bqrsErr, os.ErrNotExist) && errors.Is(sarifErr, os.ErrNotExist) { if errors.Is(bqrsErr, os.ErrNotExist) && errors.Is(sarifErr, os.ErrNotExist) {
downloadTasks = append(downloadTasks, models.DownloadTask{ downloadTasks = append(downloadTasks, models.DownloadTask{
RunId: run.Id, RunId: run.Id,
QueryId: run.QueryId,
Nwo: nwo, Nwo: nwo,
Controller: controller, Controller: controller,
Artifact: "artifact", Artifact: "artifact",
@@ -111,12 +112,15 @@ func downloadArtifacts() {
OutputFilename: outputFilename, OutputFilename: outputFilename,
}) })
} }
// download database if requested
dbPath := filepath.Join(outputDirFlag, fmt.Sprintf("%s_%s_db.zip", outputFilename, language)) dbPath := filepath.Join(outputDirFlag, fmt.Sprintf("%s_%s_db.zip", outputFilename, language))
if downloadDBsFlag { if downloadDBsFlag {
// check if the database already exists // check if the database already exists
if _, err := os.Stat(dbPath); errors.Is(err, os.ErrNotExist) { if _, err := os.Stat(dbPath); errors.Is(err, os.ErrNotExist) {
downloadTasks = append(downloadTasks, models.DownloadTask{ downloadTasks = append(downloadTasks, models.DownloadTask{
RunId: run.Id, RunId: run.Id,
QueryId: run.QueryId,
Nwo: nwo, Nwo: nwo,
Controller: controller, Controller: controller,
Artifact: "database", Artifact: "database",

View File

@@ -29,6 +29,7 @@ type Config struct {
type DownloadTask struct { type DownloadTask struct {
RunId int RunId int
QueryId string
Nwo string Nwo string
Controller string Controller string
Artifact string Artifact string

View File

@@ -2,7 +2,6 @@ package utils
import ( import (
"archive/zip" "archive/zip"
"bufio"
"bytes" "bytes"
"encoding/base64" "encoding/base64"
"encoding/json" "encoding/json"
@@ -277,7 +276,7 @@ func ResolveQueries(codeqlPath string, querySuite string) []string {
} }
func RunCodeQLCommand(codeqlPath string, combined bool, args ...string) ([]byte, error) { func RunCodeQLCommand(codeqlPath string, combined bool, args ...string) ([]byte, error) {
if !strings.Contains(strings.Join(args, " "), "packlist") { if codeqlPath != "" && !strings.Contains(strings.Join(args, " "), "packlist") {
args = append(args, fmt.Sprintf("--additional-packs=%s", codeqlPath)) args = append(args, fmt.Sprintf("--additional-packs=%s", codeqlPath))
} }
cmd := exec.Command("codeql", args...) cmd := exec.Command("codeql", args...)
@@ -521,17 +520,17 @@ func DownloadWorker(wg *sync.WaitGroup, taskChannel <-chan models.DownloadTask,
defer wg.Done() defer wg.Done()
for task := range taskChannel { for task := range taskChannel {
if task.Artifact == "artifact" { if task.Artifact == "artifact" {
DownloadResults(task.Controller, task.RunId, task.Nwo, task.OutputDir, task.OutputFilename) DownloadResults(task)
resultChannel <- task resultChannel <- task
} else if task.Artifact == "database" { } else if task.Artifact == "database" {
fmt.Println("Downloading database", task.Nwo, task.Language, task.OutputDir, task.OutputFilename) fmt.Println("Downloading database", task.Nwo, task.Language, task.OutputDir, task.OutputFilename)
DownloadDatabase(task.Nwo, task.Language, task.OutputDir, task.OutputFilename) DownloadDatabase(task)
resultChannel <- task resultChannel <- task
} }
} }
} }
func downloadArtifact(url string, outputDir string, nwo string, outputFilename string) error { func downloadArtifact(url string, task models.DownloadTask) error {
client, err := gh.HTTPClient(nil) client, err := gh.HTTPClient(nil)
if err != nil { if err != nil {
return err return err
@@ -561,21 +560,24 @@ func downloadArtifact(url string, outputDir string, nwo string, outputFilename s
log.Fatal(err) log.Fatal(err)
} }
defer f.Close() defer f.Close()
bytes, err := io.ReadAll(f) content, err := io.ReadAll(f)
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }
if outputFilename == "" {
extension := "" outputDir := task.OutputDir
outputFilename := task.OutputFilename
if zf.Name == "results.bqrs" { if zf.Name == "results.bqrs" {
extension = "bqrs" outputFilename = outputFilename + ".bqrs"
} else if zf.Name == "results.sarif" { } else if zf.Name == "results.sarif" {
extension = "sarif" outputFilename = outputFilename + ".sarif"
}
outputFilename = fmt.Sprintf("%s.%s", strings.Replace(nwo, "/", "_", -1), extension)
} }
// replace remote-query with real query id
content = bytes.Replace(content, []byte("remote-query"), []byte(task.QueryId), -1)
resultPath := filepath.Join(outputDir, outputFilename) resultPath := filepath.Join(outputDir, outputFilename)
err = os.WriteFile(resultPath, bytes, os.ModePerm) err = os.WriteFile(resultPath, content, os.ModePerm)
if err != nil { if err != nil {
return err return err
} }
@@ -584,26 +586,22 @@ func downloadArtifact(url string, outputDir string, nwo string, outputFilename s
return errors.New("No results.sarif file found in artifact") return errors.New("No results.sarif file found in artifact")
} }
func DownloadResults(controller string, runId int, nwo string, outputDir string, outputFilename string) error { func DownloadResults(task models.DownloadTask) error {
// download artifact (BQRS or SARIF) // download artifact (BQRS or SARIF)
runRepositoryDetails, err := GetRunRepositoryDetails(controller, runId, nwo) runRepositoryDetails, err := GetRunRepositoryDetails(task.Controller, task.RunId, task.Nwo)
if err != nil { if err != nil {
return errors.New("Failed to get run repository details") return errors.New("Failed to get run repository details")
} }
// download the results // download the results
err = downloadArtifact(runRepositoryDetails["artifact_url"].(string), outputDir, nwo, outputFilename) err = downloadArtifact(runRepositoryDetails["artifact_url"].(string), task)
if err != nil { if err != nil {
return errors.New("Failed to download artifact") return errors.New("Failed to download artifact")
} }
return nil return nil
} }
func DownloadDatabase(nwo string, language string, outputDir string, outputFilename string) error { func DownloadDatabase(task models.DownloadTask) error {
dnwo := strings.Replace(nwo, "/", "_", -1) targetPath := filepath.Join(task.OutputDir, fmt.Sprintf("%s_db.zip", task.OutputFilename))
if outputFilename == "" {
outputFilename = fmt.Sprintf("%s_%s_db.zip", dnwo, language)
}
targetPath := filepath.Join(outputDir, outputFilename)
opts := api.ClientOptions{ opts := api.ClientOptions{
Headers: map[string]string{"Accept": "application/zip"}, Headers: map[string]string{"Accept": "application/zip"},
} }
@@ -611,16 +609,16 @@ func DownloadDatabase(nwo string, language string, outputDir string, outputFilen
if err != nil { if err != nil {
return err return err
} }
resp, err := client.Get(fmt.Sprintf("https://api.github.com/repos/%s/code-scanning/codeql/databases/%s", nwo, language)) resp, err := client.Get(fmt.Sprintf("https://api.github.com/repos/%s/code-scanning/codeql/databases/%s", task.Nwo, task.Language))
if err != nil { if err != nil {
return err return err
} }
defer resp.Body.Close() defer resp.Body.Close()
bytes, err := io.ReadAll(resp.Body) content, err := io.ReadAll(resp.Body)
if err != nil { if err != nil {
return err return err
} }
err = os.WriteFile(targetPath, bytes, os.ModePerm) err = os.WriteFile(targetPath, content, os.ModePerm)
return nil return nil
} }