Skip to content

Commit df895ad

Browse files
authored
Access scw links (#60)
This adds support for getting the new [Secure Code Warrior](https://www.securecodewarrior.com/) vulnerability remediation links that were added to the VRT. The mapping portion is maintained within the securecodewarrior API, so the VRT just maintains a flat list of which ids are supported and their respective link. #### Example: ```ruby VRT.find_node( vrt_id: 'server_security_misconfiguration.unsafe_cross_origin_resource_sharing' ).third_party_links[:scw] => "https://integration-api.securecodewarrior.com/api/v1/trial?id=bugcrowd&mappingList=vrt&mappingKey=server_security_misconfiguration:unsafe_cross_origin_resource_sharing&redirect=true" ```
1 parent efffe05 commit df895ad

File tree

11 files changed

+233
-8
lines changed

11 files changed

+233
-8
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p
55

66
## [Unreleased]
77
### Added
8+
- Find the [Secure Code Warrior](https://www.securecodewarrior.com/) remediation training associated with a VRT node
89

910
### Changed
1011

README.md

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,14 +77,15 @@ node.id
7777

7878
node.name
7979

80-
node.mappings
80+
node.mappings # The node's mappings to other classifications
8181
```
8282

83-
### If you need to deal with mappings between versions
83+
### If you need to deal with translating between versions
8484
VRT module also has a `find_node` method that is version agnostic. This is used to find the best
8585
match for a node under any version and has options to specify a preferred version.
8686

8787
#### Examples:
88+
8889
```ruby
8990
# Find a node in a given preferred version that best maps to the given id
9091
VRT.find_node(
@@ -103,3 +104,37 @@ VRT.find_node(
103104
# deprecated ids to the search with `all_matching_categories`
104105
categories_to_search_for += VRT.all_matching_categories(categories_to_search_for)
105106
```
107+
108+
### Mappings and external links
109+
110+
#### Mappings
111+
112+
A mapping is a relationship defined from a node to another classification like cvss or cwe or to
113+
more information like remediation advice. The relationships that are defined in mappings are
114+
maintained by the Bugcrowd team as well as external contributors to the
115+
[VRT repo](https://github.com/bugcrowd/vulnerability-rating-taxonomy/tree/master/mappings).
116+
117+
##### Example getting the CWE for a particular VRT ID
118+
119+
```ruby
120+
VRT.find_node(
121+
vrt_id: 'server_security_misconfiguration.unsafe_cross_origin_resource_sharing'
122+
).mappings[:cwe]
123+
124+
=> ["CWE-942", "CWE-16"]
125+
```
126+
127+
#### Third party links
128+
129+
These are simillar to mappings, but the relationships are maintained by an external party instead of
130+
Bugcrowd.
131+
132+
##### Example getting Secure Code Warrior training link for a particular VRT ID
133+
134+
```ruby
135+
VRT.find_node(
136+
vrt_id: 'server_security_misconfiguration.unsafe_cross_origin_resource_sharing'
137+
).third_party_links[:scw]
138+
139+
=> "https://integration-api.securecodewarrior.com/api/v1/trial?id=bugcrowd&mappingList=vrt&mappingKey=server_security_misconfiguration:unsafe_cross_origin_resource_sharing&redirect=true"
140+
```

lib/vrt.rb

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
require 'vrt/mapping'
88
require 'vrt/cross_version_mapping'
99
require 'vrt/errors'
10+
require 'vrt/third_party_links'
1011

1112
require 'date'
1213
require 'json'
@@ -123,6 +124,12 @@ def mappings
123124
@mappings ||= Hash[MAPPINGS.map { |name| [name, VRT::Mapping.new(name)] }]
124125
end
125126

127+
def third_party_links
128+
@third_party_links ||= {
129+
scw: VRT::ThirdPartyLinks.new('secure-code-warrior-links', 'remediation_training')
130+
}
131+
end
132+
126133
# Cache the VRT contents in-memory, so we're not hitting File I/O multiple times per
127134
# request that needs it.
128135
def reload!
@@ -131,6 +138,7 @@ def reload!
131138
get_json
132139
get_map
133140
last_updated
141+
third_party_links
134142
mappings
135143
end
136144

lib/vrt/mapping.rb

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
1+
# frozen_string_literal: true
2+
13
module VRT
24
class Mapping
3-
def initialize(scheme)
5+
PARENT_DIR = 'mappings'
6+
7+
def initialize(scheme, subdirectory = nil)
48
@scheme = scheme.to_s
9+
@parent_directory = File.join(self.class::PARENT_DIR, (subdirectory || @scheme))
510
load_mappings
611
end
712

@@ -14,9 +19,9 @@ def get(id_list, version)
1419
id_list = VRT.find_node(vrt_id: id_list.join('.'), preferred_version: @min_version).id_list
1520
version = @min_version
1621
end
17-
mapping = @mappings[version]['content']
18-
default = @mappings[version]['metadata']['default']
19-
keys = @mappings[version]['metadata']['keys']
22+
mapping = @mappings.dig(version, 'content') || @mappings[version]
23+
default = @mappings.dig(version, 'metadata', 'default')
24+
keys = @mappings.dig(version, 'metadata', 'keys')
2025
if keys
2126
# Convert mappings with multiple keys to be nested under a single
2227
# top-level key. Remediation advice has keys 'remediation_advice'
@@ -53,11 +58,12 @@ def load_mappings
5358
end
5459

5560
def mapping_file_path(version)
56-
filename = VRT::DIR.join(version, 'mappings', "#{@scheme}.json")
61+
# Supports legacy flat file structure `mappings/cvss.json`
62+
filename = VRT::DIR.join(version, self.class::PARENT_DIR, "#{@scheme}.json")
5763
return filename if File.file?(filename)
5864

5965
# Supports mappings that are nested under their scheme name e.g. `mappings/cvss/cvss.json`
60-
VRT::DIR.join(version, 'mappings', @scheme, "#{@scheme}.json")
66+
VRT::DIR.join(version, @parent_directory, "#{@scheme}.json")
6167
end
6268

6369
# Converts arrays to hashes keyed by the id attribute (as a symbol) for easier lookup. So

lib/vrt/node.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@ def mappings
2727
Hash[VRT.mappings.map { |name, map| [name, map.get(id_list, @version)] }]
2828
end
2929

30+
def third_party_links
31+
Hash[VRT.third_party_links.map { |name, map| [name, map.get(id_list, @version)] }]
32+
end
33+
3034
def id_list
3135
parent ? parent.id_list << id : [id]
3236
end

lib/vrt/third_party_links.rb

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# frozen_string_literal: true
2+
3+
module VRT
4+
class ThirdPartyLinks < Mapping
5+
PARENT_DIR = 'third-party-mappings'
6+
7+
# Example:
8+
# scw = VRT::ThirdPartyLinks.new('secure-code-warrior-links', 'remediation_training')
9+
# scw.get(['automotive_security_misconfiguration', 'can', 'injection_dos'], '1.10.1')
10+
11+
private
12+
13+
def load_mappings
14+
@mappings = {}
15+
VRT.versions.each do |version|
16+
filename = mapping_file_path(version)
17+
next unless File.file?(filename)
18+
19+
mapping = JSON.parse(File.read(filename))
20+
@mappings[version] = mapping
21+
# VRT.versions is sorted in reverse semver order
22+
# so this will end up as the earliest version with a mapping file
23+
@min_version = version
24+
end
25+
raise VRT::Errors::MappingNotFound if @mappings.empty?
26+
end
27+
28+
# For flat third party links ther is no hierarchical step up
29+
def get_key(id_list:, mapping:, key: nil) # rubocop:disable Lint/UnusedMethodArgument
30+
mapping.dig(id_list.join('.'))
31+
end
32+
end
33+
end
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
{
2+
"server_security_misconfiguration": null,
3+
"server_security_misconfiguration.unsafe_cross_origin_resource_sharing": "https://integration-api.securecodewarrior.com/api/v1/trial?id=bugcrowd&mappingList=vrt&mappingKey=server_security_misconfiguration:unsafe_cross_origin_resource_sharing&redirect=true",
4+
"server_security_misconfiguration.path_traversal": "https://integration-api.securecodewarrior.com/api/v1/trial?id=bugcrowd&mappingList=vrt&mappingKey=server_security_misconfiguration:path_traversal&redirect=true",
5+
"server_security_misconfiguration.directory_listing_enabled": null,
6+
"server_security_misconfiguration.directory_listing_enabled.sensitive_data_exposure": "https://integration-api.securecodewarrior.com/api/v1/trial?id=bugcrowd&mappingList=vrt&mappingKey=server_security_misconfiguration:directory_listing_enabled:sensitive_data_exposure&redirect=true",
7+
"server_security_misconfiguration.directory_listing_enabled.non_sensitive_data_exposure": "https://integration-api.securecodewarrior.com/api/v1/trial?id=bugcrowd&mappingList=vrt&mappingKey=server_security_misconfiguration:directory_listing_enabled:non_sensitive_data_exposure&redirect=true",
8+
"server_security_misconfiguration.same_site_scripting": "https://integration-api.securecodewarrior.com/api/v1/trial?id=bugcrowd&mappingList=vrt&mappingKey=server_security_misconfiguration:same_site_scripting&redirect=true",
9+
"server_security_misconfiguration.ssl_attack_breach_poodle_etc": "https://integration-api.securecodewarrior.com/api/v1/trial?id=bugcrowd&mappingList=vrt&mappingKey=server_security_misconfiguration:ssl_attack_breach_poodle_etc&redirect=true",
10+
"server_security_misconfiguration.using_default_credentials": "https://integration-api.securecodewarrior.com/api/v1/trial?id=bugcrowd&mappingList=vrt&mappingKey=server_security_misconfiguration:using_default_credentials&redirect=true",
11+
"server_security_misconfiguration.misconfigured_dns": null,
12+
"server_security_misconfiguration.misconfigured_dns.basic_subdomain_takeover": "https://integration-api.securecodewarrior.com/api/v1/trial?id=bugcrowd&mappingList=vrt&mappingKey=server_security_misconfiguration:misconfigured_dns:basic_subdomain_takeover&redirect=true",
13+
"server_security_misconfiguration.misconfigured_dns.high_impact_subdomain_takeover": "https://integration-api.securecodewarrior.com/api/v1/trial?id=bugcrowd&mappingList=vrt&mappingKey=server_security_misconfiguration:misconfigured_dns:high_impact_subdomain_takeover&redirect=true",
14+
"server_security_misconfiguration.misconfigured_dns.zone_transfer": "https://integration-api.securecodewarrior.com/api/v1/trial?id=bugcrowd&mappingList=vrt&mappingKey=server_security_misconfiguration:misconfigured_dns:zone_transfer&redirect=true",
15+
"server_security_misconfiguration.misconfigured_dns.missing_caa_record": "https://integration-api.securecodewarrior.com/api/v1/trial?id=bugcrowd&mappingList=vrt&mappingKey=server_security_misconfiguration:misconfigured_dns:missing_caa_record&redirect=true",
16+
"server_security_misconfiguration.mail_server_misconfiguration": null,
17+
"server_security_misconfiguration.mail_server_misconfiguration.no_spoofing_protection_on_email_domain": "https://integration-api.securecodewarrior.com/api/v1/trial?id=bugcrowd&mappingList=vrt&mappingKey=server_security_misconfiguration:mail_server_misconfiguration:no_spoofing_protection_on_email_domain&redirect=true",
18+
"server_security_misconfiguration.mail_server_misconfiguration.email_spoofing_to_inbox_due_to_missing_or_misconfigured_dmarc_on_email_domain": "https://integration-api.securecodewarrior.com/api/v1/trial?id=bugcrowd&mappingList=vrt&mappingKey=server_security_misconfiguration:mail_server_misconfiguration:email_spoofing_to_inbox_due_to_missing_or_misconfigured_dmarc_on_email_domain&redirect=true",
19+
"server_security_misconfiguration.mail_server_misconfiguration.email_spoofing_to_spam_folder": "https://integration-api.securecodewarrior.com/api/v1/trial?id=bugcrowd&mappingList=vrt&mappingKey=server_security_misconfiguration:mail_server_misconfiguration:email_spoofing_to_spam_folder&redirect=true",
20+
"server_security_misconfiguration.mail_server_misconfiguration.missing_or_misconfigured_spf_and_or_dkim": "https://integration-api.securecodewarrior.com/api/v1/trial?id=bugcrowd&mappingList=vrt&mappingKey=server_security_misconfiguration:mail_server_misconfiguration:missing_or_misconfigured_spf_and_or_dkim&redirect=true",
21+
"server_security_misconfiguration.mail_server_misconfiguration.email_spoofing_on_non_email_domain": "https://integration-api.securecodewarrior.com/api/v1/trial?id=bugcrowd&mappingList=vrt&mappingKey=server_security_misconfiguration:mail_server_misconfiguration:email_spoofing_on_non_email_domain&redirect=true",
22+
"server_security_misconfiguration.dbms_misconfiguration": null,
23+
"server_security_misconfiguration.dbms_misconfiguration.excessively_privileged_user_dba": "https://integration-api.securecodewarrior.com/api/v1/trial?id=bugcrowd&mappingList=vrt&mappingKey=server_security_misconfiguration:dbms_misconfiguration:excessively_privileged_user_dba&redirect=true",
24+
"server_security_misconfiguration.lack_of_password_confirmation": null,
25+
"server_security_misconfiguration.lack_of_password_confirmation.change_email_address": "https://integration-api.securecodewarrior.com/api/v1/trial?id=bugcrowd&mappingList=vrt&mappingKey=server_security_misconfiguration:lack_of_password_confirmation:change_email_address&redirect=true",
26+
"server_security_misconfiguration.lack_of_password_confirmation.change_password": "https://integration-api.securecodewarrior.com/api/v1/trial?id=bugcrowd&mappingList=vrt&mappingKey=server_security_misconfiguration:lack_of_password_confirmation:change_password&redirect=true",
27+
"server_security_misconfiguration.lack_of_password_confirmation.delete_account": "https://integration-api.securecodewarrior.com/api/v1/trial?id=bugcrowd&mappingList=vrt&mappingKey=server_security_misconfiguration:lack_of_password_confirmation:delete_account&redirect=true",
28+
"server_security_misconfiguration.lack_of_password_confirmation.manage_two_fa": "https://integration-api.securecodewarrior.com/api/v1/trial?id=bugcrowd&mappingList=vrt&mappingKey=server_security_misconfiguration:lack_of_password_confirmation:manage_two_fa&redirect=true",
29+
"server_security_misconfiguration.no_rate_limiting_on_form": null,
30+
"server_security_misconfiguration.no_rate_limiting_on_form.registration": "https://integration-api.securecodewarrior.com/api/v1/trial?id=bugcrowd&mappingList=vrt&mappingKey=server_security_misconfiguration:no_rate_limiting_on_form:registration&redirect=true",
31+
"server_security_misconfiguration.no_rate_limiting_on_form.login": "https://integration-api.securecodewarrior.com/api/v1/trial?id=bugcrowd&mappingList=vrt&mappingKey=server_security_misconfiguration:no_rate_limiting_on_form:login&redirect=true",
32+
"server_security_misconfiguration.no_rate_limiting_on_form.email_triggering": "https://integration-api.securecodewarrior.com/api/v1/trial?id=bugcrowd&mappingList=vrt&mappingKey=server_security_misconfiguration:no_rate_limiting_on_form:email_triggering&redirect=true",
33+
"server_security_misconfiguration.no_rate_limiting_on_form.sms_triggering": "https://integration-api.securecodewarrior.com/api/v1/trial?id=bugcrowd&mappingList=vrt&mappingKey=server_security_misconfiguration:no_rate_limiting_on_form:sms_triggering&redirect=true"
34+
}

0 commit comments

Comments
 (0)