Projects STRLCPY bearer Commits 48716b86
🤬
  • ■ ■ ■ ■ ■ ■
    pkg/report/output/dataflow/risks/risks.go
    skipped 36 lines
    37 37  }
    38 38   
    39 39  type dataTypeCategoryHolder struct {
    40  - name string
    41  - isPresence bool
    42  - dataType map[string]dataTypeHolder
     40 + name string
     41 + category string
     42 + parent *schema.Parent
     43 + dataType map[string]dataTypeHolder
    43 44  }
    44 45   
    45 46  type dataTypeHolder struct {
    skipped 4 lines
    50 51   subjectName *string
    51 52  }
    52 53   
     54 +var categoryPresence = "presence"
     55 +var categoryDatatype = "datatype"
     56 + 
    53 57  func New(config settings.Config, isInternal bool) *Holder {
    54 58   return &Holder{
    55 59   detectors: make(map[string]detectorHolder),
    skipped 17 lines
    73 77   content = *detection.Source.Text
    74 78   }
    75 79   
    76  - holder.addDatatype(ruleName, &db.DataType{Name: content}, nil, fileName, lineNumber, schema.Schema{Parent: parent}, true)
     80 + holder.addDatatype(ruleName, &db.DataType{Name: content}, nil, fileName, lineNumber, schema.Schema{Parent: parent}, categoryPresence)
    77 81  }
    78 82   
    79 83  func (holder *Holder) AddSchema(detection detections.Detection) error {
    skipped 15 lines
    95 99   detection.Source.Filename,
    96 100   *detection.Source.LineNumber,
    97 101   schema,
    98  - false,
     102 + categoryDatatype,
    99 103   )
    100 104   }
    101 105   
    skipped 1 lines
    103 107  }
    104 108   
    105 109  // addDatatype adds detector to hash list and at the same time blocks duplicates
    106  -func (holder *Holder) addDatatype(ruleName string, datatype *db.DataType, subjectName *string, fileName string, lineNumber int, schema schema.Schema, isPresence bool) {
     110 +func (holder *Holder) addDatatype(ruleName string, datatype *db.DataType, subjectName *string, fileName string, lineNumber int, schema schema.Schema, category string) {
    107 111   if datatype == nil {
    108 112   // FIXME: we end up with empty field Name and no datatype with the new code
    109 113   // Might be related to the bug with the Unique Identifier classification
    skipped 29 lines
    139 143   line := file.lineNumber[lineNumber]
    140 144   // create datatype category entry if it doesn't exist
    141 145   if _, exists := line.dataTypeCategory[datatype.Name]; !exists {
    142  - line.dataTypeCategory[datatype.Name] = dataTypeCategoryHolder{
    143  - name: datatype.Name,
    144  - isPresence: isPresence,
    145  - dataType: make(map[string]dataTypeHolder),
     146 + categoryToAdd := dataTypeCategoryHolder{
     147 + name: datatype.Name,
     148 + category: category,
     149 + dataType: make(map[string]dataTypeHolder),
     150 + }
     151 + 
     152 + if category == "presence" {
     153 + categoryToAdd.parent = schema.Parent
    146 154   }
     155 + 
     156 + line.dataTypeCategory[datatype.Name] = categoryToAdd
    147 157   }
    148 158   
    149  - if isPresence {
    150  - datatypeCategory := line.dataTypeCategory[datatype.Name]
    151  - if schema.Parent != nil {
    152  - datatypeKey := schema.Parent.Content
    153  - // create datatype if it doesn't exists
    154  - if _, exists := datatypeCategory.dataType[datatypeKey]; !exists {
    155  - datatypeCategory.dataType[datatypeKey] = dataTypeHolder{
    156  - content: &datatypeKey,
    157  - }
    158  - }
    159  - }
    160  - } else {
     159 + if category == "datatype" {
    161 160   datatypeCategory := line.dataTypeCategory[datatype.Name]
    162 161   datatypeKey := schema.FieldName + schema.ObjectName
    163 162   // create datatype if it doesn't exists
    skipped 33 lines
    197 196   
    198 197   for _, dataTypeCategory := range maputil.ToSortedSlice(line.dataTypeCategory) {
    199 198   category := types.RiskDatatypeCategory{
    200  - Name: dataTypeCategory.name,
    201  - IsPresence: dataTypeCategory.isPresence,
     199 + Name: dataTypeCategory.name,
     200 + Category: dataTypeCategory.category,
     201 + }
     202 + 
     203 + if category.Category == categoryPresence {
     204 + category.Parent = dataTypeCategory.parent
     205 + category.Stored = &stored
    202 206   }
    203 207   
    204 208   for _, dataType := range maputil.ToSortedSlice(dataTypeCategory.dataType) {
    skipped 3 lines
    208 212   Stored: stored,
    209 213   }
    210 214   
    211  - if dataType.content != nil {
    212  - riskDatatype.Content = *dataType.content
    213  - }
    214 215   if dataType.fieldName != nil {
    215 216   riskDatatype.FieldName = *dataType.fieldName
    216 217   }
    skipped 42 lines
  • ■ ■ ■ ■ ■ ■
    pkg/report/output/dataflow/risks/risks_test.go
    skipped 44 lines
    45 45   LineNumber: 25,
    46 46   DataTypeCategories: []types.RiskDatatypeCategory{
    47 47   {
    48  - Name: "Username",
    49  - IsPresence: false,
     48 + Name: "Username",
    50 49   DataTypes: []types.RiskDatatype{
    51 50   {
    52 51   FieldName: "User_name",
    skipped 26 lines
    79 78   LineNumber: 25,
    80 79   DataTypeCategories: []types.RiskDatatypeCategory{
    81 80   {
    82  - Name: "Username",
    83  - IsPresence: false,
     81 + Name: "Username",
    84 82   DataTypes: []types.RiskDatatype{
    85 83   {
    86 84   FieldName: "User_name",
    skipped 19 lines
    106 104   LineNumber: 25,
    107 105   DataTypeCategories: []types.RiskDatatypeCategory{
    108 106   {
    109  - Name: "Username",
    110  - IsPresence: false,
     107 + Name: "Username",
    111 108   DataTypes: []types.RiskDatatype{
    112 109   {
    113 110   Stored: true,
    skipped 21 lines
    135 132   LineNumber: 25,
    136 133   DataTypeCategories: []types.RiskDatatypeCategory{
    137 134   {
    138  - Name: "Username",
    139  - IsPresence: false,
     135 + Name: "Username",
    140 136   DataTypes: []types.RiskDatatype{
    141 137   {
    142 138   FieldName: "User_name",
    skipped 20 lines
    163 159   LineNumber: 25,
    164 160   DataTypeCategories: []types.RiskDatatypeCategory{
    165 161   {
    166  - Name: "Physical Address",
    167  - IsPresence: false,
     162 + Name: "Physical Address",
    168 163   DataTypes: []types.RiskDatatype{
    169 164   {
    170 165   FieldName: "address",
    skipped 1 lines
    172 167   },
    173 168   },
    174 169   {
    175  - Name: "Username",
    176  - IsPresence: false,
     170 + Name: "Username",
    177 171   DataTypes: []types.RiskDatatype{
    178 172   {
    179 173   FieldName: "User_name",
    skipped 45 lines
  • ■ ■ ■ ■ ■ ■
    pkg/report/output/dataflow/types/risks.go
    skipped 9 lines
    10 10  type RiskLocation struct {
    11 11   Filename string `json:"filename" yaml:"filename"`
    12 12   LineNumber int `json:"line_number" yaml:"line_number"`
    13  - DataTypeCategories []RiskDatatypeCategory `json:"data_type_categories,omitempty" yaml:"data_type_categories,omitempty"`
     13 + DataTypeCategories []RiskDatatypeCategory `json:"categories,omitempty" yaml:"categories,omitempty"`
    14 14  }
    15 15   
    16 16  type RiskDatatypeCategory struct {
    17  - Name string `json:"name,omitempty" yaml:"name,omitempty"`
    18  - DataTypes []RiskDatatype `json:"data_types,omitempty" yaml:"data_types,omitempty"`
    19  - IsPresence bool `json:"is_presence,omitempty" yaml:"is_presence,omitempty"`
     17 + Category string `json:"category,omitempty" yaml:"category,omitempty"`
     18 + Name string `json:"name,omitempty" yaml:"name,omitempty"`
     19 + DataTypes []RiskDatatype `json:"data_types,omitempty" yaml:"data_types,omitempty"`
     20 + Parent *schema.Parent `json:"parent,omitempty" yaml:"parent,omitempty"`
     21 + Stored *bool `json:"stored,omitempty" yaml:"stored,omitempty"`
    20 22  }
    21 23   
    22 24  type RiskDatatype struct {
    23 25   Parent *schema.Parent `json:"parent,omitempty" yaml:"parent,omitempty"`
    24  - Content string `json:"content,omitempty" yaml:"content,omitempty"`
    25 26   FieldName string `json:"field_name,omitempty" yaml:"field_name,omitempty"`
    26 27   ObjectName string `json:"object_name,omitempty" yaml:"object_name,omitempty"`
    27 28   SubjectName *string `json:"subject_name,omitempty" yaml:"subject_name,omitempty"`
    skipped 3 lines
  • ■ ■ ■ ■ ■ ■
    pkg/report/output/security/security_test.go
    1  -package security_test
    2  - 
    3  -import (
    4  - "testing"
    5  - 
    6  - "github.com/bearer/bearer/pkg/commands/process/settings"
    7  - "github.com/bearer/bearer/pkg/flag"
    8  - "github.com/bearer/bearer/pkg/report/output/dataflow"
    9  - "github.com/bearer/bearer/pkg/report/output/dataflow/types"
    10  - "github.com/bearer/bearer/pkg/report/output/security"
    11  - "github.com/bearer/bearer/pkg/report/schema"
    12  - "github.com/bradleyjkemp/cupaloy"
    13  - "github.com/hhatto/gocloc"
    14  -)
    15  - 
    16  -func TestBuildReportString(t *testing.T) {
    17  - config, err := generateConfig(flag.ReportOptions{
    18  - Report: "security",
    19  - Severity: map[string]bool{
    20  - "critical": true,
    21  - "high": true,
    22  - "medium": true,
    23  - "low": true,
    24  - "warning": true,
    25  - },
    26  - })
    27  - 
    28  - // new rules are added
    29  - customRule := &settings.Rule{
    30  - Id: "custom_test_rule",
    31  - Description: "Its a test!",
    32  - CWEIDs: []string{},
    33  - Type: "risk",
    34  - Languages: []string{"ruby"},
    35  - Severity: "low",
    36  - IsLocal: false,
    37  - }
    38  - 
    39  - // limit rules so that test doesn't fail just because
    40  - config.Rules = map[string]*settings.Rule{
    41  - "ruby_lang_ssl_verification": config.Rules["ruby_lang_ssl_verification"],
    42  - "ruby_rails_logger": config.Rules["ruby_rails_logger"],
    43  - "custom_test_rule": customRule,
    44  - }
    45  - 
    46  - if err != nil {
    47  - t.Fatalf("failed to generate config:%s", err)
    48  - }
    49  - 
    50  - dataflow := dummyDataflow()
    51  - 
    52  - results, err := security.GetOutput(&dataflow, config)
    53  - if err != nil {
    54  - t.Fatalf("failed to generate security output err:%s", err)
    55  - }
    56  - 
    57  - dummyGoclocLanguage := gocloc.Language{}
    58  - dummyGoclocResult := gocloc.Result{
    59  - Total: &dummyGoclocLanguage,
    60  - Files: map[string]*gocloc.ClocFile{},
    61  - Languages: map[string]*gocloc.Language{
    62  - "Ruby": {},
    63  - },
    64  - MaxPathLength: 0,
    65  - }
    66  - 
    67  - stringBuilder, _ := security.BuildReportString(config, results, &dummyGoclocResult, &dataflow)
    68  - cupaloy.SnapshotT(t, stringBuilder.String())
    69  -}
    70  - 
    71  -func TestGetOutput(t *testing.T) {
    72  - config, err := generateConfig(flag.ReportOptions{
    73  - Report: "security",
    74  - Severity: map[string]bool{
    75  - "critical": true,
    76  - "high": true,
    77  - "medium": true,
    78  - "low": true,
    79  - "warning": true,
    80  - },
    81  - })
    82  - 
    83  - if err != nil {
    84  - t.Fatalf("failed to generate config:%s", err)
    85  - }
    86  - 
    87  - dataflow := dummyDataflow()
    88  - 
    89  - res, err := security.GetOutput(&dataflow, config)
    90  - if err != nil {
    91  - t.Fatalf("failed to generate security output err:%s", err)
    92  - }
    93  - 
    94  - cupaloy.SnapshotT(t, res)
    95  -}
    96  - 
    97  -func TestTestGetOutputWithSeverity(t *testing.T) {
    98  - config, err := generateConfig(flag.ReportOptions{
    99  - Report: "security",
    100  - Severity: map[string]bool{
    101  - "critical": true,
    102  - "high": false,
    103  - "medium": false,
    104  - "low": false,
    105  - "warning": false,
    106  - },
    107  - })
    108  - 
    109  - if err != nil {
    110  - t.Fatalf("failed to generate config:%s", err)
    111  - }
    112  - 
    113  - dataflow := dummyDataflow()
    114  - 
    115  - res, err := security.GetOutput(&dataflow, config)
    116  - if err != nil {
    117  - t.Fatalf("failed to generate security output err:%s", err)
    118  - }
    119  - 
    120  - cupaloy.SnapshotT(t, res)
    121  -}
    122  - 
    123  -func TestCalculateSeverity(t *testing.T) {
    124  - res := []string{
    125  - security.CalculateSeverity([]string{"PHI", "Personal Data"}, "low", true),
    126  - security.CalculateSeverity([]string{"Personal Data (Sensitive)"}, "low", false),
    127  - security.CalculateSeverity([]string{"Personal Data"}, "low", false),
    128  - security.CalculateSeverity([]string{"Personal Data"}, "warning", false),
    129  - security.CalculateSeverity([]string{}, "warning", false),
    130  - }
    131  - 
    132  - cupaloy.SnapshotT(t, res)
    133  -}
    134  - 
    135  -func generateConfig(reportOptions flag.ReportOptions) (settings.Config, error) {
    136  - opts := flag.Options{
    137  - ScanOptions: flag.ScanOptions{
    138  - Scanner: []string{"sast"},
    139  - },
    140  - RuleOptions: flag.RuleOptions{},
    141  - RepoOptions: flag.RepoOptions{},
    142  - ReportOptions: reportOptions,
    143  - GeneralOptions: flag.GeneralOptions{},
    144  - }
    145  - 
    146  - return settings.FromOptions(opts)
    147  -}
    148  - 
    149  -func dummyDataflow() dataflow.DataFlow {
    150  - subject := "User"
    151  - riskLocation := types.RiskLocation{
    152  - Filename: "config/application.rb",
    153  - LineNumber: 2,
    154  - FieldName: "",
    155  - ObjectName: "",
    156  - SubjectName: &subject,
    157  - Parent: &schema.Parent{
    158  - LineNumber: 2,
    159  - Content: "http.verify_mode = OpenSSL::SSL::VERIFY_NONE",
    160  - },
    161  - }
    162  - lowRisk := types.RiskDetection{
    163  - DetectorID: "ruby_lang_ssl_verification",
    164  - Locations: []types.RiskDetectionLocation{
    165  - {
    166  - Content: "http.verify_mode = OpenSSL::SSL::VERIFY_NONE",
    167  - RiskLocation: &riskLocation,
    168  - },
    169  - },
    170  - }
    171  - 
    172  - criticalRisk := types.RiskDetector{
    173  - DetectorID: "ruby_rails_logger",
    174  - DataTypes: []types.RiskDatatype{
    175  - {
    176  - Name: "Biometric Data",
    177  - Stored: false,
    178  - UUID: "85599b0c-37b6-4855-af54-5789edc27c00",
    179  - CategoryUUID: "35b94efa-9b67-49b2-abb9-29b6a759a030",
    180  - Locations: []types.RiskLocation{
    181  - {
    182  - Filename: "pkg/datatype_leak.rb",
    183  - LineNumber: 1,
    184  - FieldName: "biometric_data",
    185  - ObjectName: "user",
    186  - SubjectName: &subject,
    187  - Parent: &schema.Parent{
    188  - LineNumber: 1,
    189  - Content: "Rails.logger.info(user.biometric_data)",
    190  - },
    191  - },
    192  - },
    193  - },
    194  - },
    195  - }
    196  - 
    197  - // build risk []interface
    198  - risks := make([]interface{}, 2)
    199  - risks[0] = criticalRisk
    200  - risks[1] = lowRisk
    201  - 
    202  - return dataflow.DataFlow{
    203  - Datatypes: []types.Datatype{
    204  - {
    205  - Name: "Email Address",
    206  - UUID: "02bb0d3a-2c8c-4842-be1c-c057f0dccd63",
    207  - CategoryUUID: "dd88aee5-9d40-4ad2-8983-0c791ddec47c",
    208  - Detectors: []types.DatatypeDetector{
    209  - {
    210  - Name: "ruby",
    211  - Locations: []types.DatatypeLocation{
    212  - {
    213  - Filename: "app/model/user.rb",
    214  - LineNumber: 1,
    215  - FieldName: "email",
    216  - ObjectName: "user",
    217  - SubjectName: &subject,
    218  - },
    219  - },
    220  - },
    221  - },
    222  - },
    223  - },
    224  - Risks: risks,
    225  - Components: []types.Component{},
    226  - }
    227  -}
    228  - 
Please wait...
Page is in error, reload to recover