Skip to content

Commit

Permalink
feat: Ruby policy for insecure FTP when sensitive data is processed (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
spdawson committed Dec 6, 2022
1 parent 9b4e1f9 commit fcea3bb
Show file tree
Hide file tree
Showing 13 changed files with 238 additions and 0 deletions.
55 changes: 55 additions & 0 deletions integration/flags/.snapshots/TestInitCommand-init
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,22 @@ scan:
metavars: {}
stored: false
detect_presence: true
detect_rails_insecure_ftp:
disabled: false
type: risk
languages:
- ruby
param_parenting: false
processors: []
patterns:
- pattern: |
Net::FTP::new
filters: []
root_singularize: false
root_lowercase: false
metavars: {}
stored: false
detect_presence: true
detect_rails_insecure_smtp:
disabled: false
type: risk
Expand Down Expand Up @@ -387,6 +403,45 @@ scan:
"parent_content": location.parent.content
}
}
insecure_ftp_processing_sensitive_data:
query: |
medium = data.bearer.insecure_ftp.medium
id: detect_rails_insecure_ftp
name: Insecure FTP
description: Communication with insecure FTP in an application processing sensitive data
level: ""
modules:
- path: policies/insecure_ftp.rego
name: bearer.insecure_ftp
content: |
package bearer.insecure_ftp

import future.keywords

sensitive_data_group_uuid := "f6a0c071-5908-4420-bac2-bba28d41223e"

has_sensitive_data if {
some data_type in input.dataflow.data_types
some data_category in input.data_categories
data_category.uuid == data_type.category_uuid
data_category.group_uuid == sensitive_data_group_uuid
}

medium[item] {
has_sensitive_data == true

some detector in input.dataflow.risks
detector.detector_id == input.policy_id

location = detector.locations[_]
item := {
"category_group": "sensitive data",
"filename": location.filename,
"line_number": location.line_number,
"parent_line_number": location.parent.line_number,
"parent_content": location.parent.content
}
}
insecure_smtp_processing_sensitive_data:
query: |
medium = data.bearer.insecure_smtp.medium
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
medium:
- policy_name: Insecure FTP
policy_description: Communication with insecure FTP in an application processing sensitive data
line_number: 10
filename: testdata/ruby/insecure_ftp/with_sensitive_data.rb
category_group: sensitive data
parent_line_number: 10
parent_content: Net::FTP::new("ftp.ruby-lang.org")


--

Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{}


--

2 changes: 2 additions & 0 deletions integration/policies/policies_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ func TestPolicies(t *testing.T) {
newPolicyTest("insecure_smtp_without_sensitive_data", []string{"ruby/insecure_smtp/without_sensitive_data.rb"}),
newPolicyTest("insecure_communication_with_sensitive_data", []string{"ruby/insecure_communication/with_sensitive_data.rb"}),
newPolicyTest("insecure_communication_without_sensitive_data", []string{"ruby/insecure_communication/without_sensitive_data.rb"}),
newPolicyTest("insecure_ftp_with_sensitive_data", []string{"ruby/insecure_ftp/with_sensitive_data.rb"}),
newPolicyTest("insecure_ftp_without_sensitive_data", []string{"ruby/insecure_ftp/without_sensitive_data.rb"}),
}

testhelper.RunTests(t, tests)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Insecure FTP

class User
attr_reader :name, :email, :password, :ethnicity
end

## Detected
require "net/ftp"

ftp = Net::FTP::new("ftp.ruby-lang.org")
ftp.login("anonymous", "matz@ruby-lang.org")
ftp.chdir("/pub/ruby")
tgz = ftp.list("ruby-*.tar.gz").sort.last
ftp.getbinaryfile(tgz, tgz)
ftp.close

## Not detected
require "net/sftp"

Net::SFTP.start("localhost", "user") do |sftp|
sftp.upload! "/local/file.tgz", "/remote/file.tgz"
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Insecure FTP

class User
attr_reader :name, :email, :password
end

## Detected
require "net/ftp"

ftp = Net::FTP::new("ftp.ruby-lang.org")
ftp.login("anonymous", "matz@ruby-lang.org")
ftp.chdir("/pub/ruby")
tgz = ftp.list("ruby-*.tar.gz").sort.last
ftp.getbinaryfile(tgz, tgz)
ftp.close

## Not detected
require "net/sftp"

