Privacy hardening, remote-peer IP masking and review fixes

- Add privacy projection (core/privacy.py), private report storage, bounded
  process capture; omit identities, free text and unapproved paths
- Mask remote peer IPs: only loopback/host/wildcard stay numeric, others are
  reduced to remote_scope private/public (schema + scoring updated)
- Map ss TCP states to canonical names; ASCII-only numeric fields; fix
  "Microsoft Visual C++" product matching (Python and PowerShell)
- Merge 7fed3b9: -Diagnostic switch, serialization exit code 3, PS7 module
  path, UI error detail; keep hardened task/certificate collectors
- Add audit docs, privacy docs and regression tests

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-11-04 18:50:24 -08:00
parent 7fed3b9ab9
commit 610a3bb447
51 changed files with 2719 additions and 604 deletions

View File

@@ -78,7 +78,7 @@ class UITests(unittest.TestCase):
self.assertTrue(window.report_buttons[0].isEnabled())
with tempfile.TemporaryDirectory() as folder:
report = Path(folder) / 'local.html'
with patch('samsara.ui.window.QFileDialog.getSaveFileName', return_value=(str(report), '')), patch('samsara.ui.window.QMessageBox.information'):
with patch('samsara.core.storage._verify_windows_acl'), patch('samsara.core.storage.report_directory',return_value=Path(folder)), patch('samsara.ui.window.report_directory',return_value=Path(folder)), patch('samsara.ui.window.QFileDialog.getSaveFileName', return_value=(str(report), '')), patch('samsara.ui.window.QMessageBox.information'):
window.quick_save.click()
self.assertIn('LOCAL LINUX INVENTORY', report.read_text())
window.close()
@@ -137,7 +137,7 @@ class UITests(unittest.TestCase):
self.assertTrue(window.report_buttons[0].isEnabled())
with tempfile.TemporaryDirectory() as folder:
report = Path(folder)/'windows.html'
with patch('samsara.ui.window.QFileDialog.getSaveFileName', return_value=(str(report), '')), patch('samsara.ui.window.QMessageBox.information'):
with patch('samsara.core.storage._verify_windows_acl'), patch('samsara.core.storage.report_directory',return_value=Path(folder)), patch('samsara.ui.window.report_directory',return_value=Path(folder)), patch('samsara.ui.window.QFileDialog.getSaveFileName', return_value=(str(report), '')), patch('samsara.ui.window.QMessageBox.information'):
window.quick_save.click()
self.assertIn('LOCAL WINDOWS INVENTORY', report.read_text())
window.close()
@@ -171,3 +171,20 @@ class UITests(unittest.TestCase):
self.assertEqual(window.assessment['scoring']['policy_id'],original_policy)
window.reset_policy()
window.close()
def test_privacy_and_bounded_history_clear(self):
import json
window=MainWindow()
raw=collect_demo(LINUX_DEMO_HOST)
raw['server']['hostname']='SYNTHETIC_PERSON_UI_CANARY'
for _ in range(12): window.collection_done(raw)
self.assertEqual(len(window.records),10)
self.assertEqual(window.history_list.count(),10)
self.assertNotIn('SYNTHETIC_PERSON_UI_CANARY',json.dumps(window.records))
window.clear_history_button.click()
self.assertEqual(window.records,[])
self.assertEqual(window.history,[])
self.assertIsNone(window.data)
self.assertFalse(window.quick_save.isEnabled())
self.assertEqual(window.scheduled_jobs.text(),'')
window.close()