diff --git a/CHANGELOG b/CHANGELOG
index 0224a0ed7..2f669dcd0 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,4 +1,4 @@
-[v#.#.#] ([month] [YYYY])
+v4.15.0 (December 2024)
- Tags: Add custom ordering
- Welcome Kit:
- Add HTML report template
@@ -6,28 +6,10 @@
- Update OWASP Top 10 methodology to latest version (2021)
- Upgraded gems:
- rails, rexml
- - Bugs fixes:
- - [entity]:
- - [future tense verb] [bug fix]
- - Bug tracker items:
- - [item]
- - New integrations:
- - [integration]
- - Integration enhancements:
- - [integration]:
- - [future tense verb] [integration enhancement]
- - [integration bug fixes]:
- - [future tense verb] [integration bug fix]
- - Reporting enhancements:
- - [report type]:
- - [future tense verb] [reporting enhancement]
- - REST/JSON API enhancements:
- - [API entity]:
- - [future tense verb] [API enhancement]
+ - Integration enhancements:
+ - Qualys: Add `cvss3_base`, `cvss3_temporal`, and `cvss3_version` as available vuln fields
- Security Fixes:
- - High: (Authenticated|Unauthenticated) (admin|author|contributor) [vulnerability description]
- - Medium: (Authenticated|Unauthenticated) (admin|author|contributor) [vulnerability description]
- - Low: (Authenticated|Unauthenticated) (admin|author|contributor) [vulnerability description]
+ - High: Authenticated (author) persistent cross-site scripting
v4.14.0 (October 2024)
- Kit Import: Use file name sequencing when a template file with the same name exists
diff --git a/Gemfile b/Gemfile
index ac479684f..d7332b46c 100644
--- a/Gemfile
+++ b/Gemfile
@@ -216,12 +216,12 @@ end
#
# Base framework classes required by other plugins
-gem 'dradis-plugins', '~> 4.14.0'
+gem 'dradis-plugins', '~> 4.15.0'
gem 'dradis-api', path: 'engines/dradis-api'
# Import / export project data
-gem 'dradis-projects', '~> 4.14.0'
+gem 'dradis-projects', '~> 4.15.0'
plugins_file = 'Gemfile.plugins'
if File.exists?(plugins_file)
@@ -233,33 +233,33 @@ end
# ----------------------------------------------------------------- Calculators
-gem 'dradis-calculator_cvss', '~> 4.14.0'
-gem 'dradis-calculator_dread', '~> 4.14.0'
+gem 'dradis-calculator_cvss', '~> 4.15.0'
+gem 'dradis-calculator_dread', '~> 4.15.0'
# ---------------------------------------------------------------------- Export
-gem 'dradis-csv_export', '~> 4.14.0'
-gem 'dradis-html_export', '~> 4.14.0'
+gem 'dradis-csv_export', '~> 4.15.0'
+gem 'dradis-html_export', '~> 4.15.0'
# ---------------------------------------------------------------------- Import
-gem 'dradis-csv', '~> 4.14.0'
+gem 'dradis-csv', '~> 4.15.0'
# ---------------------------------------------------------------------- Upload
-gem 'dradis-acunetix', '~> 4.14.0'
-gem 'dradis-brakeman', '~> 4.14.0'
-gem 'dradis-burp', '~> 4.14.0'
-gem 'dradis-coreimpact', '~> 4.14.0'
-gem 'dradis-metasploit', '~> 4.14.0'
-gem 'dradis-nessus', '~> 4.14.0'
-gem 'dradis-netsparker', '~> 4.14.0'
-gem 'dradis-nexpose', '~> 4.14.0'
-gem 'dradis-nikto', '~> 4.14.0'
-gem 'dradis-nipper', '~> 4.14.0'
-gem 'dradis-nmap', '~> 4.14.0'
-gem 'dradis-ntospider', '~> 4.14.0'
-gem 'dradis-openvas', '~> 4.14.0'
-gem 'dradis-pentera', '~> 4.14.0'
-gem 'dradis-qualys', '~> 4.14.0'
-gem 'dradis-saint', '~> 4.14.0'
-gem 'dradis-veracode', '~> 4.14.0'
-gem 'dradis-wpscan', '~> 4.14.0'
-gem 'dradis-zap', '~> 4.14.0'
+gem 'dradis-acunetix', '~> 4.15.0'
+gem 'dradis-brakeman', '~> 4.15.0'
+gem 'dradis-burp', '~> 4.15.0'
+gem 'dradis-coreimpact', '~> 4.15.0'
+gem 'dradis-metasploit', '~> 4.15.0'
+gem 'dradis-nessus', '~> 4.15.0'
+gem 'dradis-netsparker', '~> 4.15.0'
+gem 'dradis-nexpose', '~> 4.15.0'
+gem 'dradis-nikto', '~> 4.15.0'
+gem 'dradis-nipper', '~> 4.15.0'
+gem 'dradis-nmap', '~> 4.15.0'
+gem 'dradis-ntospider', '~> 4.15.0'
+gem 'dradis-openvas', '~> 4.15.0'
+gem 'dradis-pentera', '~> 4.15.0'
+gem 'dradis-qualys', '~> 4.15.0'
+gem 'dradis-saint', '~> 4.15.0'
+gem 'dradis-veracode', '~> 4.15.0'
+gem 'dradis-wpscan', '~> 4.15.0'
+gem 'dradis-zap', '~> 4.15.0'
diff --git a/Gemfile.lock b/Gemfile.lock
index 666560776..8095ebcf1 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -1,7 +1,7 @@
PATH
remote: engines/dradis-api
specs:
- dradis-api (4.14.0)
+ dradis-api (4.15.0)
jbuilder
GEM
@@ -127,73 +127,73 @@ GEM
date (3.3.4)
diff-lcs (1.5.0)
differ (0.1.2)
- dradis-acunetix (4.14.0)
+ dradis-acunetix (4.15.0)
dradis-plugins (~> 4.0)
nokogiri (~> 1.3)
- dradis-brakeman (4.14.0)
+ dradis-brakeman (4.15.0)
dradis-plugins (~> 4.0)
- dradis-burp (4.14.0)
+ dradis-burp (4.15.0)
dradis-plugins (~> 4.0)
nokogiri (~> 1.3)
- dradis-calculator_cvss (4.14.0)
+ dradis-calculator_cvss (4.15.0)
dradis-plugins (~> 4.0)
- dradis-calculator_dread (4.14.0)
+ dradis-calculator_dread (4.15.0)
dradis-plugins (~> 4.0)
- dradis-coreimpact (4.14.0)
+ dradis-coreimpact (4.15.0)
dradis-plugins (~> 4.0)
- dradis-csv (4.14.0)
+ dradis-csv (4.15.0)
dradis-plugins (~> 4.0)
- dradis-csv_export (4.14.0)
+ dradis-csv_export (4.15.0)
dradis-plugins (>= 4.8.0)
- dradis-html_export (4.14.0)
+ dradis-html_export (4.15.0)
RedCloth (~> 4.3.2)
dradis-plugins (>= 4.8.0)
rails_autolink (~> 1.1)
- dradis-metasploit (4.14.0)
+ dradis-metasploit (4.15.0)
dradis-plugins (~> 4.0)
nokogiri (~> 1.3)
- dradis-nessus (4.14.0)
+ dradis-nessus (4.15.0)
dradis-plugins (~> 4.0)
nokogiri
- dradis-netsparker (4.14.0)
+ dradis-netsparker (4.15.0)
dradis-plugins (~> 4.0)
nokogiri (>= 1.12.5)
- dradis-nexpose (4.14.0)
+ dradis-nexpose (4.15.0)
dradis-plugins (~> 4.0)
nokogiri (~> 1.3)
- dradis-nikto (4.14.0)
+ dradis-nikto (4.15.0)
dradis-plugins (~> 4.0)
nokogiri (~> 1.3)
- dradis-nipper (4.14.0)
+ dradis-nipper (4.15.0)
dradis-plugins (~> 4.0)
- dradis-nmap (4.14.0)
+ dradis-nmap (4.15.0)
dradis-plugins (~> 4.0)
ruby-nmap (~> 0.7)
- dradis-ntospider (4.14.0)
+ dradis-ntospider (4.15.0)
dradis-plugins (~> 4.0)
- dradis-openvas (4.14.0)
+ dradis-openvas (4.15.0)
dradis-plugins (~> 4.0)
- dradis-pentera (4.14.0)
+ dradis-pentera (4.15.0)
dradis-plugins (~> 4.0)
- dradis-plugins (4.14.0)
- dradis-projects (4.14.0)
+ dradis-plugins (4.15.0)
+ dradis-projects (4.15.0)
dradis-plugins (>= 4.8.0)
rubyzip
- dradis-qualys (4.14.0)
+ dradis-qualys (4.15.1)
dradis-plugins (~> 4.0)
nokogiri (~> 1.3)
- dradis-saint (4.14.0)
+ dradis-saint (4.15.0)
combustion (~> 0.6.0)
dradis-plugins (~> 4.0)
nokogiri
rake (~> 13.0)
rspec-rails
- dradis-veracode (4.14.0)
+ dradis-veracode (4.15.0)
dradis-plugins (~> 4.0)
- dradis-wpscan (4.14.0)
+ dradis-wpscan (4.15.0)
dradis-plugins (~> 4.0)
multi_json
- dradis-zap (4.14.0)
+ dradis-zap (4.15.0)
dradis-plugins (~> 4.0)
nokogiri (~> 1.3)
erubi (1.13.0)
@@ -530,33 +530,33 @@ DEPENDENCIES
coffee-rails (~> 5.0)
database_cleaner
differ (~> 0.1.2)
- dradis-acunetix (~> 4.14.0)
+ dradis-acunetix (~> 4.15.0)
dradis-api!
- dradis-brakeman (~> 4.14.0)
- dradis-burp (~> 4.14.0)
- dradis-calculator_cvss (~> 4.14.0)
- dradis-calculator_dread (~> 4.14.0)
- dradis-coreimpact (~> 4.14.0)
- dradis-csv (~> 4.14.0)
- dradis-csv_export (~> 4.14.0)
- dradis-html_export (~> 4.14.0)
- dradis-metasploit (~> 4.14.0)
- dradis-nessus (~> 4.14.0)
- dradis-netsparker (~> 4.14.0)
- dradis-nexpose (~> 4.14.0)
- dradis-nikto (~> 4.14.0)
- dradis-nipper (~> 4.14.0)
- dradis-nmap (~> 4.14.0)
- dradis-ntospider (~> 4.14.0)
- dradis-openvas (~> 4.14.0)
- dradis-pentera (~> 4.14.0)
- dradis-plugins (~> 4.14.0)
- dradis-projects (~> 4.14.0)
- dradis-qualys (~> 4.14.0)
- dradis-saint (~> 4.14.0)
- dradis-veracode (~> 4.14.0)
- dradis-wpscan (~> 4.14.0)
- dradis-zap (~> 4.14.0)
+ dradis-brakeman (~> 4.15.0)
+ dradis-burp (~> 4.15.0)
+ dradis-calculator_cvss (~> 4.15.0)
+ dradis-calculator_dread (~> 4.15.0)
+ dradis-coreimpact (~> 4.15.0)
+ dradis-csv (~> 4.15.0)
+ dradis-csv_export (~> 4.15.0)
+ dradis-html_export (~> 4.15.0)
+ dradis-metasploit (~> 4.15.0)
+ dradis-nessus (~> 4.15.0)
+ dradis-netsparker (~> 4.15.0)
+ dradis-nexpose (~> 4.15.0)
+ dradis-nikto (~> 4.15.0)
+ dradis-nipper (~> 4.15.0)
+ dradis-nmap (~> 4.15.0)
+ dradis-ntospider (~> 4.15.0)
+ dradis-openvas (~> 4.15.0)
+ dradis-pentera (~> 4.15.0)
+ dradis-plugins (~> 4.15.0)
+ dradis-projects (~> 4.15.0)
+ dradis-qualys (~> 4.15.0)
+ dradis-saint (~> 4.15.0)
+ dradis-veracode (~> 4.15.0)
+ dradis-wpscan (~> 4.15.0)
+ dradis-zap (~> 4.15.0)
factory_bot_rails
font-awesome-sass (~> 6.4.0)
foreman
diff --git a/app/assets/javascripts/shared/differ.js b/app/assets/javascripts/shared/differ.js
new file mode 100644
index 000000000..8bd02dd9d
--- /dev/null
+++ b/app/assets/javascripts/shared/differ.js
@@ -0,0 +1,37 @@
+class Differ {
+ constructor() {
+ this.delRegex = /\[31m([\s\S]*?)\[0m/g;
+ this.insRegex = /\[32m([\s\S]*?)\[0m/g;
+ }
+
+ ansiToHTML(text) {
+ return text
+ .replace(this.delRegex, '$1')
+ .replace(this.insRegex, '$1');
+ }
+
+ highlightString(text, diffType) {
+ if (diffType === 'del') {
+ return text
+ .replace(this.delRegex, '$1')
+ .replace(this.insRegex, '');
+ }
+ else if (diffType === 'ins') {
+ return text
+ .replace(this.insRegex, '$1')
+ .replace(this.delRegex, '');
+ }
+ else {
+ console.log('Invalid diffType!');
+ }
+ }
+}
+
+document.addEventListener('turbolinks:load', function() {
+ if ($('.js-diff-body').length) {
+ let differ = new Differ(),
+ content = $('.js-diff-body').html();
+
+ $('.js-diff-body').html(differ.ansiToHTML(content));
+ }
+});
diff --git a/app/assets/javascripts/shared/revisions.js.coffee b/app/assets/javascripts/shared/revisions.js.coffee
deleted file mode 100644
index 692424d1b..000000000
--- a/app/assets/javascripts/shared/revisions.js.coffee
+++ /dev/null
@@ -1,14 +0,0 @@
-document.addEventListener "turbolinks:load", ->
-
- if $('.js-diff-body').length
- delRegex = /\[31m([\s\S]*?)\[0m/g
- insRegex = /\[32m([\s\S]*?)\[0m/g
-
- diffText = $('.js-diff-body').html()
-
- newText =
- diffText.
- replace(delRegex, '$1').
- replace(insRegex, '$1')
-
- $('.js-diff-body').html(newText)
diff --git a/app/assets/javascripts/tylium.js b/app/assets/javascripts/tylium.js
index 8675ededf..8a78b8b2e 100644
--- a/app/assets/javascripts/tylium.js
+++ b/app/assets/javascripts/tylium.js
@@ -21,11 +21,11 @@
//= require shared/charts
//= require shared/comments
//= require shared/console_updater
+//= require shared/differ
//= require shared/editor_toolbar
//= require shared/quote_selector
//= require shared/mentions
//= require shared/notifications
-//= require shared/revisions
//= require shared/rtp_validation
//= require shared/state_button
//= require shared/subscriptions
diff --git a/app/models/comment.rb b/app/models/comment.rb
index d0ddb8478..61e6fd0b6 100644
--- a/app/models/comment.rb
+++ b/app/models/comment.rb
@@ -47,7 +47,7 @@ def notify(action:, actor:, recipients:)
# to be an ActiveRecord::Relation.
subscribers = User.includes(:subscriptions).where(
subscriptions: { subscribable_id: commentable.id, subscribable_type: commentable.class.to_s }
- ).where.not(id: [user.id] + mentions.pluck(:id))
+ ).where.not(id: [user.id] + mentions.pluck(:id)).enabled
subscribers = subscribers.select { |user| Ability.new(user).can?(:read, self) }
create_notifications(action: :create, actor: actor, recipients: subscribers)
end
@@ -87,7 +87,7 @@ def to_xml(xml_builder, version: 3)
xml_builder.content do
xml_builder.cdata!(content)
end
- xml_builder.author(user.email)
+ xml_builder.author(user&.email)
xml_builder.created_at(created_at.to_i)
end
diff --git a/app/services/diffed_content.rb b/app/services/diffed_content.rb
index 092a10c2e..8484ec327 100644
--- a/app/services/diffed_content.rb
+++ b/app/services/diffed_content.rb
@@ -84,12 +84,8 @@ def content_with_updated_field_from_target(field:, source:, target:)
end
def diff_by_word(source_content, target_content)
- Differ.format = :html
- differ_result = Differ.diff_by_word(source_content, target_content)
-
- output = highlighted_string(differ_result)
-
- { source: output[1], target: output[0] }
+ Differ.format = :color
+ Differ.diff_by_word(source_content, target_content)
end
def normalize_content(record)
@@ -100,21 +96,4 @@ def normalize_content(record)
"#[#{field}]#\n#{value.gsub("\r", '')}\n"
end.join("\n")
end
-
- def highlighted_string(differ_result)
- [:delete, :insert].map do |highlight_type|
- result_str = differ_result.dup.to_s
-
- case highlight_type
- when :delete
- result_str.gsub!(/(.*?)<\/del>/m, '\1')
- result_str.gsub!(/(.*?)<\/ins>/m, '')
- when :insert
- result_str.gsub!(/(.*?)<\/ins>/m, '\1')
- result_str.gsub!(/(.*?)<\/del>/m, '')
- end
-
- result_str.html_safe
- end
- end
end
diff --git a/app/views/issues/update.json.erb b/app/views/issues/update.json.erb
index aed67e7d0..417db53f4 100644
--- a/app/views/issues/update.json.erb
+++ b/app/views/issues/update.json.erb
@@ -2,6 +2,6 @@
"success": <%= @modified %>,
<% if tag = @issue.tags.first %>
"issue_link": "<%= j render(partial: 'issues/issue', locals: { issue: @issue }, formats: :html) %>",
- "tag_cell": "<%= j " #{tag.display_name} | ".html_safe %>"
+ "tag_cell": "<%= j " #{tag.display_name} | ".html_safe %>"
<% end %>
}
diff --git a/lib/dradis/ce/version.rb b/lib/dradis/ce/version.rb
index 55c6e4b30..6432bc10d 100644
--- a/lib/dradis/ce/version.rb
+++ b/lib/dradis/ce/version.rb
@@ -2,7 +2,7 @@ module Dradis
module CE #:nodoc:
module VERSION #:nodoc:
MAJOR = 4
- MINOR = 14
+ MINOR = 15
TINY = 0
PRE = nil
diff --git a/spec/services/diffed_content_spec.rb b/spec/services/diffed_content_spec.rb
index d2024377c..7231c16be 100644
--- a/spec/services/diffed_content_spec.rb
+++ b/spec/services/diffed_content_spec.rb
@@ -8,10 +8,9 @@
describe '#content_diff' do
it 'returns the diff' do
- expect(subject.content_diff).to eq({
- source: "#[Title]#\nIssue1\n",
- target: "#[Title]#\nIssue2\n"
- })
+ expect(subject.content_diff.to_s).to eq(
+ "#[Title]#\n\e[31mIssue2\e[0m\e[32mIssue1\e[0m\n"
+ )
end
end
@@ -33,12 +32,9 @@
describe '#unsynced_fields' do
it 'returns the fields that have changed between the source and the target' do
- expect(subject.unsynced_fields).to eq({
- 'Title' => {
- source: 'Issue1',
- target: 'Issue2'
- }
- })
+ expect(subject.unsynced_fields['Title'].to_s).to eq(
+ "\e[31mIssue2\e[0m\e[32mIssue1\e[0m"
+ )
end
end