diff --git a/cmd/config/config.go b/cmd/config/config.go index 057f5aee..9e930a66 100644 --- a/cmd/config/config.go +++ b/cmd/config/config.go @@ -41,6 +41,7 @@ type OptionalConfig struct { ProgressBar bool `json:"progress"` TLSVerify bool `json:"tls"` Proxy string `json:"proxy"` + Dynamic bool `json:"dynamic"` } type RepoConfig struct { diff --git a/config.json b/config.json index f3ca44d7..3b3c760e 100644 --- a/config.json +++ b/config.json @@ -48,7 +48,11 @@ // 全局http代理 // global proxy for http requests, eg: http://127.0.0.1:7890 - "proxy": "" + "proxy": "", + + // 允许动态命令 + // allow dynamic command, eg: mvn + "dynamic": false }, diff --git a/go.mod b/go.mod index 8e54870b..c8eb42bd 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/xmirrorsecurity/opensca-cli/v3 -go 1.20 +go 1.25 require ( github.com/BurntSushi/toml v1.3.2 diff --git a/opensca/sca/golang/gomod.go b/opensca/sca/golang/gomod.go index 3fe5a277..eefa90de 100644 --- a/opensca/sca/golang/gomod.go +++ b/opensca/sca/golang/gomod.go @@ -9,6 +9,7 @@ import ( "sort" "strings" + "github.com/xmirrorsecurity/opensca-cli/v3/cmd/config" "github.com/xmirrorsecurity/opensca-cli/v3/opensca/model" ) @@ -131,6 +132,10 @@ func ParseGosum(file *model.File) *model.DepGraph { // GoModGraph 调用 go mod graph 解析依赖 func GoModGraph(ctx context.Context, modfile *model.File) *model.DepGraph { + if !config.Conf().Optional.Dynamic { + return nil + } + _, err := exec.LookPath("go") if err != nil { return nil diff --git a/opensca/sca/golang/sca.go b/opensca/sca/golang/sca.go index 7730d32d..30844951 100644 --- a/opensca/sca/golang/sca.go +++ b/opensca/sca/golang/sca.go @@ -4,6 +4,7 @@ import ( "context" "path/filepath" + "github.com/xmirrorsecurity/opensca-cli/v3/cmd/config" "github.com/xmirrorsecurity/opensca-cli/v3/opensca/model" "github.com/xmirrorsecurity/opensca-cli/v3/opensca/sca/filter" ) @@ -44,12 +45,14 @@ func (sca Sca) Sca(ctx context.Context, parent *model.File, files []*model.File, } // 尝试调用 go mod graph - for dir, f := range gomod { - graph := GoModGraph(ctx, f) - if graph != nil && len(graph.Children) > 0 { - call(f, graph) - delete(gomod, dir) - delete(gosum, dir) + if config.Conf().Optional.Dynamic { + for dir, f := range gomod { + graph := GoModGraph(ctx, f) + if graph != nil && len(graph.Children) > 0 { + call(f, graph) + delete(gomod, dir) + delete(gosum, dir) + } } } diff --git a/opensca/sca/groovy/gradle.go b/opensca/sca/groovy/gradle.go index 4eb8f958..15606cfe 100644 --- a/opensca/sca/groovy/gradle.go +++ b/opensca/sca/groovy/gradle.go @@ -11,6 +11,7 @@ import ( "regexp" "strings" + "github.com/xmirrorsecurity/opensca-cli/v3/cmd/config" "github.com/xmirrorsecurity/opensca-cli/v3/opensca/logs" "github.com/xmirrorsecurity/opensca-cli/v3/opensca/model" "github.com/xmirrorsecurity/opensca-cli/v3/opensca/sca/filter" @@ -115,6 +116,10 @@ type gradleDep struct { func GradleTree(ctx context.Context, dir *model.File) []*model.DepGraph { + if !config.Conf().Optional.Dynamic { + return nil + } + if dir == nil { return nil } diff --git a/opensca/sca/java/mvn.go b/opensca/sca/java/mvn.go index ce67072f..eb608480 100644 --- a/opensca/sca/java/mvn.go +++ b/opensca/sca/java/mvn.go @@ -13,6 +13,7 @@ import ( "strings" "sync" + "github.com/xmirrorsecurity/opensca-cli/v3/cmd/config" "github.com/xmirrorsecurity/opensca-cli/v3/opensca/common" "github.com/xmirrorsecurity/opensca-cli/v3/opensca/logs" "github.com/xmirrorsecurity/opensca-cli/v3/opensca/model" @@ -528,6 +529,10 @@ func DownloadPomFromRepo(dep PomDependency, do func(r io.Reader), repos ...commo // pom: pom文件信息 func MvnTree(ctx context.Context, pom *Pom) *model.DepGraph { + if !config.Conf().Optional.Dynamic { + return nil + } + if pom == nil { return nil } diff --git a/opensca/sca/java/xml/marshal.go b/opensca/sca/java/xml/marshal.go index 07b6042d..b2f4864d 100644 --- a/opensca/sca/java/xml/marshal.go +++ b/opensca/sca/java/xml/marshal.go @@ -415,9 +415,9 @@ func (p *printer) popPrefix() { } var ( - marshalerType = reflect.TypeOf((*Marshaler)(nil)).Elem() - marshalerAttrType = reflect.TypeOf((*MarshalerAttr)(nil)).Elem() - textMarshalerType = reflect.TypeOf((*encoding.TextMarshaler)(nil)).Elem() + marshalerType = reflect.TypeFor[Marshaler]() + marshalerAttrType = reflect.TypeFor[MarshalerAttr]() + textMarshalerType = reflect.TypeFor[encoding.TextMarshaler]() ) // marshalValue writes one or more XML elements representing val. diff --git a/opensca/sca/java/xml/read.go b/opensca/sca/java/xml/read.go index ed669485..2306a1a8 100644 --- a/opensca/sca/java/xml/read.go +++ b/opensca/sca/java/xml/read.go @@ -303,10 +303,10 @@ func (d *Decoder) unmarshalAttr(val reflect.Value, attr Attr) error { } var ( - attrType = reflect.TypeOf(Attr{}) - unmarshalerType = reflect.TypeOf((*Unmarshaler)(nil)).Elem() - unmarshalerAttrType = reflect.TypeOf((*UnmarshalerAttr)(nil)).Elem() - textUnmarshalerType = reflect.TypeOf((*encoding.TextUnmarshaler)(nil)).Elem() + attrType = reflect.TypeFor[Attr]() + unmarshalerType = reflect.TypeFor[Unmarshaler]() + unmarshalerAttrType = reflect.TypeFor[UnmarshalerAttr]() + textUnmarshalerType = reflect.TypeFor[encoding.TextUnmarshaler]() ) const ( diff --git a/opensca/sca/java/xml/typeinfo.go b/opensca/sca/java/xml/typeinfo.go index 058a384d..edd70b0c 100644 --- a/opensca/sca/java/xml/typeinfo.go +++ b/opensca/sca/java/xml/typeinfo.go @@ -48,7 +48,7 @@ const ( var tinfoMap sync.Map // map[reflect.Type]*typeInfo -var nameType = reflect.TypeOf(Name{}) +var nameType = reflect.TypeFor[Name]() // getTypeInfo returns the typeInfo structure with details necessary // for marshaling and unmarshaling typ. diff --git a/opensca/sca/python/env.go b/opensca/sca/python/env.go index f84574f8..a70e0325 100644 --- a/opensca/sca/python/env.go +++ b/opensca/sca/python/env.go @@ -10,6 +10,7 @@ import ( "path/filepath" "strings" + "github.com/xmirrorsecurity/opensca-cli/v3/cmd/config" "github.com/xmirrorsecurity/opensca-cli/v3/opensca/common" "github.com/xmirrorsecurity/opensca-cli/v3/opensca/logs" "github.com/xmirrorsecurity/opensca-cli/v3/opensca/model" @@ -123,6 +124,9 @@ func pipenvGraph(ctx context.Context, dir string) *model.DepGraph { } func runCmd(ctx context.Context, dir string, cmd string, args ...string) ([]byte, bool) { + if !config.Conf().Optional.Dynamic { + return nil, false + } c := exec.CommandContext(ctx, cmd, args...) c.Dir = dir out, err := c.CombinedOutput() diff --git a/opensca/sca/python/oss.py b/opensca/sca/python/oss.py deleted file mode 100644 index 624e4c7f..00000000 --- a/opensca/sca/python/oss.py +++ /dev/null @@ -1,36 +0,0 @@ -import re -import sys -import json - -def parse_setup_py(setup_py_path): - """解析setup.py文件""" - - with open(setup_py_path, "r", encoding='utf8') as f: - pass_func = lambda **x: x - try: - import distutils - distutils.core.setup = pass_func # type: ignore - except Exception: - pass - try: - import setuptools - setuptools.setup = pass_func # type: ignore - except Exception: - pass - - # 获取setup参数 - args = {} - code = re.sub(r'(?>opensca_end'.format(json.dumps(info))) - -if __name__ == "__main__": - if len(sys.argv) > 1: - parse_setup_py(sys.argv[1]) \ No newline at end of file diff --git a/opensca/sca/python/setup.go b/opensca/sca/python/setup.go index 2a48f847..119f34f6 100644 --- a/opensca/sca/python/setup.go +++ b/opensca/sca/python/setup.go @@ -2,28 +2,17 @@ package python import ( _ "embed" - "encoding/json" "io" - "os" - "os/exec" - "path/filepath" "regexp" "strings" - "github.com/xmirrorsecurity/opensca-cli/v3/opensca/logs" "github.com/xmirrorsecurity/opensca-cli/v3/opensca/model" ) // ParseSetup 解析setup.py func ParseSetup(file *model.File) *model.DepGraph { - // 尝试调用python解析 - root := ParseSetupPyWithPython(file) - if root != nil && len(root.Children) > 0 { - return root - } - - root = &model.DepGraph{Path: file.Relpath()} + root := &model.DepGraph{Path: file.Relpath()} // 静态解析 file.OpenReader(func(reader io.Reader) { @@ -56,69 +45,3 @@ func ParseSetup(file *model.File) *model.DepGraph { return root } - -//go:embed oss.py -var ossPy []byte - -// oss.py 脚本输出的依赖结构 -type setupDep struct { - Name string `json:"name"` - Version string `json:"version"` - License string `json:"license"` - Packages []string `json:"packages"` - InstallRequires []string `json:"install_requires"` - Requires []string `json:"requires"` -} - -func ParseSetupPyWithPython(file *model.File) *model.DepGraph { - - if _, err := exec.LookPath("python"); err != nil { - return nil - } - - dir := filepath.Dir(file.Abspath()) - ossfile := filepath.Join(dir, "oss.py") - - // 创建 oss.py - if err := os.WriteFile(ossfile, ossPy, 0777); err != nil { - logs.Warn(err) - return nil - } - - // 解析 setup.py - cmd := exec.Command("python", ossfile, file.Abspath()) - out, _ := cmd.CombinedOutput() - startTag, endTag := `opensca_start<<`, `>>opensca_end` - startIndex, endIndex := strings.Index(string(out), startTag), strings.Index(string(out), endTag) - if startIndex == -1 || endIndex == -1 { - return nil - } else { - out = out[startIndex+len(startTag) : endIndex] - } - - // 获取解析结果 - var dep setupDep - if err := json.Unmarshal(out, &dep); err != nil { - logs.Warn(err) - return nil - } - - root := &model.DepGraph{Name: dep.Name, Version: dep.Version, Path: file.Relpath()} - root.AppendLicense(dep.License) - - for _, pkg := range [][]string{dep.Packages, dep.InstallRequires, dep.Requires} { - for _, p := range pkg { - index := strings.IndexAny(p, "=<>") - var name, version string - if index > -1 { - name = p[:index] - version = p[index:] - } else { - name = p - } - root.AppendChild(&model.DepGraph{Name: name, Version: version}) - } - } - - return root -}