diff --git a/pkg/languages/java/.snapshots/TestImport-import.yml b/pkg/languages/java/.snapshots/TestImport-import.yml new file mode 100644 index 000000000..7923e6d97 --- /dev/null +++ b/pkg/languages/java/.snapshots/TestImport-import.yml @@ -0,0 +1,30 @@ +high: + - rule: + cwe_ids: + - "42" + id: import_test + title: Test import handling + description: Test import handling + documentation_url: "" + line_number: 7 + full_filename: import.java + filename: import.java + source: + location: + start: 7 + end: 7 + column: + start: 9 + end: 21 + sink: + location: + start: 7 + end: 7 + column: + start: 9 + end: 21 + content: "" + parent_line_number: 7 + fingerprint: fd41a77f77dc09c75355f0d8bf69d976_0 + old_fingerprint: fd41a77f77dc09c75355f0d8bf69d976_0 + diff --git a/pkg/languages/java/analyzer/analyzer.go b/pkg/languages/java/analyzer/analyzer.go index 1c883beb1..b2e9d3777 100644 --- a/pkg/languages/java/analyzer/analyzer.go +++ b/pkg/languages/java/analyzer/analyzer.go @@ -2,6 +2,7 @@ package analyzer import ( "slices" + "strings" sitter "github.com/smacker/go-tree-sitter" @@ -48,6 +49,8 @@ func (analyzer *analyzer) Analyze(node *sitter.Node, visitChildren func() error) return analyzer.withScope(language.NewScope(analyzer.scope), func() error { return visitChildren() }) + case "import_declaration": + return analyzer.analyzeImport(node, visitChildren) case "assignment_expression": return analyzer.analyzeAssignment(node, visitChildren) case "variable_declarator": @@ -84,6 +87,29 @@ func (analyzer *analyzer) Analyze(node *sitter.Node, visitChildren func() error) } } +// import foo.Bar; +// import foo.*; +// import static foo.Bar; +func (analyzer *analyzer) analyzeImport(node *sitter.Node, visitChildren func() error) error { + // package import + if node.NamedChildCount() != 1 { + return nil + } + + identifier := node.NamedChild(0) + + content := analyzer.builder.ContentFor(node) + prefix := content[:identifier.StartByte()-node.StartByte()] + if strings.Contains(prefix, "static") { + return nil + } + + name := identifier.ChildByFieldName("name") + analyzer.scope.Declare(analyzer.builder.ContentFor(name), name) + analyzer.builder.Alias(name, identifier) + return nil +} + // foo = a // foo += a func (analyzer *analyzer) analyzeAssignment(node *sitter.Node, visitChildren func() error) error { diff --git a/pkg/languages/java/java_test.go b/pkg/languages/java/java_test.go index b3f48bc05..ff8a9c662 100644 --- a/pkg/languages/java/java_test.go +++ b/pkg/languages/java/java_test.go @@ -11,12 +11,19 @@ import ( patternquerybuilder "github.com/bearer/bearer/pkg/scanner/detectors/customrule/patternquery/builder" ) +//go:embed testdata/import.yml +var importRule []byte + //go:embed testdata/logger.yml var loggerRule []byte //go:embed testdata/scope_rule.yml var scopeRule []byte +func TestImport(t *testing.T) { + testhelper.GetRunner(t, importRule, java.Get()).RunTest(t, "./testdata/import", ".snapshots/") +} + func TestFlow(t *testing.T) { testhelper.GetRunner(t, loggerRule, java.Get()).RunTest(t, "./testdata/testcases/flow", ".snapshots/flow/") } diff --git a/pkg/languages/java/testdata/import.yml b/pkg/languages/java/testdata/import.yml new file mode 100644 index 000000000..8c32fabdc --- /dev/null +++ b/pkg/languages/java/testdata/import.yml @@ -0,0 +1,21 @@ +languages: + - java +patterns: + - pattern: sink($) + filters: + - variable: IMPORT + detection: flow_test_source + scope: cursor +auxiliary: + - id: flow_test_source + patterns: + - import $foo.Import + - import $foo.Import2 + - import $foo.Import3 +severity: high +metadata: + description: Test import handling + remediation_message: Test import handling + cwe_id: + - 42 + id: import_test diff --git a/pkg/languages/java/testdata/import/import.java b/pkg/languages/java/testdata/import/import.java new file mode 100644 index 000000000..4c9284b7e --- /dev/null +++ b/pkg/languages/java/testdata/import/import.java @@ -0,0 +1,11 @@ +import foo.Import; +import foo.Import2.*; +import static foo.Import3; + +class A { + public void exec() { + sink(Import); + sink(Import2); // no match + sink(Import3); // no match + } +} \ No newline at end of file