scelint 0.6.2 → 0.7.0
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/CHANGELOG.md +5 -0
- data/lib/scelint/version.rb +1 -1
- data/lib/scelint.rb +48 -0
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: a1e8f8d8e3eb96d5aa6bc36fb178f2b3cb283240ff04c37f469f4563693e94ee
|
|
4
|
+
data.tar.gz: d89de6916fd66be7a7572240e8d04606ce33201b964f58b455da8423e850d474
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 29896aa3398ae2a5503f304ec68968bf4e2944084dbbee5eee3056eba57cb843d3cc9e39eb1660bb6d679485548fed575e5a027a38ce9c3f2ef0cf2d34bc0900
|
|
7
|
+
data.tar.gz: f34b1e846bd6a188af09b9b5e5fc4fed0510c068ed05c09488ed845ba8e83f0ab46738551a005daa5a34cc4d6aef587bc8ca0a75b6a2833cc3482da452cd9243
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
### 0.7.0 / 2026-11-02
|
|
2
|
+
* **BREAKING:** Report an error when files give a CE `oval-ids` for different
|
|
3
|
+
rules, as happens when two revisions of a benchmark ship together. Remove
|
|
4
|
+
the superseded files.
|
|
5
|
+
|
|
1
6
|
### 0.6.2 / 2026-11-02
|
|
2
7
|
* Report the file and check when data cannot be merged instead of crashing
|
|
3
8
|
* Report a `profiles`, `ce` or `checks` section that is not a hash, and a check's
|
data/lib/scelint/version.rb
CHANGED
data/lib/scelint.rb
CHANGED
|
@@ -149,6 +149,8 @@ module Scelint
|
|
|
149
149
|
|
|
150
150
|
merged_data_lint
|
|
151
151
|
|
|
152
|
+
check_ce_oval_ids
|
|
153
|
+
|
|
152
154
|
validate
|
|
153
155
|
end
|
|
154
156
|
|
|
@@ -801,8 +803,54 @@ module Scelint
|
|
|
801
803
|
errors << "#{file}: #{e.message} (not a hash?)"
|
|
802
804
|
end
|
|
803
805
|
|
|
806
|
+
# Report CEs that resolve to more than one rule
|
|
807
|
+
#
|
|
808
|
+
# A CE identifies one rule. When two files give the same CE different
|
|
809
|
+
# oval-ids, the merged CE carries every one of them, and scan results
|
|
810
|
+
# can no longer be correlated back to a single rule with any confidence.
|
|
811
|
+
#
|
|
812
|
+
# In practice this is what a superseded benchmark file looks like from the
|
|
813
|
+
# inside: the old and new revisions both define the same CE keys, and the
|
|
814
|
+
# rule ids are where they diverge.
|
|
815
|
+
def check_ce_oval_ids
|
|
816
|
+
data.ces.each do |ce, component|
|
|
817
|
+
by_file = component.component[:fragments].each_with_object({}) do |(file, fragment), result|
|
|
818
|
+
next unless fragment.is_a?(Hash)
|
|
819
|
+
|
|
820
|
+
ids = Array(fragment['oval-ids']).select { |id| id.is_a?(String) && !id.empty? }
|
|
821
|
+
result[file] = ids unless ids.empty?
|
|
822
|
+
end
|
|
823
|
+
|
|
824
|
+
by_file.to_a.combination(2) do |(file_a, ids_a), (file_b, ids_b)|
|
|
825
|
+
next if same_rules?(ids_a, ids_b)
|
|
826
|
+
|
|
827
|
+
errors << "CE '#{ce}': conflicting oval-ids (#{ids_a.inspect} in #{file_a}, #{ids_b.inspect} in #{file_b})"
|
|
828
|
+
end
|
|
829
|
+
end
|
|
830
|
+
end
|
|
831
|
+
|
|
804
832
|
private
|
|
805
833
|
|
|
834
|
+
# Return true if two sets of oval-ids name the same rules
|
|
835
|
+
#
|
|
836
|
+
# The same rule is routinely written two ways in one data set: a manual
|
|
837
|
+
# benchmark uses the bare rule id and its SCAP counterpart prefixes it, as in
|
|
838
|
+
# 'SV-230221r1017040_rule' and
|
|
839
|
+
# 'xccdf_mil.disa.stig_rule_SV-230221r1017040_rule'. Those are not a
|
|
840
|
+
# disagreement, so the 'xccdf_<namespace>_rule_' prefix is ignored, and
|
|
841
|
+
# the remaining rule names are compared as sets. The namespace may be
|
|
842
|
+
# written with '.' or ':', as in 'xccdf_org.ssgproject.content_rule_foo'
|
|
843
|
+
# and 'xccdf_org:ssgproject:content_rule_foo'.
|
|
844
|
+
#
|
|
845
|
+
# @param ids_a [Array<String>] A set of oval-ids
|
|
846
|
+
# @param ids_b [Array<String>] A set of oval-ids
|
|
847
|
+
# @return [Boolean]
|
|
848
|
+
def same_rules?(ids_a, ids_b)
|
|
849
|
+
rule_names = ->(ids) { ids.map { |id| id.sub(%r{\Axccdf_[^_]+_rule_}, '') }.uniq.sort }
|
|
850
|
+
|
|
851
|
+
rule_names.call(ids_a) == rule_names.call(ids_b)
|
|
852
|
+
end
|
|
853
|
+
|
|
806
854
|
# Merge a ComplianceEngine::Collection object into a Hash
|
|
807
855
|
#
|
|
808
856
|
# Components that cannot be merged (usually because a fragment is
|