diff --git a/internal/classification/schema/.snapshots/TestJava b/internal/classification/schema/.snapshots/TestJava index 746598194..6128ed6d9 100644 --- a/internal/classification/schema/.snapshots/TestJava +++ b/internal/classification/schema/.snapshots/TestJava @@ -1,4 +1,4 @@ -([]testhelper.ClassificationResult) (len=36) { +([]testhelper.ClassificationResult) (len=38) { (testhelper.ClassificationResult) { Name: (string) (len=25) "RepositorySystemHookEvent", Decision: (classify.ClassificationDecision) { @@ -109,6 +109,23 @@ } } }, + (testhelper.ClassificationResult) { + Name: (string) (len=29) "QueryRobotDialogDetailRequest", + Decision: (classify.ClassificationDecision) { + State: (classify.ValidationState) (len=7) "invalid", + Reason: (string) (len=19) "only_db_identifiers" + }, + Properties: (map[string]testhelper.ClassificationResult) (len=1) { + (string) (len=10) "setOwnerId": (testhelper.ClassificationResult) { + Name: (string) (len=10) "setOwnerId", + Decision: (classify.ClassificationDecision) { + State: (classify.ValidationState) (len=5) "valid", + Reason: (string) (len=25) "known_database_identifier" + }, + Properties: (map[string]testhelper.ClassificationResult) + } + } + }, (testhelper.ClassificationResult) { Name: (string) (len=15) "RSADigestSigner", Decision: (classify.ClassificationDecision) { @@ -286,6 +303,23 @@ } } }, + (testhelper.ClassificationResult) { + Name: (string) (len=20) "UserOAuthAccessToken", + Decision: (classify.ClassificationDecision) { + State: (classify.ValidationState) (len=5) "valid", + Reason: (string) (len=34) "valid_object_with_valid_properties" + }, + Properties: (map[string]testhelper.ClassificationResult) (len=1) { + (string) (len=13) "getClientName": (testhelper.ClassificationResult) { + Name: (string) (len=13) "getClientName", + Decision: (classify.ClassificationDecision) { + State: (classify.ValidationState) (len=5) "valid", + Reason: (string) (len=13) "known_pattern" + }, + Properties: (map[string]testhelper.ClassificationResult) + } + } + }, (testhelper.ClassificationResult) { Name: (string) (len=13) "UserQueryImpl", Decision: (classify.ClassificationDecision) { @@ -443,8 +477,8 @@ (string) (len=9) "getUserId": (testhelper.ClassificationResult) { Name: (string) (len=9) "getUserId", Decision: (classify.ClassificationDecision) { - State: (classify.ValidationState) (len=7) "invalid", - Reason: (string) (len=16) "invalid_property" + State: (classify.ValidationState) (len=5) "valid", + Reason: (string) (len=25) "known_database_identifier" }, Properties: (map[string]testhelper.ClassificationResult) }, @@ -547,8 +581,8 @@ (string) (len=9) "setUserId": (testhelper.ClassificationResult) { Name: (string) (len=9) "setUserId", Decision: (classify.ClassificationDecision) { - State: (classify.ValidationState) (len=7) "invalid", - Reason: (string) (len=16) "invalid_property" + State: (classify.ValidationState) (len=5) "valid", + Reason: (string) (len=25) "known_database_identifier" }, Properties: (map[string]testhelper.ClassificationResult) }, diff --git a/internal/classification/schema/.snapshots/TestJavaKPI b/internal/classification/schema/.snapshots/TestJavaKPI index 41c3c2acd..5cc31ffe2 100644 --- a/internal/classification/schema/.snapshots/TestJavaKPI +++ b/internal/classification/schema/.snapshots/TestJavaKPI @@ -1,8 +1,8 @@ (testhelper.KPI) { DetectionsCount: (int) 6230, - ValidDetectionsCount: (int) 126, - ValidObjectDetectionsCount: (int) 34, - ValidFieldDetectionsCount: (int) 92, + ValidDetectionsCount: (int) 131, + ValidObjectDetectionsCount: (int) 35, + ValidFieldDetectionsCount: (int) 96, ExpectedValidDetectionsCount: (int) 137, ExpectedValidObjectDetectionsCount: (int) 37, ExpectedValidFieldDetectionsCount: (int) 100, diff --git a/internal/classification/schema/.snapshots/TestPHP b/internal/classification/schema/.snapshots/TestPHP index ace750ece..854276b60 100644 --- a/internal/classification/schema/.snapshots/TestPHP +++ b/internal/classification/schema/.snapshots/TestPHP @@ -411,8 +411,8 @@ (string) (len=7) "getName": (testhelper.ClassificationResult) { Name: (string) (len=7) "getName", Decision: (classify.ClassificationDecision) { - State: (classify.ValidationState) (len=7) "invalid", - Reason: (string) (len=16) "invalid_property" + State: (classify.ValidationState) (len=5) "valid", + Reason: (string) (len=22) "valid_extended_pattern" }, Properties: (map[string]testhelper.ClassificationResult) }, diff --git a/internal/classification/schema/.snapshots/TestPHPKPI b/internal/classification/schema/.snapshots/TestPHPKPI index 4688c10eb..c5997156f 100644 --- a/internal/classification/schema/.snapshots/TestPHPKPI +++ b/internal/classification/schema/.snapshots/TestPHPKPI @@ -1,8 +1,8 @@ (testhelper.KPI) { DetectionsCount: (int) 353, - ValidDetectionsCount: (int) 118, + ValidDetectionsCount: (int) 119, ValidObjectDetectionsCount: (int) 27, - ValidFieldDetectionsCount: (int) 91, + ValidFieldDetectionsCount: (int) 92, ExpectedValidDetectionsCount: (int) 143, ExpectedValidObjectDetectionsCount: (int) 33, ExpectedValidFieldDetectionsCount: (int) 110, diff --git a/internal/languages/php/detectors/.snapshots/TestPHPObjects-object_no_class b/internal/languages/php/detectors/.snapshots/TestPHPObjects-object_no_class index 4020c8b36..da20a4b39 100644 --- a/internal/languages/php/detectors/.snapshots/TestPHPObjects-object_no_class +++ b/internal/languages/php/detectors/.snapshots/TestPHPObjects-object_no_class @@ -1,10 +1,12 @@ type: program id: 0 -range: 1:1 - 3:3 +range: 1:1 - 6:1 dataflow_sources: - 1 - 2 - - 14 + - 13 + - 27 + - 41 children: - type: php_tag id: 1 @@ -12,15 +14,15 @@ children: content: "' id: 7 - range: 2:6 - 2:7 - - type: function_call_expression + range: 2:6 - 2:8 + - type: name id: 8 - range: 2:7 - 2:13 + range: 2:8 - 2:12 + content: name + - type: arguments + id: 9 + range: 2:12 - 2:14 dataflow_sources: - 10 + - 11 children: + - type: '"("' + id: 10 + range: 2:12 - 2:13 + - type: '")"' + id: 11 + range: 2:13 - 2:14 + - type: '";"' + id: 12 + range: 2:14 - 2:15 + - type: expression_statement + id: 13 + range: 3:1 - 3:21 + children: + - type: member_call_expression + id: 14 + range: 3:1 - 3:20 + dataflow_sources: + - 23 + queries: + - 2 + children: + - type: member_access_expression + id: 15 + range: 3:1 - 3:12 + queries: + - 2 + children: + - type: variable_name + id: 16 + range: 3:1 - 3:6 + children: + - type: '"$"' + id: 17 + range: 3:1 - 3:2 + - type: name + id: 18 + range: 3:2 - 3:6 + content: this + - type: '"->"' + id: 19 + range: 3:6 - 3:8 - type: name - id: 9 - range: 2:7 - 2:11 - content: name + id: 20 + range: 3:8 - 3:12 + content: user + - type: '"->"' + id: 21 + range: 3:12 - 3:14 + - type: name + id: 22 + range: 3:14 - 3:18 + content: name + - type: arguments + id: 23 + range: 3:18 - 3:20 + dataflow_sources: + - 24 + - 25 + children: + - type: '"("' + id: 24 + range: 3:18 - 3:19 + - type: '")"' + id: 25 + range: 3:19 - 3:20 + - type: '";"' + id: 26 + range: 3:20 - 3:21 + - type: expression_statement + id: 27 + range: 4:1 - 4:21 + children: + - type: member_access_expression + id: 28 + range: 4:1 - 4:20 + queries: + - 2 + children: + - type: member_call_expression + id: 29 + range: 4:1 - 4:14 + dataflow_sources: + - 35 + queries: + - 2 + children: + - type: variable_name + id: 30 + range: 4:1 - 4:6 + children: + - type: '"$"' + id: 31 + range: 4:1 - 4:2 + - type: name + id: 32 + range: 4:2 - 4:6 + content: this + - type: '"->"' + id: 33 + range: 4:6 - 4:8 + - type: name + id: 34 + range: 4:8 - 4:12 + content: user - type: arguments - id: 10 - range: 2:11 - 2:13 + id: 35 + range: 4:12 - 4:14 dataflow_sources: - - 11 - - 12 + - 36 + - 37 children: - type: '"("' - id: 11 - range: 2:11 - 2:12 + id: 36 + range: 4:12 - 4:13 - type: '")"' - id: 12 - range: 2:12 - 2:13 + id: 37 + range: 4:13 - 4:14 + - type: '"->"' + id: 38 + range: 4:14 - 4:16 + - type: name + id: 39 + range: 4:16 - 4:20 + content: name - type: '";"' - id: 13 - range: 2:13 - 2:14 + id: 40 + range: 4:20 - 4:21 - type: text_interpolation - id: 14 - range: 3:1 - 3:3 + id: 41 + range: 5:1 - 5:3 dataflow_sources: - - 15 + - 42 children: - type: '"?>"' - id: 15 - range: 3:1 - 3:3 + id: 42 + range: 5:1 - 5:3 -[] +- node: 3 + content: $user->name() + data: + properties: + - name: $user + node: null + object: + ruleid: object + matchnode: + id: 3 + typeid: 3 + contentstart: + byte: 6 + line: 2 + column: 1 + contentend: + byte: 19 + line: 2 + column: 14 + executingdetectors: [] + data: + properties: + - name: name + node: null + object: null + isvirtual: true + isvirtual: true +- node: 14 + content: $this->user->name() + data: + properties: + - name: user + node: null + object: + ruleid: object + matchnode: + id: 14 + typeid: 3 + contentstart: + byte: 21 + line: 3 + column: 1 + contentend: + byte: 40 + line: 3 + column: 20 + executingdetectors: [] + data: + properties: + - name: name + node: null + object: null + isvirtual: true + isvirtual: true +- node: 28 + content: $this->user()->name + data: + properties: + - name: user + node: null + object: + ruleid: object + matchnode: + id: 28 + typeid: 12 + contentstart: + byte: 42 + line: 4 + column: 1 + contentend: + byte: 61 + line: 4 + column: 20 + executingdetectors: [] + data: + properties: + - name: name + node: null + object: null + isvirtual: true + isvirtual: true +- node: 15 + content: $this->user + data: + properties: + - name: $this + node: null + object: + ruleid: object + matchnode: + id: 15 + typeid: 12 + contentstart: + byte: 21 + line: 3 + column: 1 + contentend: + byte: 32 + line: 3 + column: 12 + executingdetectors: [] + data: + properties: + - name: user + node: null + object: null + isvirtual: true + isvirtual: true +- node: 29 + content: $this->user() + data: + properties: + - name: $this + node: null + object: + ruleid: object + matchnode: + id: 29 + typeid: 3 + contentstart: + byte: 42 + line: 4 + column: 1 + contentend: + byte: 55 + line: 4 + column: 14 + executingdetectors: [] + data: + properties: + - name: user + node: null + object: null + isvirtual: true + isvirtual: true diff --git a/internal/languages/php/detectors/object/object.go b/internal/languages/php/detectors/object/object.go index 2d53d3c0f..627d9fda6 100644 --- a/internal/languages/php/detectors/object/object.go +++ b/internal/languages/php/detectors/object/object.go @@ -6,7 +6,6 @@ import ( "github.com/bearer/bearer/internal/scanner/ast/tree" "github.com/bearer/bearer/internal/scanner/detectors/common" - detectorscommon "github.com/bearer/bearer/internal/scanner/detectors/common" "github.com/bearer/bearer/internal/scanner/detectors/types" "github.com/bearer/bearer/internal/scanner/ruleset" ) @@ -51,9 +50,9 @@ func New(querySet *query.Set) types.Detector { // $user->name; // $user->name(); fieldAccessQuery := querySet.Add(`[ - (member_access_expression object: (_) @object name: (name) @field) @root - (member_call_expression object: (_) @object name: (name) @field) @root - ]`) + (member_access_expression object: (_) @object name: (name) @field) + (member_call_expression object: (_) @object name: (name) @field) + ] @root`) // array('foo' => 'bar'); // [ 'foo' => 'bar' ]; @@ -110,10 +109,10 @@ func (detector *objectDetector) getArrayCreation( return nil, nil } - var properties []detectorscommon.Property + var properties []common.Property for _, result := range results { - pairNode := result["key"] - name := result["value"].Content() + keyNode := result["key"] + name := keyNode.Content() propertyObjects, err := detectorContext.Scan(result["value"], ruleset.BuiltinObjectRule, traversalstrategy.Cursor) if err != nil { @@ -121,24 +120,24 @@ func (detector *objectDetector) getArrayCreation( } if len(propertyObjects) == 0 { - properties = append(properties, detectorscommon.Property{ + properties = append(properties, common.Property{ Name: name, - Node: pairNode, + Node: keyNode, }) continue } for _, propertyObject := range propertyObjects { - properties = append(properties, detectorscommon.Property{ + properties = append(properties, common.Property{ Name: name, - Node: pairNode, + Node: keyNode, Object: propertyObject, }) } } - return []interface{}{detectorscommon.Object{Properties: properties}}, nil + return []interface{}{common.Object{Properties: properties}}, nil } func (detector *objectDetector) getAssignment( diff --git a/internal/languages/php/detectors/object/projection.go b/internal/languages/php/detectors/object/projection.go index 3d932e0c0..5032177b4 100644 --- a/internal/languages/php/detectors/object/projection.go +++ b/internal/languages/php/detectors/object/projection.go @@ -5,11 +5,10 @@ import ( "github.com/bearer/bearer/internal/util/stringutil" "github.com/bearer/bearer/internal/scanner/detectors/common" - detectorscommon "github.com/bearer/bearer/internal/scanner/detectors/common" "github.com/bearer/bearer/internal/scanner/detectors/types" ) -func (detector *objectDetector) getProjections( // Deal with subscriptExpressionQuery here / Check Ruby +func (detector *objectDetector) getProjections( node *tree.Node, detectorContext types.Context, ) ([]interface{}, error) { @@ -47,7 +46,7 @@ func (detector *objectDetector) getProjections( // Deal with subscriptExpression return nil, nil } - objects, err := detectorscommon.ProjectObject( + objects, err := common.ProjectObject( node, detectorContext, objectNode, @@ -66,10 +65,16 @@ func (detector *objectDetector) getProjections( // Deal with subscriptExpression } func getObjectName(objectNode *tree.Node) string { + switch objectNode.Type() { // $user->name() // $user->name - if objectNode.Type() == "variable_name" { + // user->name + case "variable_name", "name": return objectNode.Content() + // $user->foo->name + // $user->foo()->name + case "member_access_expression", "member_call_expression": + return objectNode.ChildByFieldName("name").Content() } return "" diff --git a/internal/languages/php/detectors/testdata/no_class.php b/internal/languages/php/detectors/testdata/no_class.php index 97c2fe56e..93e8e9845 100644 --- a/internal/languages/php/detectors/testdata/no_class.php +++ b/internal/languages/php/detectors/testdata/no_class.php @@ -1,3 +1,5 @@ \ No newline at end of file +$user->name(); +$this->user->name(); +$this->user()->name; +?> diff --git a/internal/util/normalize_key/normalize_key.go b/internal/util/normalize_key/normalize_key.go index 9f8f25747..c68215d13 100644 --- a/internal/util/normalize_key/normalize_key.go +++ b/internal/util/normalize_key/normalize_key.go @@ -2,12 +2,13 @@ package normalize_key import ( "regexp" + "slices" "strings" ) var ( normalizeCaseRegexp = regexp.MustCompile(`[A-Z][A-Z][a-z]|[a-z][A-Z]`) // Matches "AP(INa)me" or "firs(tN)ame" - normalizeSeparatorRegexp = regexp.MustCompile(`[_\-.,\s:0-9]+`) + normalizeSeparatorRegexp = regexp.MustCompile(`[$_\-.,\s:0-9]+`) ) func Normalize(key string) string { @@ -22,6 +23,10 @@ func Normalize(key string) string { pieces = append(pieces, normalizeKeyPiece(key[start:])) + if len(pieces) != 0 && (pieces[0] == "get" || pieces[0] == "set") { + pieces = slices.Delete(pieces, 0, 1) + } + return strings.Join(pieces, " ") }