Net::SFTP.start("localhost", "user") do |sftp|
sftp.upload! "/local/file.tgz", "/remote/file.tgz"
end
8 changes: 8 additions & 0 deletions pkg/commands/process/settings/custom_detector.yml
Original file line number Diff line number Diff line change
Expand Up @@ -154,3 +154,11 @@ detect_rails_insecure_communication:
languages:
- ruby
detect_presence: true
detect_rails_insecure_ftp:
type: "risk"
patterns:
- |
Net::FTP::new
languages:
- ruby
detect_presence: true
9 changes: 9 additions & 0 deletions pkg/commands/process/settings/policies.yml
Original file line number Diff line number Diff line change
Expand Up @@ -75,3 +75,12 @@ insecure_communication_processing_sensitive_data:
modules:
- path: policies/insecure_communication.rego
name: bearer.insecure_communication
insecure_ftp_processing_sensitive_data:
description: "Communication with insecure FTP in an application processing sensitive data"
name: "Insecure FTP"
id: "detect_rails_insecure_ftp"
query: |
medium = data.bearer.insecure_ftp.medium
modules:
- path: policies/insecure_ftp.rego
name: bearer.insecure_ftp
28 changes: 28 additions & 0 deletions pkg/commands/process/settings/policies/insecure_ftp.rego
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package bearer.insecure_ftp

import future.keywords

sensitive_data_group_uuid := "f6a0c071-5908-4420-bac2-bba28d41223e"

has_sensitive_data if {
some data_type in input.dataflow.data_types
some data_category in input.data_categories
data_category.uuid == data_type.category_uuid
data_category.group_uuid == sensitive_data_group_uuid
}

medium[item] {
has_sensitive_data == true

some detector in input.dataflow.risks
detector.detector_id == input.policy_id

location = detector.locations[_]
item := {
"category_group": "sensitive data",
"filename": location.filename,
"line_number": location.line_number,
"parent_line_number": location.parent.line_number,
"parent_content": location.parent.content
}
}
18 changes: 18 additions & 0 deletions pkg/detectors/custom/.snapshots/TestInsecureFTPJSON
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
[
{
"type": "custom_risk",
"detector_type": "detect_rails_insecure_ftp",
"source": {
"filename": "config.rb",
"language": "Ruby",
"language_type": "programming",
"line_number": 5,
"column_number": 7,
"text": "Net::FTP::new\n"
},
"value": {
"line_number": 5,
"content": "Net::FTP::new(\"ftp.ruby-lang.org\")"
}
}
]
32 changes: 32 additions & 0 deletions pkg/detectors/custom/custom_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ var configInsecureSMTP []byte
//go:embed testdata/config/insecure_communication.yml
var configInsecureCommunication []byte

//go:embed testdata/config/insecure_ftp.yml
var configInsecureFTP []byte

func TestRailsSessionsJSON(t *testing.T) {
var rulesConfig map[string]settings.Rule

Expand Down Expand Up @@ -304,3 +307,32 @@ func TestInsecureCommunicationJSON(t *testing.T) {

cupaloy.SnapshotT(t, string(bytes))
}

func TestInsecureFTPJSON(t *testing.T) {
var rulesConfig map[string]settings.Rule

detector := custom.New(&nodeid.IntGenerator{Counter: 0})
err := yaml.Unmarshal(configInsecureFTP, &rulesConfig)
if err != nil {
t.Fatal(err)
return
}
customDetector := detector.(*custom.Detector)
err = customDetector.CompileRules(rulesConfig)
if err != nil {
t.Fatal(err)
}

var registrations = []detectors.InitializedDetector{{
Type: detectorType,
Detector: detector}}
detectorReport := testhelper.Extract(t, filepath.Join("testdata", "ruby", "insecure_ftp"), registrations, detectorType)

bytes, err := json.MarshalIndent(detectorReport.CustomDetections, "", " ")

if err != nil {
t.Fatal(err)
}

cupaloy.SnapshotT(t, string(bytes))
}
8 changes: 8 additions & 0 deletions pkg/detectors/custom/testdata/config/insecure_ftp.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
detect_rails_insecure_ftp:
type: "risk"
patterns:
- |
Net::FTP::new
languages:
- ruby
detect_presence: true
17 changes: 17 additions & 0 deletions pkg/detectors/custom/testdata/ruby/insecure_ftp/config.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Insecure FTP
## Detected
require "net/ftp"

ftp = Net::FTP::new("ftp.ruby-lang.org")
ftp.login("anonymous", "matz@ruby-lang.org")
ftp.chdir("/pub/ruby")
tgz = ftp.list("ruby-*.tar.gz").sort.last
ftp.getbinaryfile(tgz, tgz)
ftp.close

## Not detected
require "net/sftp"

Net::SFTP.start("localhost", "user") do |sftp|
sftp.upload! "/local/file.tgz", "/remote/file.tgz"
end

0 comments on commit fcea3bb

Please sign in to comment.