neetob 0.5.16 → 0.5.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.env +4 -0
- data/.neetoci/default.yml +1 -1
- data/.ruby-version +1 -1
- data/Gemfile +1 -1
- data/Gemfile.lock +108 -109
- data/lib/neetob/cli/cloudflare/always_use_https.rb +7 -2
- data/lib/neetob/cli/cloudflare/bot_fight_mode.rb +7 -2
- data/lib/neetob/cli/cloudflare/dns_proxy_status.rb +8 -2
- data/lib/neetob/cli/cloudflare/min_tls_version.rb +8 -2
- data/lib/neetob/cli/cloudflare/ssl_mode.rb +4 -1
- data/lib/neetob/cli/cloudflare/verify_spf.rb +21 -8
- data/lib/neetob/cli/code/audit.rb +19 -7
- data/lib/neetob/cli/cronitor/base.rb +49 -0
- data/lib/neetob/cli/cronitor/get_all_monitors.rb +21 -0
- data/lib/neetob/cli/github/base.rb +3 -2
- data/lib/neetob/cli/github/brakeman.rb +7 -3
- data/lib/neetob/cli/github/bundle_audit.rb +47 -0
- data/lib/neetob/cli/github/make_pr/base.rb +6 -2
- data/lib/neetob/cli/github/repositories/get_security_details.rb +45 -0
- data/lib/neetob/cli/github/repositories/pull_requests.rb +34 -0
- data/lib/neetob/cli/github/yarn_audit.rb +47 -0
- data/lib/neetob/cli/monthly_audit/commands.rb +19 -0
- data/lib/neetob/cli/monthly_audit/databases/main.rb +29 -0
- data/lib/neetob/cli/monthly_audit/databases/users_unique_email_index.rb +40 -0
- data/lib/neetob/cli/monthly_audit/databases/uuid_primary_key.rb +45 -0
- data/lib/neetob/cli/monthly_audit/instances_and_addons/cloudflare/always_use_https_is_enabled.rb +32 -0
- data/lib/neetob/cli/monthly_audit/instances_and_addons/cloudflare/bot_protection_enabled.rb +32 -0
- data/lib/neetob/cli/monthly_audit/instances_and_addons/cloudflare/dns_entry_has_proxy_status.rb +41 -0
- data/lib/neetob/cli/monthly_audit/instances_and_addons/cloudflare/main.rb +38 -0
- data/lib/neetob/cli/monthly_audit/instances_and_addons/cloudflare/minimum_tls_version_is_one_point_two.rb +34 -0
- data/lib/neetob/cli/monthly_audit/instances_and_addons/cloudflare/spf_records_are_valid.rb +41 -0
- data/lib/neetob/cli/monthly_audit/instances_and_addons/cloudflare/ssl_tls_encryption_mode_set_to_full.rb +34 -0
- data/lib/neetob/cli/monthly_audit/instances_and_addons/cronitor/main.rb +29 -0
- data/lib/neetob/cli/monthly_audit/instances_and_addons/cronitor/setup_correctly_for_apps.rb +54 -0
- data/lib/neetob/cli/monthly_audit/instances_and_addons/cronitor/setup_correctly_for_help_center.rb +53 -0
- data/lib/neetob/cli/monthly_audit/instances_and_addons/cronitor/setup_correctly_for_landing_pages.rb +53 -0
- data/lib/neetob/cli/monthly_audit/instances_and_addons/honeybadger/main.rb +23 -0
- data/lib/neetob/cli/monthly_audit/instances_and_addons/honeybadger/setup_correctly_for_apps.rb +49 -0
- data/lib/neetob/cli/monthly_audit/instances_and_addons/main.rb +40 -0
- data/lib/neetob/cli/monthly_audit/instances_and_addons/neeto_deploy/auto_scaling_enabled.rb +46 -0
- data/lib/neetob/cli/monthly_audit/instances_and_addons/neeto_deploy/cloudfront_cdn_enabled.rb +56 -0
- data/lib/neetob/cli/monthly_audit/instances_and_addons/neeto_deploy/essential_environment_variables_set.rb +43 -0
- data/lib/neetob/cli/monthly_audit/instances_and_addons/neeto_deploy/main.rb +35 -0
- data/lib/neetob/cli/monthly_audit/instances_and_addons/neeto_deploy/scheduled_exports_enabled.rb +43 -0
- data/lib/neetob/cli/monthly_audit/instances_and_addons/neeto_deploy/ssl_certificates_over_thirty_days_from_expiry.rb +41 -0
- data/lib/neetob/cli/monthly_audit/misc/main.rb +32 -0
- data/lib/neetob/cli/monthly_audit/misc/redirections_working_correctly.rb +30 -0
- data/lib/neetob/cli/monthly_audit/misc/sparkpost_sub_account_used_for_all_apps.rb +32 -0
- data/lib/neetob/cli/monthly_audit/misc/ssl_certs_setup_for_auto_renewal.rb +29 -0
- data/lib/neetob/cli/monthly_audit/perform.rb +41 -0
- data/lib/neetob/cli/monthly_audit/security/code/brakeman.rb +38 -0
- data/lib/neetob/cli/monthly_audit/security/code/bundle_audit.rb +40 -0
- data/lib/neetob/cli/monthly_audit/security/code/main.rb +29 -0
- data/lib/neetob/cli/monthly_audit/security/code/yarn_audit.rb +44 -0
- data/lib/neetob/cli/monthly_audit/security/github/dependabot_prs_merged.rb +48 -0
- data/lib/neetob/cli/monthly_audit/security/github/dependabot_turned_on.rb +44 -0
- data/lib/neetob/cli/monthly_audit/security/github/main.rb +26 -0
- data/lib/neetob/cli/monthly_audit/security/main.rb +31 -0
- data/lib/neetob/cli/neeto_deploy/autoscaling_config.rb +6 -1
- data/lib/neetob/cli/neeto_deploy/certificates.rb +3 -0
- data/lib/neetob/cli/neeto_deploy/config_vars/list.rb +8 -2
- data/lib/neetob/cli/neeto_deploy/scheduled_exports.rb +6 -1
- data/lib/neetob/cli/redirections/check.rb +13 -3
- data/lib/neetob/cli/sre/base.rb +10 -0
- data/lib/neetob/cli/sre/check_essential_env.rb +18 -3
- data/lib/neetob/cli/ui.rb +43 -3
- data/lib/neetob/cli.rb +4 -0
- data/lib/neetob/version.rb +1 -1
- metadata +48 -5
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Neetob
|
4
|
+
class CLI
|
5
|
+
module MonthlyAudit
|
6
|
+
module InstancesAndAddons
|
7
|
+
module NeetoDeploy
|
8
|
+
class SslCertificatesOverThirtyDaysFromExpiry < CLI::Base
|
9
|
+
def initialize
|
10
|
+
super()
|
11
|
+
end
|
12
|
+
|
13
|
+
def run
|
14
|
+
ui.success "### 3.1.1. Checking whether SSL certificates are over 30 days from expiry"
|
15
|
+
apps_data = [["App", "Certificates status", "Comments", "Audit Passed"]]
|
16
|
+
ui.info("\n", print_to_audit_log: false)
|
17
|
+
Neetob::CLI::Sre::Base::APPS_LIST[:neetodeploy].select { |app| app.include?("production") }.each do |app|
|
18
|
+
ui.info("Checking Certificates status for #{app}", print_to_audit_log: false)
|
19
|
+
certificates_status = Neetob::CLI::NeetoDeploy::Certificates.new(app).run
|
20
|
+
audit_passed = nil
|
21
|
+
comments = nil
|
22
|
+
if certificates_status.is_a?(Hash) && certificates_status["error"] == "Forbidden"
|
23
|
+
audit_passed = "No"
|
24
|
+
comments = "You do not have permission to access the certificates for this app."
|
25
|
+
else
|
26
|
+
audit_passed = certificates_status.any? { |certificate| certificate["expires_before_30_days"] } ? "No" : "Yes"
|
27
|
+
if audit_passed == "No"
|
28
|
+
certificates_failing_audit = certificates_status.select { |certificate| certificate["expires_before_30_days"] }.map { |certificate| certificate["name"] }
|
29
|
+
comments = "Certificates #{certificates_failing_audit.join(", ")} are expiring in less than 30 days."
|
30
|
+
end
|
31
|
+
end
|
32
|
+
apps_data << [app, certificates_status, comments, audit_passed]
|
33
|
+
end
|
34
|
+
ui.print_table(apps_data)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "ssl_certs_setup_for_auto_renewal"
|
4
|
+
require_relative "sparkpost_sub_account_used_for_all_apps"
|
5
|
+
require_relative "redirections_working_correctly"
|
6
|
+
|
7
|
+
module Neetob
|
8
|
+
class CLI
|
9
|
+
module MonthlyAudit
|
10
|
+
module Misc
|
11
|
+
class Main < CLI::Base
|
12
|
+
def initialize
|
13
|
+
super()
|
14
|
+
end
|
15
|
+
|
16
|
+
def run
|
17
|
+
ui.success("# 4. Running miscellaneous checks")
|
18
|
+
ui.info "\n"
|
19
|
+
ui.success("## 4.1. [Manual] Checking whether SSL certs are set up for auto-renewal for all the apps")
|
20
|
+
SslCertsSetupForAutoRenewal.new.run
|
21
|
+
ui.info "\n"
|
22
|
+
ui.success("## 4.2. [Manual] Checking whether we are using Sparkpost sub-account for all the apps")
|
23
|
+
SparkpostSubAccountUsedForAllApps.new.run
|
24
|
+
ui.info "\n"
|
25
|
+
ui.success("## 4.3. Checking whether redirections are set correctly")
|
26
|
+
RedirectionsWorkingCorrectly.new.run
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Neetob
|
4
|
+
class CLI
|
5
|
+
module MonthlyAudit
|
6
|
+
module Misc
|
7
|
+
class RedirectionsWorkingCorrectly < CLI::Base
|
8
|
+
REDIRECTIONS_LIST = [
|
9
|
+
{ source: "https://academy.bigbinary.com", destination: "https://bigbinaryacademy.com" }
|
10
|
+
]
|
11
|
+
def initialize
|
12
|
+
super()
|
13
|
+
end
|
14
|
+
|
15
|
+
def run
|
16
|
+
table_data = [["Source", "Destination", "Status", "Audit passed"]]
|
17
|
+
REDIRECTIONS_LIST.each do |redirection|
|
18
|
+
check = Redirections::Check.new(redirection[:source], redirection[:destination])
|
19
|
+
status = check.run ? "Working" : "Not working"
|
20
|
+
audit_passed = status == "Working" ? "Yes" : "No"
|
21
|
+
|
22
|
+
table_data << [redirection[:source], redirection[:destination], status, audit_passed]
|
23
|
+
end
|
24
|
+
ui.print_table(table_data)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Neetob
|
4
|
+
class CLI
|
5
|
+
module MonthlyAudit
|
6
|
+
module Misc
|
7
|
+
class SparkpostSubAccountUsedForAllApps < CLI::Base
|
8
|
+
def initialize
|
9
|
+
super()
|
10
|
+
end
|
11
|
+
|
12
|
+
def run
|
13
|
+
repo_data = [["App",
|
14
|
+
"SPARKPOST_PASSWORD env variable first 4 characters same as corresponding sub-account in Sparkpost dashboard", "Comments", "Audit Passed"]]
|
15
|
+
ui.info "\n"
|
16
|
+
ui.info "#### Please manually check and add Yes/No for all the following checks:"
|
17
|
+
ui.info "- Get the first 4 characters of the SPARKPOST_PASSWORD environment variable for the app"
|
18
|
+
ui.info "- Go to https://app.sparkpost.com/account/api-keys"
|
19
|
+
ui.info "- Match the first 4 characters against the API keys values"
|
20
|
+
ui.info "- Verify that the API key belongs to the subaccount for same app. Accordingly add Yes/No in the 2nd column"
|
21
|
+
ui.info "- Finally, set Audit Passed as Yes only if the last check passed, otherwise set it as No and add a comment in the Comments column"
|
22
|
+
ui.info "\n"
|
23
|
+
NeetoCompliance::NeetoRepos.products.keys.each do |repo|
|
24
|
+
repo_data << [repo, nil, nil]
|
25
|
+
end
|
26
|
+
ui.print_table(repo_data)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Neetob
|
4
|
+
class CLI
|
5
|
+
module MonthlyAudit
|
6
|
+
module Misc
|
7
|
+
class SslCertsSetupForAutoRenewal < CLI::Base
|
8
|
+
def initialize
|
9
|
+
super()
|
10
|
+
end
|
11
|
+
|
12
|
+
def run
|
13
|
+
domains_data = [["Domain", "Listed on certmanager", "Comments", "Audit Passed"]]
|
14
|
+
ui.info("\n", print_to_audit_log: false)
|
15
|
+
ui.info "#### Please manually check and add Yes/No for all the following checks on https://certmanager.neeto.com for the domains listed in the table below:"
|
16
|
+
ui.info "- Check whether the certificate for the domain is listed on certmanager"
|
17
|
+
ui.info "- Finally, set Audit Passed as Yes only if certificate for the domain is listed, otherwise set it as No, and add a comment in the Comments column"
|
18
|
+
ui.info("\n")
|
19
|
+
Neetob::CLI::Cloudflare::Base::ZONE_IDS.keys.select { |domain|
|
20
|
+
domain.to_s.include?(".com") }.map do |domain|
|
21
|
+
domains_data << [domain, nil, nil, nil]
|
22
|
+
end
|
23
|
+
ui.print_table(domains_data)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "security/main"
|
4
|
+
require_relative "databases/main"
|
5
|
+
require_relative "instances_and_addons/main"
|
6
|
+
require_relative "misc/main"
|
7
|
+
|
8
|
+
module Neetob
|
9
|
+
class CLI
|
10
|
+
module MonthlyAudit
|
11
|
+
class Perform < CLI::Base
|
12
|
+
attr_accessor :sandbox, :month
|
13
|
+
|
14
|
+
def initialize(month, sandbox = false)
|
15
|
+
super()
|
16
|
+
@month = month
|
17
|
+
@sandbox = sandbox
|
18
|
+
end
|
19
|
+
|
20
|
+
def run
|
21
|
+
Thread.current[:audit_mode] = true
|
22
|
+
markdown_file_name = "audit-report-#{DateTime.now.to_i}.md"
|
23
|
+
Thread.current[:markdown_file_name] = markdown_file_name
|
24
|
+
ui.success("## Starting the audit for #{month}")
|
25
|
+
ui.info "\n"
|
26
|
+
Security::Main.new.run
|
27
|
+
ui.info "\n"
|
28
|
+
Databases::Main.new.run
|
29
|
+
ui.info "\n"
|
30
|
+
InstancesAndAddons::Main.new.run
|
31
|
+
ui.info "\n"
|
32
|
+
Misc::Main.new.run
|
33
|
+
ui.info "\n"
|
34
|
+
ui.success("## Audit for #{month} completed successfully.")
|
35
|
+
ui.success("## Audit report is written to #{markdown_file_name}")
|
36
|
+
ui.success("## Please update the manual audit part and post the audit in Github.")
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Neetob
|
4
|
+
class CLI
|
5
|
+
module MonthlyAudit
|
6
|
+
module Security
|
7
|
+
module Code
|
8
|
+
class Brakeman < CLI::Base
|
9
|
+
def initialize
|
10
|
+
super()
|
11
|
+
end
|
12
|
+
|
13
|
+
def run
|
14
|
+
ui.success("### 1.1.3. Checking whether running `bundle exec brakeman` throws any vulnerabilities")
|
15
|
+
repo_data = [["Repository", "Vulnerabilities Found", "Comments", "Audit Passed"]]
|
16
|
+
ui.info "\n"
|
17
|
+
NeetoCompliance::NeetoRepos.products.keys.each do |repo|
|
18
|
+
ui.info("Checking Brakeman run results for #{repo}", print_to_audit_log: false)
|
19
|
+
brakeman_run_result = Neetob::CLI::Github::Brakeman.new([repo]).run
|
20
|
+
vulnerabilities_found = "No"
|
21
|
+
audit_passed = "No"
|
22
|
+
comments = nil
|
23
|
+
if brakeman_run_result && brakeman_run_result.include?("No warnings found")
|
24
|
+
audit_passed = "Yes"
|
25
|
+
else
|
26
|
+
vulnerabilities_found = "Yes"
|
27
|
+
comments = brakeman_run_result.gsub("\n", "<br>")
|
28
|
+
end
|
29
|
+
repo_data << [repo, vulnerabilities_found, comments, audit_passed]
|
30
|
+
end
|
31
|
+
ui.print_table(repo_data)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "../../../github/bundle_audit"
|
4
|
+
|
5
|
+
module Neetob
|
6
|
+
class CLI
|
7
|
+
module MonthlyAudit
|
8
|
+
module Security
|
9
|
+
module Code
|
10
|
+
class BundleAudit < CLI::Base
|
11
|
+
def initialize
|
12
|
+
super()
|
13
|
+
end
|
14
|
+
|
15
|
+
def run
|
16
|
+
ui.success("### 1.1.1. Checking whether running `bundle-audit check` throws any vulnerabilities")
|
17
|
+
repo_data = [["Repository", "Vulnerabilities Found", "Comments", "Audit Passed"]]
|
18
|
+
ui.info "\n"
|
19
|
+
NeetoCompliance::NeetoRepos.products.keys.each do |repo|
|
20
|
+
ui.info("Checking bundle audit run results for #{repo}", print_to_audit_log: false)
|
21
|
+
bundle_audit_result = Neetob::CLI::Github::BundleAudit.new([repo]).run
|
22
|
+
vulnerabilities_found = "No"
|
23
|
+
audit_passed = "No"
|
24
|
+
comments = nil
|
25
|
+
if bundle_audit_result && bundle_audit_result.include?("No vulnerabilities found")
|
26
|
+
audit_passed = "Yes"
|
27
|
+
else
|
28
|
+
vulnerabilities_found = "Yes"
|
29
|
+
comments = bundle_audit_result.gsub("\n", "<br>")
|
30
|
+
end
|
31
|
+
repo_data << [repo, vulnerabilities_found, comments, audit_passed]
|
32
|
+
end
|
33
|
+
ui.print_table(repo_data)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "bundle_audit"
|
4
|
+
require_relative "yarn_audit"
|
5
|
+
require_relative "brakeman"
|
6
|
+
|
7
|
+
module Neetob
|
8
|
+
class CLI
|
9
|
+
module MonthlyAudit
|
10
|
+
module Security
|
11
|
+
module Code
|
12
|
+
class Main < CLI::Base
|
13
|
+
def initialize
|
14
|
+
super()
|
15
|
+
end
|
16
|
+
|
17
|
+
def run
|
18
|
+
BundleAudit.new.run
|
19
|
+
ui.info "\n"
|
20
|
+
YarnAudit.new.run
|
21
|
+
ui.info "\n"
|
22
|
+
Brakeman.new.run
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "../../../github/yarn_audit"
|
4
|
+
|
5
|
+
module Neetob
|
6
|
+
class CLI
|
7
|
+
module MonthlyAudit
|
8
|
+
module Security
|
9
|
+
module Code
|
10
|
+
class YarnAudit < CLI::Base
|
11
|
+
def initialize
|
12
|
+
super()
|
13
|
+
end
|
14
|
+
|
15
|
+
def run
|
16
|
+
ui.success("### 1.1.2. Checking whether running `yarn audit` throws any vulnerabilities")
|
17
|
+
repo_data = [["Repository", "Vulnerabilities Found", "Comments", "Audit Passed"]]
|
18
|
+
ui.info "\n"
|
19
|
+
NeetoCompliance::NeetoRepos.products.keys.each do |repo|
|
20
|
+
ui.info("Checking yarn audit run results for #{repo}", print_to_audit_log: false)
|
21
|
+
yarn_audit_result = Neetob::CLI::Github::YarnAudit.new([repo]).run
|
22
|
+
vulnerabilities_found = "No"
|
23
|
+
audit_passed = "No"
|
24
|
+
comments = nil
|
25
|
+
if yarn_audit_result && yarn_audit_result.include?("0 vulnerabilities found")
|
26
|
+
audit_passed = "Yes"
|
27
|
+
else
|
28
|
+
vulnerabilities_found = "Yes"
|
29
|
+
vulnerabilities = yarn_audit_result.split("\n").select { |line|
|
30
|
+
line.include?("vulnerabilities found") }.first.strip
|
31
|
+
severity = yarn_audit_result.split("\n").select { |line|
|
32
|
+
line.include?("Severity:") }.first.strip.gsub("|", ",")
|
33
|
+
comments = "#{vulnerabilities}<br>#{severity}"
|
34
|
+
end
|
35
|
+
repo_data << [repo, vulnerabilities_found, comments, audit_passed]
|
36
|
+
end
|
37
|
+
ui.print_table(repo_data)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "../../../github/repositories/pull_requests"
|
4
|
+
|
5
|
+
module Neetob
|
6
|
+
class CLI
|
7
|
+
module MonthlyAudit
|
8
|
+
module Security
|
9
|
+
module Github
|
10
|
+
class DependabotPrsMerged < CLI::Base
|
11
|
+
def initialize
|
12
|
+
super()
|
13
|
+
end
|
14
|
+
|
15
|
+
def run
|
16
|
+
ui.success("### 1.2.2. Checking whether all dependabot PRs created before 2 days have been merged")
|
17
|
+
ui.info "\n"
|
18
|
+
|
19
|
+
repo_data = [[
|
20
|
+
"Repository",
|
21
|
+
"All dependabot PRs older than 2 days have been merged",
|
22
|
+
"Comments",
|
23
|
+
"Audit Passed"
|
24
|
+
]
|
25
|
+
]
|
26
|
+
NeetoCompliance::NeetoRepos.products.keys.each do |repo|
|
27
|
+
ui.info "Checking #{repo}...", print_to_audit_log: false
|
28
|
+
pull_requests = Neetob::CLI::Github::Repositories::PullRequests.new([repo]).run[0]
|
29
|
+
dependabot_prs = pull_requests.select { |pr| pr[:user][:login] == "dependabot[bot]" }
|
30
|
+
dependabot_prs_older_than_2_days = dependabot_prs.select { |pr| pr[:created_at] < 2.days.ago }
|
31
|
+
dependabot_prs_older_than_2_days_merged = "No"
|
32
|
+
audit_passed = "No"
|
33
|
+
comments = nil
|
34
|
+
if dependabot_prs_older_than_2_days.empty?
|
35
|
+
audit_passed = dependabot_prs_older_than_2_days_merged = "Yes"
|
36
|
+
else
|
37
|
+
comments = "PRs older than 2 days: #{dependabot_prs_older_than_2_days.map { |pr| pr[:number] }.join(', ')}"
|
38
|
+
end
|
39
|
+
repo_data << [repo, dependabot_prs_older_than_2_days_merged, comments, audit_passed]
|
40
|
+
end
|
41
|
+
ui.print_table(repo_data)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "../../../github/repositories/get_security_details.rb"
|
4
|
+
|
5
|
+
module Neetob
|
6
|
+
class CLI
|
7
|
+
module MonthlyAudit
|
8
|
+
module Security
|
9
|
+
module Github
|
10
|
+
class DependabotTurnedOn < CLI::Base
|
11
|
+
def initialize
|
12
|
+
super()
|
13
|
+
end
|
14
|
+
|
15
|
+
def run
|
16
|
+
ui.success("### 1.2.1. [Manual] Checking whether dependabot is turned on for the repository")
|
17
|
+
ui.info "\n"
|
18
|
+
ui.info "#### Please manually check and add Yes/No for all the following checks on the Honeybadger dashboard for the apps listed in the table below:"
|
19
|
+
ui.info "- Repository > Settings > Code security > Dependabot alerts are enabled"
|
20
|
+
ui.info "- Repository > Settings > Code security > Dependabot security updates are enabled"
|
21
|
+
ui.info "- Repository > Settings > Actions > Dependabot on Actions runners is enabled"
|
22
|
+
ui.info "- Finally, set Audit Passed as Yes only if all the checks are passed for the app, otherwise set it as No, and add a comment in the Comments column"
|
23
|
+
ui.info "\n"
|
24
|
+
|
25
|
+
repo_data = [[
|
26
|
+
"Repository",
|
27
|
+
"Dependabot alerts enabled",
|
28
|
+
"Dependabot security updates enabled",
|
29
|
+
"Dependabot on Actions runners",
|
30
|
+
"Comments",
|
31
|
+
"Audit Passed"
|
32
|
+
]
|
33
|
+
]
|
34
|
+
NeetoCompliance::NeetoRepos.products.keys.each do |repo|
|
35
|
+
repo_data << [repo, nil, nil, nil, nil]
|
36
|
+
end
|
37
|
+
ui.print_table(repo_data)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "dependabot_turned_on"
|
4
|
+
require_relative "dependabot_prs_merged"
|
5
|
+
|
6
|
+
module Neetob
|
7
|
+
class CLI
|
8
|
+
module MonthlyAudit
|
9
|
+
module Security
|
10
|
+
module Github
|
11
|
+
class Main < CLI::Base
|
12
|
+
def initialize
|
13
|
+
super()
|
14
|
+
end
|
15
|
+
|
16
|
+
def run
|
17
|
+
DependabotTurnedOn.new.run
|
18
|
+
ui.info "\n"
|
19
|
+
DependabotPrsMerged.new.run
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "code/main"
|
4
|
+
require_relative "github/main"
|
5
|
+
|
6
|
+
module Neetob
|
7
|
+
class CLI
|
8
|
+
module MonthlyAudit
|
9
|
+
module Security
|
10
|
+
class Main < CLI::Base
|
11
|
+
def initialize
|
12
|
+
super()
|
13
|
+
end
|
14
|
+
|
15
|
+
def run
|
16
|
+
ui.success("# 1. Running security audit")
|
17
|
+
ui.info "\n"
|
18
|
+
ui.success("## 1.1. Checking code for security vulnerabilities")
|
19
|
+
ui.info "\n"
|
20
|
+
Code::Main.new.run
|
21
|
+
ui.info "\n"
|
22
|
+
ui.success("## 1.2. Checking github repos for security vulnerabilities")
|
23
|
+
ui.info "\n"
|
24
|
+
Github::Main.new.run
|
25
|
+
ui.info "\n"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -12,7 +12,12 @@ module Neetob
|
|
12
12
|
end
|
13
13
|
|
14
14
|
def run
|
15
|
-
|
15
|
+
result = `neetodeploy autoscaling_config list -a #{app}`
|
16
|
+
if Thread.current[:audit_mode]
|
17
|
+
JSON.parse(result) rescue result
|
18
|
+
else
|
19
|
+
ui.success(result)
|
20
|
+
end
|
16
21
|
end
|
17
22
|
end
|
18
23
|
end
|
@@ -18,6 +18,9 @@ module Neetob
|
|
18
18
|
parseable_result = certificates_command_result.strip.gsub("=>", ":")
|
19
19
|
|
20
20
|
parsed_certificates_result = JSON.parse(parseable_result)
|
21
|
+
|
22
|
+
return parsed_certificates_result if Thread.current[:audit_mode]
|
23
|
+
|
21
24
|
if parsed_certificates_result.empty?
|
22
25
|
ui.error("No certificates found for the app with name \"#{app}\".")
|
23
26
|
else
|
@@ -17,9 +17,15 @@ module Neetob
|
|
17
17
|
|
18
18
|
def run
|
19
19
|
matching_apps = find_all_matching_apps_or_repos(apps, :neetodeploy, sandbox)
|
20
|
+
results = []
|
20
21
|
matching_apps.each do |app|
|
21
|
-
ui.info("\nConfig of #{app}\n")
|
22
|
-
|
22
|
+
ui.info("\nConfig of #{app}\n") unless Thread.current[:audit_mode]
|
23
|
+
result = `neetodeploy env list -a #{app}`
|
24
|
+
results << result
|
25
|
+
ui.success(result) unless Thread.current[:audit_mode]
|
26
|
+
end
|
27
|
+
if Thread.current[:audit_mode]
|
28
|
+
results
|
23
29
|
end
|
24
30
|
end
|
25
31
|
end
|
@@ -12,7 +12,12 @@ module Neetob
|
|
12
12
|
end
|
13
13
|
|
14
14
|
def run
|
15
|
-
|
15
|
+
result = `neetodeploy addon scheduled_exports_enabled -a #{app}`
|
16
|
+
if Thread.current[:audit_mode]
|
17
|
+
result
|
18
|
+
else
|
19
|
+
ui.success(result)
|
20
|
+
end
|
16
21
|
end
|
17
22
|
end
|
18
23
|
end
|
@@ -21,12 +21,22 @@ module Neetob
|
|
21
21
|
|
22
22
|
if response.code.in? %w(301 302 308)
|
23
23
|
if response["location"].chomp("/") == destination.chomp("/")
|
24
|
-
ui.success(
|
24
|
+
ui.success(
|
25
|
+
"The redirection from #{source} to #{destination} is working properly.",
|
26
|
+
print_to_audit_log: false)
|
25
27
|
else
|
26
|
-
ui.error(
|
28
|
+
ui.error(
|
29
|
+
"The redirection from #{source} to #{destination} is not working properly.",
|
30
|
+
print_to_audit_log: false)
|
27
31
|
end
|
28
32
|
else
|
29
|
-
ui.error(
|
33
|
+
ui.error(
|
34
|
+
"The redirection from #{source} to #{destination} is not working properly.",
|
35
|
+
print_to_audit_log: false)
|
36
|
+
end
|
37
|
+
|
38
|
+
if Thread.current[:audit_mode]
|
39
|
+
response.code.in?(%w(301 302 308)) && (response["location"].chomp("/") == destination.chomp("/"))
|
30
40
|
end
|
31
41
|
end
|
32
42
|
end
|
data/lib/neetob/cli/sre/base.rb
CHANGED
@@ -291,6 +291,16 @@ module Neetob
|
|
291
291
|
dns: "neetoengage.com",
|
292
292
|
app: "neeto-engage-web-production"
|
293
293
|
}
|
294
|
+
},
|
295
|
+
"NeetoPlaydash": {
|
296
|
+
"staging": {
|
297
|
+
dns: "neetoplaydash.net",
|
298
|
+
app: "neeto-playdash-web-staging"
|
299
|
+
},
|
300
|
+
"production": {
|
301
|
+
dns: "neetoplaydash.com",
|
302
|
+
app: "neeto-playdash-web-production"
|
303
|
+
}
|
294
304
|
}
|
295
305
|
}
|
296
306
|
|
@@ -59,6 +59,15 @@ module Neetob
|
|
59
59
|
# TODO: Optimize once github.com/bigbinary/neeto-deploy-web/issues/3745 is done
|
60
60
|
begin
|
61
61
|
env_table = `neetodeploy env list -a #{app}`
|
62
|
+
json_parse_result = JSON.parse(env_table) rescue nil
|
63
|
+
if json_parse_result && json_parse_result["error"] == "Forbidden"
|
64
|
+
if Thread.current[:audit_mode]
|
65
|
+
return json_parse_result
|
66
|
+
else
|
67
|
+
ui.error("You do not have permission to access the config vars for this app.")
|
68
|
+
return
|
69
|
+
end
|
70
|
+
end
|
62
71
|
envs = {}
|
63
72
|
env_table.each_line do |line|
|
64
73
|
match = line.match(/^\| (\w+) +\| (.+?) +\|$/)
|
@@ -67,15 +76,21 @@ module Neetob
|
|
67
76
|
required_keys = REQUIRED_KEYS + REQUIRED_KEYS_NEETODEPLOY
|
68
77
|
compare_envs(required_keys, envs, app)
|
69
78
|
rescue => exception
|
79
|
+
binding.pry
|
70
80
|
ui.error(exception.message)
|
71
81
|
end
|
72
82
|
end
|
73
83
|
|
74
84
|
def compare_envs(required_keys, envs, app)
|
75
85
|
all_keys_present = required_keys.all? { |key| envs.has_key?(key) }
|
76
|
-
all_keys_present
|
77
|
-
|
78
|
-
|
86
|
+
result = { all_keys_present:, missing_keys: required_keys - envs.keys }
|
87
|
+
if Thread.current[:audit_mode]
|
88
|
+
result
|
89
|
+
else
|
90
|
+
all_keys_present ?
|
91
|
+
ui.success("#{app} has all required envs") :
|
92
|
+
ui.error("#{app} doesn't have all required envs. Missing #{required_keys - envs.keys}")
|
93
|
+
end
|
79
94
|
end
|
80
95
|
end
|
81
96
|
end
|