Skip to content

Commit 5d44306

Browse files
Crazytieguyclaude
andcommitted
Migrate to NIST 800-53 Rev 5 based overlays
Major changes: - Replace old Rev 4 based CNSSI 1253 and Classified Information overlays with Rev 5 versions - Move old overlay files to superseded/ folders for archival - Update frontend to use new data formats exclusively - Improve display of CNSSI Security Impact Levels (CIA triad) CNSSI 1253 changes: - Old: 457 selected controls (Rev 4) - New: 573 selected controls (Rev 5) - 46 controls deselected (all withdrawn in Rev 5) - 162 new controls added - New format includes CIA impact level selections Classified Information Overlay changes: - Old: 113 controls (Rev 4) - New: 108 controls (Rev 5) - Better structured with justification, parameter values, guidance, and references Frontend improvements: - Renamed extraction scripts to remove version suffixes - Display "Security Impact Levels" with full CIA names and readable formatting - Simplified code by removing fallback logic for old formats 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 5b75576 commit 5d44306

22 files changed

Lines changed: 798 additions & 18 deletions

classified_information/extract_classified_information_2022.py renamed to classified_information/extract_classified_information.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -201,13 +201,13 @@ def print_summary(controls: Dict):
201201

202202
def main():
203203
if len(sys.argv) < 2:
204-
print("Usage: python extract_classified_information_2022.py <pdf_file>")
204+
print("Usage: python extract_classified_information.py <pdf_file>")
205205
sys.exit(1)
206206

207207
pdf_file = sys.argv[1]
208-
output_file = "extracted_classified_information_2022.json"
208+
output_file = "extracted_classified_information.json"
209209

210-
print("Extracting Classified Information Overlay 2022...")
210+
print("Extracting Classified Information Overlay...")
211211
controls = extract_controls_from_pdf(pdf_file)
212212

213213
if controls:

classified_information/extracted_classified_information_2022.json renamed to classified_information/extracted_classified_information.json

File renamed without changes.
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
CLASSIFIED INFORMATION OVERLAY VERSION CHANGE SUMMARY
2+
====================================================
3+
4+
STATISTICS:
5+
- Old version (based on NIST 800-53 Rev 4): 113 controls
6+
- New version (based on NIST 800-53 Rev 5): 108 controls
7+
- Controls removed: 23
8+
- Controls added: 18
9+
- Net change: -5 controls
10+
11+
12+
CONTROLS REMOVED IN NEW VERSION:
13+
---------------------------------
14+
AC-18(1)
15+
AC-18(5)
16+
AC-19(5)
17+
AC-3
18+
CA-3(2)
19+
CM-3
20+
CM-5
21+
IR-9(1)
22+
MA-3
23+
MA-5
24+
MP-5(4)
25+
PE-2
26+
PE-3
27+
PE-5
28+
PE-5(3)
29+
PS-3
30+
PS-6
31+
SA-15
32+
SA-15(9)
33+
SA-4
34+
SC-15
35+
SC-42(3)
36+
SI-4
37+
38+
39+
CONTROLS ADDED IN NEW VERSION:
40+
-------------------------------
41+
AC-1
42+
AC-21
43+
IA-5(6)
44+
IR-6
45+
PE-22
46+
PM-12
47+
PS-9
48+
RA-10
49+
RA-3(2)
50+
RA-5
51+
SA-3(2)
52+
SC-41
53+
SC-7(26)
54+
SR-12
55+
SR-3
56+
SR-3(2)
57+
SR-4
58+
SR-7

classified_information/classified_information_overlay.pdf renamed to classified_information/superseded/classified_information_overlay.pdf

File renamed without changes.

classified_information/classified_information_overlay_extractor.py renamed to classified_information/superseded/classified_information_overlay_extractor.py

