Skip to content

Commit

Permalink
v1-prerelease
Browse files Browse the repository at this point in the history
  • Loading branch information
xfhg committed Sep 12, 2024
1 parent 515c8e5 commit e95c0ed
Show file tree
Hide file tree
Showing 5 changed files with 152 additions and 17 deletions.
23 changes: 23 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Changelog

All notable changes to this project will be documented in this file.


## [[Unreleased]] - feature/loadremote
Commit: [55e24a0](https://github.com/xfhg/intercept/commit/55e24a0)

Summary: Capability to load the main policy file from remote endpoint (and check their SHA256)

### Added
- Added this CHANGELOG
- Added shorthand for policy (-p)
- Added shorthand for tag filtering "tags_any" (-f)
- Added sha256 checksum on command line for policy (--checksum)
- INTERCEPT can now load a remote policy (ex: https://raw.githubusercontent.com/xfhg/intercept/master/playground/policies/test_scan.yaml)
- INTERCEPT can verify the checksum of remote policies

### Changed
- Modified go build version to 1.23

### Removed

47 changes: 32 additions & 15 deletions cmd/audit.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,18 @@ type Performance struct {
}

var (
targetDir string
tagsAny string
tagsAll string
environment string
envDetection bool
debugOutput bool
rgPath string
gossPath string
policyFile string
outputType string
policyData *PolicyFile
targetDir string
tagsAny string
tagsAll string
environment string
envDetection bool
debugOutput bool
rgPath string
gossPath string
policyFile string
policyFileSHA256 string
outputType string
policyData *PolicyFile
)

var runAuditPerfCmd = &cobra.Command{
Expand All @@ -41,12 +42,13 @@ var runAuditPerfCmd = &cobra.Command{
func init() {
rootCmd.AddCommand(runAuditPerfCmd)
runAuditPerfCmd.Flags().StringVarP(&targetDir, "target", "t", "", "Target directory to audit")
runAuditPerfCmd.Flags().StringVar(&tagsAny, "tags_any", "", "Filter policies that match any of the provided tags (comma-separated)")
runAuditPerfCmd.Flags().StringVarP(&tagsAny, "tags_any", "f", "", "Filter policies that match any of the provided tags (comma-separated)")
runAuditPerfCmd.Flags().StringVar(&tagsAll, "tags_all", "", "Filter policies that match all of the provided tags (comma-separated)")
runAuditPerfCmd.Flags().StringVar(&environment, "environment", "", "Filter policies that match the specified environment")
runAuditPerfCmd.Flags().StringVarP(&environment, "environment", "e", "", "Filter policies that match the specified environment")
runAuditPerfCmd.Flags().BoolVar(&envDetection, "env-detection", false, "Enable environment detection if no environment is specified")
runAuditPerfCmd.Flags().BoolVar(&debugOutput, "debug", false, "Enable debug verbose output")
runAuditPerfCmd.Flags().StringVar(&policyFile, "policy", "", "policy file")
runAuditPerfCmd.Flags().StringVarP(&policyFile, "policy", "p", "", "policy FILE or URL")
runAuditPerfCmd.Flags().StringVar(&policyFileSHA256, "checksum", "", "policy file SHA256 checksum")
runAuditPerfCmd.Flags().StringVar(&outputType, "output", "sarif", "output type")
}

Expand All @@ -56,7 +58,22 @@ func runAuditPerf(cmd *cobra.Command, args []string) {

perf := Performance{StartTime: time.Now()}

policyData, err = LoadPolicyFile(policyFile)
sourceType, processedInput, err := DeterminePolicySource(policyFile)
if err != nil {
log.Fatal().Err(err)
}

switch sourceType {
case LocalFile:
policyData, err = LoadPolicyFile(processedInput)
case RemoteURL:
policyData, err = LoadRemotePolicy(processedInput, policyFileSHA256)
default:
log.Fatal().Msg("unknown policy source type")
}

//policyData, err = LoadPolicyFile(policyFile)

if err != nil {
log.Fatal().Err(err).Str("file", policyFile).Msg("Error loading policy file")
}
Expand Down
11 changes: 11 additions & 0 deletions cmd/aux.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"encoding/json"
"fmt"
"io"
"net/url"
"os"
"path/filepath"
"strconv"
Expand Down Expand Up @@ -411,3 +412,13 @@ func PathInfo(path string) (exists bool, isDir bool, err error) {
func GetDirectory(path string) string {
return filepath.Dir(path) + "/"
}

// isURL checks if the input string is a valid URL
func isURL(input string) bool {
// Check for common URL schemes
if strings.HasPrefix(input, "http://") || strings.HasPrefix(input, "https://") {
_, err := url.ParseRequestURI(input)
return err == nil
}
return false
}
84 changes: 84 additions & 0 deletions cmd/policy.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
package cmd

import (
"fmt"
"net/http"
"os"
"path/filepath"
"sync"

"github.com/go-resty/resty/v2"
"gopkg.in/yaml.v3"
)

Expand Down Expand Up @@ -108,6 +112,13 @@ type PolicyFile struct {
Policies []Policy `yaml:"Policies"`
}

type PolicySourceType int

const (
LocalFile PolicySourceType = iota
RemoteURL
)

func LoadPolicyFile(filename string) (*PolicyFile, error) {
data, err := os.ReadFile(filename)
if err != nil {
Expand All @@ -130,6 +141,79 @@ func LoadPolicyFile(filename string) (*PolicyFile, error) {
return &policyFile, nil
}

// Load Remote

// LoadRemotePolicy loads a policy file from a remote HTTPS endpoint
func LoadRemotePolicy(url string, expectedChecksum string) (*PolicyFile, error) {
// Create a temporary directory to store the downloaded file
tempDir, err := os.MkdirTemp(outputDir, "_remote")
if err != nil {
return nil, fmt.Errorf("failed to create temporary directory: %w", err)
}
defer os.RemoveAll(tempDir) // Clean up the temporary directory when done

// Generate a temporary file name
tempFile := filepath.Join(tempDir, "remote_policy.yaml")

// Create a resty client
client := resty.New()

// Download the file
resp, err := client.R().SetOutput(tempFile).Get(url)
if err != nil {
return nil, fmt.Errorf("failed to download policy file: %w", err)
}

if resp.StatusCode() != http.StatusOK {
return nil, fmt.Errorf("failed to download policy file: HTTP status %d", resp.StatusCode())
}

// If a checksum is provided, validate it
if expectedChecksum != "" {
actualChecksum, err := calculateSHA256(tempFile)
if err != nil {
log.Fatal().Err(err).Msg("failed to calculate policy checksum")
}

if actualChecksum != expectedChecksum {
log.Fatal().Msgf("Policy checksum mismatch: expected %s, got %s", expectedChecksum, actualChecksum)

}
}

// Load the policy file
policyFile, err := LoadPolicyFile(tempFile)
if err != nil {
log.Fatal().Err(err).Msg("failed to load policy file")
}

return policyFile, nil
}

func DeterminePolicySource(input string) (PolicySourceType, string, error) {
// First, check if it's a valid URL
if isURL(input) {
return RemoteURL, input, nil
}

// If not a URL, treat it as a file path
absPath, err := filepath.Abs(input)
if err != nil {
return LocalFile, "", err
}

// Check if the file exists
_, err = os.Stat(absPath)
if err != nil {
if os.IsNotExist(err) {
return LocalFile, "", fmt.Errorf("file does not exist: %s", absPath)
}
return LocalFile, "", err
}

return LocalFile, absPath, nil
}

// Policy store

var (
Expand Down
4 changes: 2 additions & 2 deletions cmd/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ var versionCmd = &cobra.Command{
Short: "Print the build info of intercept",
Long: `Print the build version number of intercept along with its signature`,
Run: func(cmd *cobra.Command, args []string) {
log.Info().Msgf("Intercept build version %s", buildVersion)
log.Info().Msgf("Intercept signature [%s]", buildSignature)
log.Log().Msgf("Intercept build version %s", buildVersion)
log.Log().Msgf("Intercept signature [%s]", buildSignature)
},
}

Expand Down

0 comments on commit e95c0ed

Please sign in to comment.