File renamed without changes.
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
#!/usr/bin/env python3
2+
"""
3+
Generate a simple summary of Classified Information Overlay version changes for reporting.
4+
"""
5+
6+
import json
7+
8+
def main():
9+
# Load data
10+
with open('extracted_classified_information_overlay.json', 'r') as f:
11+
old_data = json.load(f)
12+
13+
with open('extracted_classified_information_2022.json', 'r') as f:
14+
new_data = json.load(f)
15+
16+
# Get control sets
17+
old_controls = set(old_data.keys())
18+
new_controls = set(new_data.keys())
19+
20+
# Calculate differences
21+
removed = sorted(old_controls - new_controls)
22+
added = sorted(new_controls - old_controls)
23+
24+
# Write summary
25+
with open('Classified_Information_version_change_summary.txt', 'w') as f:
26+
f.write("CLASSIFIED INFORMATION OVERLAY VERSION CHANGE SUMMARY\n")
27+
f.write("====================================================\n\n")
28+
29+
f.write("STATISTICS:\n")
30+
f.write(f"- Old version (based on NIST 800-53 Rev 4): {len(old_controls)} controls\n")
31+
f.write(f"- New version (based on NIST 800-53 Rev 5): {len(new_controls)} controls\n")
32+
f.write(f"- Controls removed: {len(removed)}\n")
33+
f.write(f"- Controls added: {len(added)}\n")
34+
f.write(f"- Net change: {len(new_controls) - len(old_controls):+d} controls\n")
35+
36+
f.write("\n\nCONTROLS REMOVED IN NEW VERSION:\n")
37+
f.write("---------------------------------\n")
38+
for control_id in removed:
39+
f.write(f"{control_id}\n")
40+
41+
f.write("\n\nCONTROLS ADDED IN NEW VERSION:\n")
42+
f.write("-------------------------------\n")
43+
for control_id in added:
44+
f.write(f"{control_id}\n")
45+
46+
print("Summary written to: Classified_Information_version_change_summary.txt")
47+
48+
if __name__ == "__main__":
49+
main()
Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
#!/usr/bin/env python3
2+
"""
3+
Compare Classified Information Overlay old version (Rev 4 based) with new version (Rev 5 based).
4+
Shows differences in control selections between the two versions.
5+
"""
6+
7+
import json
8+
from collections import defaultdict
9+
10+
def load_old_classified():
11+
"""Load the old Classified Information Overlay format."""
12+
with open('extracted_classified_information_overlay.json', 'r') as f:
13+
return json.load(f)
14+
15+
def load_new_classified():
16+
"""Load the new Classified Information 2022 format."""
17+
with open('extracted_classified_information_2022.json', 'r') as f:
18+
return json.load(f)
19+
20+
def analyze_attributes(old_data, new_data):
21+
"""Analyze differences in control attributes between versions."""
22+
# Count attribute types in old format
23+
old_attrs = defaultdict(int)
24+
for control in old_data.values():
25+
for attr in control.get('attributes', {}):
26+
old_attrs[attr] += 1
27+
28+
# Count field types in new format
29+
new_fields = defaultdict(int)
30+
for control in new_data.values():
31+
if control.get('justification'):
32+
new_fields['justification'] += 1
33+
if control.get('parameter_value'):
34+
new_fields['parameter_value'] += 1
35+
if control.get('guidance'):
36+
new_fields['guidance'] += 1
37+
if control.get('references'):
38+
new_fields['references'] += 1
39+
40+
return old_attrs, new_fields
41+
42+
def main():
43+
print("=== Classified Information Overlay Version Comparison ===\n")
44+
45+
# Load data
46+
old_data = load_old_classified()
47+
new_data = load_new_classified()
48+
49+
print(f"Old version (Rev 4 based): {len(old_data)} controls")
50+
print(f"New version (Rev 5 based): {len(new_data)} controls")
51+
52+
# Get control sets
53+
old_controls = set(old_data.keys())
54+
new_controls = set(new_data.keys())
55+
56+
# Find differences
57+
only_old = old_controls - new_controls
58+
only_new = new_controls - old_controls
59+
both = old_controls & new_controls
60+
61+
print(f"\n=== Control Coverage ===")
62+
print(f"Controls in both versions: {len(both)}")
63+
print(f"Controls only in old version: {len(only_old)}")
64+
print(f"Controls only in new version: {len(only_new)}")
65+
66+
if only_old:
67+
print("\n--- Controls Only in Old Version ---")
68+
for control_id in sorted(only_old):
69+
old_control = old_data[control_id]
70+
print(f"{control_id}: {old_control.get('name', 'N/A')}")
71+
# Check if control might have different ID format in new version
72+
base_id = control_id.split('(')[0]
73+
similar = [cid for cid in new_controls if cid.startswith(base_id)]
74+
if similar:
75+
print(f" → Possible matches in new version: {similar}")
76+
77+
if only_new:
78+
print("\n--- Controls Only in New Version ---")
79+
for control_id in sorted(only_new):
80+
new_control = new_data[control_id]
81+
print(f"{control_id}: {new_control.get('name', 'N/A')}")
82+
83+
# Analyze attributes
84+
print("\n=== Attribute/Field Analysis ===")
85+
old_attrs, new_fields = analyze_attributes(old_data, new_data)
86+
87+
print("\nOld version attribute types:")
88+
for attr, count in sorted(old_attrs.items()):
89+
print(f" {attr}: {count} controls")
90+
91+
print("\nNew version field types:")
92+
for field, count in sorted(new_fields.items()):
93+
print(f" {field}: {count} controls")
94+
95+
# Show some examples of controls in both versions
96+
print("\n=== Sample Control Comparisons ===")
97+
sample_controls = sorted(both)[:5]
98+
99+
for control_id in sample_controls:
100+
print(f"\n{control_id}:")
101+
old_control = old_data[control_id]
102+
new_control = new_data[control_id]
103+
104+
print(f" Old name: {old_control.get('name', 'N/A')}")
105+
print(f" New name: {new_control.get('name', 'N/A')}")
106+
107+
# Compare attributes
108+
old_attrs = old_control.get('attributes', {})
109+
if old_attrs:
110+
print(" Old attributes:")
111+
for attr, value in old_attrs.items():
112+
if value:
113+
print(f" {attr}: {str(value)[:60]}...")
114+
115+
print(" New fields:")
116+
if new_control.get('justification'):
117+
print(f" justification: {new_control['justification'][:60]}...")
118+
if new_control.get('parameter_value'):
119+
print(f" parameter_value: {new_control['parameter_value'][:60]}...")
120+
if new_control.get('guidance'):
121+
print(f" guidance: {new_control['guidance'][:60]}...")
122+
if new_control.get('references'):
123+
print(f" references: {new_control['references'][:60]}...")
124+
125+
# Count families
126+
print("\n=== Control Family Distribution ===")
127+
old_families = defaultdict(int)
128+
new_families = defaultdict(int)
129+
130+
for control_id in old_controls:
131+
family = control_id.split('-')[0]
132+
old_families[family] += 1
133+
134+
for control_id in new_controls:
135+
family = control_id.split('-')[0]
136+
new_families[family] += 1
137+
138+
all_families = sorted(set(old_families.keys()) | set(new_families.keys()))
139+
140+
print("\nFamily | Old | New | Diff")
141+
print("-------|-----|-----|-----")
142+
for family in all_families:
143+
old_count = old_families[family]
144+
new_count = new_families[family]
145+
diff = new_count - old_count
146+
diff_str = f"+{diff}" if diff > 0 else str(diff)
147+
print(f"{family:6} | {old_count:3} | {new_count:3} | {diff_str:4}")
148+
149+
print(f"\nTotal | {len(old_controls):3} | {len(new_controls):3} | {len(new_controls) - len(old_controls):+4}")
150+
151+
if __name__ == "__main__":
152+
main()

classified_information/extracted_classified_information_overlay.json renamed to classified_information/superseded/extracted_classified_information_overlay.json

File renamed without changes.

cnssi_1253/extract_cnssi_1253_2022_final.py renamed to cnssi_1253/extract_cnssi_1253.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -328,7 +328,7 @@ def main():
328328

329329
if not debug_page:
330330
# Save to JSON
331-
output_path = 'extracted_cnssi_1253_2022.json'
331+
output_path = 'extracted_cnssi_1253.json'
332332
with open(output_path, 'w') as f:
333333
json.dump(controls, f, indent=2)
334334

0 commit comments

Comments
 (0)