gitgalaxy 1.0.9__tar.gz → 1.1.2__tar.gz

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.
Files changed (27) hide show
  1. {gitgalaxy-1.0.9 → gitgalaxy-1.1.2}/PKG-INFO +1 -1
  2. {gitgalaxy-1.0.9 → gitgalaxy-1.1.2}/gitgalaxy/audit_recorder.py +4 -6
  3. {gitgalaxy-1.0.9 → gitgalaxy-1.1.2}/gitgalaxy/chronometer.py +1 -1
  4. {gitgalaxy-1.0.9 → gitgalaxy-1.1.2}/gitgalaxy/detector.py +1 -1
  5. {gitgalaxy-1.0.9 → gitgalaxy-1.1.2}/gitgalaxy/galaxyscope.py +91 -11
  6. gitgalaxy-1.0.9/gitgalaxy/gitgalaxy_standards_v011.py → gitgalaxy-1.1.2/gitgalaxy/gitgalaxy_standards_v1.py +74 -0
  7. {gitgalaxy-1.0.9 → gitgalaxy-1.1.2}/gitgalaxy/gpu_recorder.py +9 -13
  8. {gitgalaxy-1.0.9 → gitgalaxy-1.1.2}/gitgalaxy/guidestar_lens.py +1 -1
  9. {gitgalaxy-1.0.9 → gitgalaxy-1.1.2}/gitgalaxy/language_lens.py +1 -1
  10. {gitgalaxy-1.0.9 → gitgalaxy-1.1.2}/gitgalaxy/llm_recorder.py +7 -7
  11. {gitgalaxy-1.0.9 → gitgalaxy-1.1.2}/gitgalaxy/prism.py +1 -1
  12. gitgalaxy-1.1.2/gitgalaxy/security_lens.py +174 -0
  13. {gitgalaxy-1.0.9 → gitgalaxy-1.1.2}/gitgalaxy/signal_processor.py +71 -6
  14. {gitgalaxy-1.0.9 → gitgalaxy-1.1.2}/gitgalaxy.egg-info/PKG-INFO +1 -1
  15. {gitgalaxy-1.0.9 → gitgalaxy-1.1.2}/gitgalaxy.egg-info/SOURCES.txt +1 -1
  16. {gitgalaxy-1.0.9 → gitgalaxy-1.1.2}/pyproject.toml +1 -1
  17. gitgalaxy-1.0.9/gitgalaxy/security_lens.py +0 -181
  18. {gitgalaxy-1.0.9 → gitgalaxy-1.1.2}/LICENSE +0 -0
  19. {gitgalaxy-1.0.9 → gitgalaxy-1.1.2}/README.md +0 -0
  20. {gitgalaxy-1.0.9 → gitgalaxy-1.1.2}/gitgalaxy/__init__.py +0 -0
  21. {gitgalaxy-1.0.9 → gitgalaxy-1.1.2}/gitgalaxy/aperture.py +0 -0
  22. {gitgalaxy-1.0.9 → gitgalaxy-1.1.2}/gitgalaxy/record_keeper.py +0 -0
  23. {gitgalaxy-1.0.9 → gitgalaxy-1.1.2}/gitgalaxy/spectral_auditor.py +0 -0
  24. {gitgalaxy-1.0.9 → gitgalaxy-1.1.2}/gitgalaxy.egg-info/dependency_links.txt +0 -0
  25. {gitgalaxy-1.0.9 → gitgalaxy-1.1.2}/gitgalaxy.egg-info/entry_points.txt +0 -0
  26. {gitgalaxy-1.0.9 → gitgalaxy-1.1.2}/gitgalaxy.egg-info/top_level.txt +0 -0
  27. {gitgalaxy-1.0.9 → gitgalaxy-1.1.2}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: gitgalaxy
3
- Version: 1.0.9
3
+ Version: 1.1.2
4
4
  Summary: A high-speed static analysis engine that sequences source code like DNA to map architectural risk and security threats.
5
5
  Author: Joe Esquibel
6
6
  License: PolyForm Noncommercial License 1.0.0
@@ -14,7 +14,7 @@ import re
14
14
  from datetime import datetime
15
15
  from pathlib import Path
16
16
  from typing import Any
17
- from . import gitgalaxy_standards_v011 as config
17
+ from . import gitgalaxy_standards_v1 as config
18
18
 
19
19
  # ==============================================================================
20
20
  # GitGalaxy Phase 8 & 9: Astrograph Auditor (The Forensic Record)
@@ -365,11 +365,9 @@ class AuditRecorder:
365
365
  "6. Visible Matter (Scanned Artifacts)": pretty_constellations
366
366
  }
367
367
 
368
- # --- ABSOLUTE ROUTING LOGIC ---
369
- base_dir = Path("/srv/storage_16tb/projects/gitgalaxy/data")
370
- base_dir.mkdir(parents=True, exist_ok=True)
371
- safe_filename = Path(output_path).name
372
- target_path = base_dir / safe_filename
368
+ # --- THE FIX ---
369
+ # Convert the output_path handed to us by the orchestrator into a Path object
370
+ target_path = Path(output_path)
373
371
 
374
372
  try:
375
373
  with open(target_path, 'w', encoding='utf-8') as f:
@@ -13,7 +13,7 @@ import logging
13
13
  import time
14
14
  from pathlib import Path
15
15
  from typing import Dict, Any, Optional, List, Tuple
16
- from . import gitgalaxy_standards_v011 as config
16
+ from . import gitgalaxy_standards_v1 as config
17
17
 
18
18
  # ==============================================================================
19
19
  # GitGalaxy Phase 3: Chronometer (Temporal Sensor)
@@ -13,7 +13,7 @@ import hashlib
13
13
  import logging
14
14
  import time
15
15
  from typing import Dict, List, Any, TypedDict, Optional, Tuple
16
- from . import gitgalaxy_standards_v011 as config
16
+ from . import gitgalaxy_standards_v1 as config
17
17
 
18
18
 
19
19
  # ==============================================================================
@@ -36,7 +36,7 @@ from .audit_recorder import AuditRecorder
36
36
  from .llm_recorder import LLMRecorder
37
37
  from .security_lens import SecurityLens
38
38
  # Load Universal Laws from config
39
- from . import gitgalaxy_standards_v011 as scanning_config
39
+ from . import gitgalaxy_standards_v1 as scanning_config
40
40
 
41
41
  logger = logging.getLogger("GalaxyScope")
42
42
 
@@ -90,6 +90,12 @@ def _init_worker(root_str: str, config: Dict[str, Any], ext_tally: Dict[str, int
90
90
  if lang_id not in splicer_cache:
91
91
  splicer_cache[lang_id] = LogicSplicer(lang_id, lang_defs, parent_logger=worker_logger)
92
92
 
93
+ # --- NEW: Decide the Rules of Engagement before booting the engines ---
94
+ if os.environ.get("GITGALAXY_DATA_DIR"):
95
+ active_policy = scanning_config.ThreatPolicy.get_policy("paranoid")
96
+ else:
97
+ active_policy = scanning_config.ThreatPolicy.get_policy("baseline")
98
+
93
99
  _worker_state.update({
94
100
  'root': root,
95
101
  'config': config,
@@ -103,10 +109,30 @@ def _init_worker(root_str: str, config: Dict[str, Any], ext_tally: Dict[str, int
103
109
  'detector': LanguageDetector(lang_defs, comm_defs),
104
110
  'prism': Prism(comm_defs, lang_defs, parent_logger=worker_logger),
105
111
  'splicer_cache': splicer_cache,
106
- 'word_tokenizer': re.compile(r'\b\w+\b')
112
+ 'word_tokenizer': re.compile(r'\b\w+\b'),
113
+
114
+ # --- NEW: Boot the physics engines into worker memory ---
115
+ 'chronometer': Chronometer(root, parent_logger=worker_logger),
116
+ 'signal': SignalProcessor(aperture_config=config, parent_logger=worker_logger),
117
+ 'security': SecurityLens(policy=active_policy)
118
+ # --------------------------------------------------------
107
119
  })
108
120
 
109
121
  _worker_state['guidestar'].align_telescope()
122
+
123
+ def resolve_mission_control(target_name: str) -> Path:
124
+ """Routes reports to a .env path, or defaults to the current directory."""
125
+ env_path = os.environ.get("GITGALAXY_DATA_DIR")
126
+
127
+ if env_path:
128
+ # If the environment variable is set, drop the files EXACTLY there
129
+ mission_dir = Path(env_path)
130
+ else:
131
+ # If no variable (like on a user's machine), make a safe subfolder so we don't make a mess
132
+ mission_dir = Path.cwd() / "galaxy_reports" / target_name
133
+
134
+ mission_dir.mkdir(parents=True, exist_ok=True)
135
+ return mission_dir
110
136
 
111
137
  def _process_file_worker(rel_path: str) -> Dict[str, Any]:
112
138
  """Processes a single file path using the worker's cached hardware modules."""
@@ -139,6 +165,12 @@ def _process_file_worker(rel_path: str) -> Dict[str, Any]:
139
165
  splicer_cache = _worker_state['splicer_cache']
140
166
  tokenizer = _worker_state['word_tokenizer']
141
167
 
168
+ # --- NEW: Extract the physics engines from worker memory ---
169
+ chronometer = _worker_state['chronometer']
170
+ signal = _worker_state['signal']
171
+ security = _worker_state['security']
172
+ # -----------------------------------------------------------
173
+
142
174
  has_prior, intent_vector = guidestar.get_intent_status(full_path_str)
143
175
  observation = {"rel_path": rel_path, "status": "filtered", "reason": "Aperture block", "data": {}}
144
176
 
@@ -298,6 +330,16 @@ class Orchestrator:
298
330
  self.audit_recorder = AuditRecorder(parent_logger=logger)
299
331
  self.llm_recorder = LLMRecorder(parent_logger=logger)
300
332
 
333
+ # --- NEW: THE SMART THREAT SWITCH (MAIN THREAD) ---
334
+ if os.environ.get("GITGALAXY_DATA_DIR"):
335
+ logger.info("☣️ HAZMAT SANDBOX DETECTED: Engaging PARANOID threat thresholds.")
336
+ active_policy = scanning_config.ThreatPolicy.get_policy("paranoid")
337
+ else:
338
+ active_policy = scanning_config.ThreatPolicy.get_policy("baseline")
339
+
340
+ self.security_analyzer = SecurityLens(policy=active_policy)
341
+ # --------------------------------------------------
342
+
301
343
  # State Arrays
302
344
  self.census: Set[str] = set()
303
345
  self.stem_map: Dict[str, str] = {}
@@ -360,6 +402,11 @@ class Orchestrator:
360
402
  # Pass the array into the function, and merge the results directly
361
403
  summary["singularity"].update(self._summarize_anomalies(total_singularity))
362
404
 
405
+ # --- THE NEW ROUTER ---
406
+ mission_dir = resolve_mission_control(self.root.name)
407
+ output_file = str(mission_dir / Path(output_file).name)
408
+ # ----------------------
409
+
363
410
  # ==========================================================
364
411
  # PHASE 8: AUDIT RECORDER (Non-Destructive Forensic Fork)
365
412
  # ==========================================================
@@ -712,6 +759,25 @@ class Orchestrator:
712
759
  """Pass 2: Universal Exposure Framework & Signal Processing."""
713
760
  logger.info("PASS_2: Calculating structural physics and Tiered Normalization.")
714
761
 
762
+ # ==============================================================
763
+ # NEW: CALCULATE FOLDER CONTEXTS (For Domain Ontologies)
764
+ # Tally the languages in every folder to find the dominant ecosystem
765
+ # ==============================================================
766
+ folder_tallies = {}
767
+ for rel_path, meta in self.cryolink.items():
768
+ folder = str(Path(rel_path).parent)
769
+ lang = meta.get("lang_id", "unknown")
770
+
771
+ if folder not in folder_tallies:
772
+ folder_tallies[folder] = {}
773
+ folder_tallies[folder][lang] = folder_tallies[folder].get(lang, 0) + 1
774
+
775
+ folder_dominant_langs = {}
776
+ for folder, tallies in folder_tallies.items():
777
+ if tallies:
778
+ # The language with the most files wins the neighborhood
779
+ folder_dominant_langs[folder] = max(tallies, key=tallies.get)
780
+
715
781
  # --- NEW: CALCULATE THE GLOBAL TEST UMBRELLA ---
716
782
  total_loc = 0
717
783
  test_loc = 0
@@ -732,6 +798,15 @@ class Orchestrator:
732
798
 
733
799
  for rel_path, meta in self.cryolink.items():
734
800
 
801
+ # ---> NEW: INJECT THE FOLDER CONTEXT FOR THE SIGNAL PROCESSOR <---
802
+ folder = str(Path(rel_path).parent)
803
+ if "metadata" not in meta:
804
+ meta["metadata"] = {}
805
+
806
+ # Grab the winning language for this folder (defaulting to the file's own language)
807
+ meta["metadata"]["folder_dominant_lang"] = folder_dominant_langs.get(folder, meta.get("lang_id", "unknown"))
808
+ # -----------------------------------------------------------------
809
+
735
810
  meta["temporal_telemetry"] = self.chronometer.get_temporal_signals(rel_path)
736
811
  meta["authors"] = meta["temporal_telemetry"].get("authors", {})
737
812
  stem = Path(rel_path).stem.lower()
@@ -1060,15 +1135,20 @@ def main():
1060
1135
  merged_langs[lang]['rules'].update(rules_patch)
1061
1136
  logging.debug(f" -> Patched '{lang}' geometry rules.")
1062
1137
 
1063
- # =========================================================
1064
- # --- NEW: SECURITY LENS INTEGRATION ---
1065
- # =========================================================
1066
- logging.info("🛡️ SECURITY LENS ACTIVE: Passively monitoring for Threat Signatures.")
1067
- lens = SecurityLens(parent_logger=logging.getLogger())
1068
-
1069
- # Unconditionally inject the 'sec_' prefixed observers into the registry
1070
- merged_langs = lens.arm_lens(merged_langs)
1071
- # =========================================================
1138
+ # --- THE SMART THREAT SWITCH ---
1139
+ # If the engine detects the Docker airlock environment variable, it goes into full lockdown.
1140
+ if os.environ.get("GITGALAXY_DATA_DIR"):
1141
+ # We are in the sandbox. Engage Paranoid Mode.
1142
+ active_policy = scanning_config.ThreatPolicy.get_policy("paranoid")
1143
+ # Optional: Print a cool warning so you know it worked in the logs
1144
+ logging.getLogger("GalaxyScope").info("☣️ HAZMAT SANDBOX DETECTED: Engaging PARANOID threat thresholds.")
1145
+ else:
1146
+ # Normal developer scan. Engage Baseline Mode.
1147
+ active_policy = scanning_config.ThreatPolicy.get_policy("baseline")
1148
+
1149
+ # Boot the lens with the chosen policy
1150
+ security_lens = SecurityLens(policy=active_policy)
1151
+ # -------------------------------
1072
1152
 
1073
1153
  # ---------------------------------------------------------
1074
1154
  # 3. Assemble the Final Configuration
@@ -21,6 +21,36 @@ Contains:
21
21
 
22
22
  """
23
23
 
24
+ class ThreatPolicy:
25
+ """Defines the threshold at which a structural anomaly becomes a critical threat."""
26
+
27
+ PROFILES = {
28
+ # The Baseline: For standard, internal development where some low-level logic is expected.
29
+ "baseline": {
30
+ "secrets_risk_threshold": 0.001, # 0.1% density
31
+ "hidden_malware_threshold": 0.60, # 60% density
32
+ "logic_bomb_threshold": 0.50, # 50% density
33
+ "injection_surface_threshold": 0.65, # 65% density
34
+ "memory_corruption_threshold": 0.60 # 60% density
35
+ },
36
+
37
+ # The Hazmat Suit: For scanning unknown PyPI/npm packages in a quarantine sandbox.
38
+ "paranoid": {
39
+ "secrets_risk_threshold": 0.0001, # Any trace is critical
40
+ "hidden_malware_threshold": 0.15, # 15% density trips the wire
41
+ "logic_bomb_threshold": 0.20, # 20% density
42
+ "injection_surface_threshold": 0.25, # 25% density
43
+ "memory_corruption_threshold": 0.10 # 10% density
44
+ }
45
+ }
46
+
47
+ @staticmethod
48
+ def get_policy(mode="baseline"):
49
+ """Returns the specific threat thresholds based on the deployment mode."""
50
+ return ThreatPolicy.PROFILES.get(mode, ThreatPolicy.PROFILES["baseline"])
51
+
52
+ #
53
+
24
54
 
25
55
  # ------------------------------------------------------------------------------
26
56
  # 1. OPTICAL LAYER (Consumed by aperture.py & guidestar_lens.py)
@@ -10402,6 +10432,50 @@ RISK_EQUATION_TUNING = {
10402
10432
  }
10403
10433
  }
10404
10434
 
10435
+ # ------------------------------------------------------------------------------
10436
+ # 4.6 LANGUAGE SECURITY PROFILES (The Context vs. Entity Matrix)
10437
+ # Defines domain ontologies to cure the "Apollo Paradox" and detect Trojan Horses.
10438
+ # ------------------------------------------------------------------------------
10439
+ LANGUAGE_SECURITY_PROFILES = {
10440
+ "ECOSYSTEMS": {
10441
+ # Bare metal, embedded, and legacy mainframe. Pointer math and direct OS hooks are native.
10442
+ "systems": {
10443
+ "c", "cpp", "rust", "assembly", "agc_assembly", "zig", "cobol",
10444
+ "fortran", "micropython", "objective-c"
10445
+ },
10446
+ # High DOM flux, UI components, and massive string manipulation. Highly vulnerable to XSS.
10447
+ "web": {
10448
+ "javascript", "typescript", "html", "css", "php", "ruby",
10449
+ "dart", "livecode"
10450
+ },
10451
+ # Deployment, orchestration, and scripting. OS execution is the literal purpose.
10452
+ "infra": {
10453
+ "shell", "powershell", "dockerfile", "yaml", "makefile", "m4",
10454
+ "xml", "json", "toml", "sqlite", "csv", "plaintext"
10455
+ },
10456
+ # Data processing, APIs, and strict-typed object orientation.
10457
+ "backend": {
10458
+ "python", "java", "go", "csharp", "kotlin", "scala", "scheme",
10459
+ "tcl", "matlab", "perl", "haskell", "lua", "apex", "swift"
10460
+ }
10461
+ },
10462
+
10463
+ # Baseline multipliers applied when the file MATCHES its neighborhood's dominant ecosystem
10464
+ "NATIVE_WEIGHTS": {
10465
+ "systems": {"memory": 0.1, "logic_bomb": 0.2, "flux": 1.0, "injection": 1.0}, # Pointer math is normal
10466
+ "web": {"memory": 1.0, "logic_bomb": 1.0, "flux": 0.3, "injection": 2.0}, # DOM flux is normal, XSS is deadly
10467
+ "infra": {"memory": 1.0, "logic_bomb": 0.0, "flux": 1.0, "injection": 1.0}, # OS commands are literally the point
10468
+ "backend": {"memory": 1.5, "logic_bomb": 1.0, "flux": 1.5, "injection": 1.5} # Standard aggressive baseline
10469
+ },
10470
+
10471
+ # Aggressive penalties applied when the file is an ALIEN in its neighborhood
10472
+ "ALIEN_WEIGHTS": {
10473
+ "systems_in_web": {"memory": 5.0, "logic_bomb": 3.0}, # C code hiding in a JS app = Trojan
10474
+ "infra_in_web": {"logic_bomb": 4.0}, # Shell script hiding in a JS app = Backdoor
10475
+ "web_in_systems": {"flux": 3.0} # JS embedded in C firmware = Bizarre architecture
10476
+ }
10477
+ }
10478
+
10405
10479
  # ------------------------------------------------------------------------------
10406
10480
  # 5. SCHEMA & EXPORT REGISTRY (Consumed by recorders & SQLite)
10407
10481
  # ------------------------------------------------------------------------------
@@ -12,7 +12,7 @@ import logging
12
12
  import gc
13
13
  from pathlib import Path
14
14
  from typing import List, Dict, Any, Optional
15
- from . import gitgalaxy_standards_v011 as config
15
+ from . import gitgalaxy_standards_v1 as config
16
16
 
17
17
  # ==============================================================================
18
18
  # GitGalaxy Phase 9: GPU Recorder (Formerly RecordKeeper)
@@ -291,21 +291,17 @@ class GPURecorder:
291
291
  return registry.index(val)
292
292
 
293
293
  def save_minified(self, payload: Dict[str, Any], filename: str):
294
- """Serializes with maximum JSON compression to a dedicated storage drive."""
295
-
296
- # 1. Define the target directory
297
- base_dir = Path("/srv/storage_16tb/projects/gitgalaxy/data")
298
-
299
- # 2. Ensure the directory exists (creates parent folders if needed)
300
- base_dir.mkdir(parents=True, exist_ok=True)
294
+ """Serializes with maximum JSON compression to the provided output path."""
295
+ from pathlib import Path
296
+
297
+ # Convert the path handed to us by the orchestrator into a Path object
298
+ target_path = Path(filename)
301
299
 
302
- # 3. Strip any existing paths from the filename and append it to the base directory
303
- # This prevents errors if someone passes a filename like "data/output.json"
304
- safe_filename = Path(filename).name
305
- target_path = base_dir / safe_filename
300
+ # Ensure the parent directory exists just to be safe
301
+ target_path.parent.mkdir(parents=True, exist_ok=True)
306
302
 
307
303
  try:
308
- # 4. Save using the new absolute target_path
304
+ # Save using the safe target_path
309
305
  with open(target_path, 'w', encoding='utf-8') as f:
310
306
  json.dump(payload, f, indent=None, separators=(',', ':'), ensure_ascii=False)
311
307
  self.logger.info(f"GPU Manifest Sealed -> {target_path}")
@@ -13,7 +13,7 @@ import logging
13
13
  import fnmatch
14
14
  from pathlib import Path
15
15
  from typing import Dict, Any, Optional, List, Tuple, Union
16
- from . import gitgalaxy_standards_v011 as config
16
+ from . import gitgalaxy_standards_v1 as config
17
17
 
18
18
  # ==============================================================================
19
19
  # GitGalaxy Phase 0.5: Sector Intelligence (The GuideStar Lens)
@@ -13,7 +13,7 @@ import time
13
13
  import logging
14
14
  from pathlib import Path
15
15
  from typing import Tuple, Optional, Dict, List, Any, TypedDict, Union
16
- from .gitgalaxy_standards_v011 import EXACT_FILE_MATCH, LANGUAGE_DEFINITIONS, LENS_CONFIG
16
+ from .gitgalaxy_standards_v1 import EXACT_FILE_MATCH, LANGUAGE_DEFINITIONS, LENS_CONFIG
17
17
 
18
18
  # ==============================================================================
19
19
  # GitGalaxy Phase 1: The Entity Census (The Linguistic Detector Chip)
@@ -13,7 +13,7 @@ import statistics
13
13
  from pathlib import Path
14
14
  from datetime import datetime
15
15
  from typing import List, Dict, Any, Optional
16
- from . import gitgalaxy_standards_v011 as config
16
+ from . import gitgalaxy_standards_v1 as config
17
17
 
18
18
  # ==============================================================================
19
19
  # GitGalaxy Phase 10: LLM Recorder (The AI Translation Layer)
@@ -58,13 +58,13 @@ class LLMRecorder:
58
58
  if forensic_report is None:
59
59
  forensic_report = {}
60
60
 
61
- # --- ABSOLUTE ROUTING LOGIC (Matching Audit Recorder) ---
62
- base_dir = Path("/srv/storage_16tb/projects/gitgalaxy/data")
63
- base_dir.mkdir(parents=True, exist_ok=True)
64
61
 
65
62
  target_name = session_meta.get("target", "unknown_project")
66
- output_path_md = base_dir / f"{target_name}_galaxy_llm.md"
67
- output_path_db = base_dir / f"{target_name}_galaxy_graph.sqlite"
63
+ safe_dir = Path(output_dir)
64
+
65
+ # Use safe_dir instead of base_dir!
66
+ output_path_md = safe_dir / f"{target_name}_galaxy_llm.md"
67
+ output_path_db = safe_dir / f"{target_name}_galaxy_graph.sqlite"
68
68
 
69
69
  self.logger.info(f"Initiating LLM Artifact Generation for '{target_name}'...")
70
70
 
@@ -200,7 +200,7 @@ class LLMRecorder:
200
200
  lines.append("> Most scores use a Sigmoid curve based on density (Hits / LOC) to prevent massive files from mathematically hiding their flaws.")
201
201
  lines.append("> ")
202
202
  lines.append("> 1. **Cognitive Load Exposure:** Measures the mental effort required for a developer to read and understand the file. `Density(Branches + (Flux * 2) + Async/Danger)` mitigated by `Doc Coverage`. High scores indicate a high density of decision-making, conditional branching, and complex state management packed into a small area.")
203
- lines.append("> 2. **Safety Risk Exposure:** Measures structural integrity and resilience against runtime errors. `Net Exposure = (Danger + Safety_Neg + Flux) - (Safety + Tests + Docs)`. High scores mean risky operations (dynamic execution, type bypasses, unhandled mutations) exceed defensive guardrails (try/catch blocks, type checks, assertions). **Breach Cap:** If danger density is too high, the score is mathematically floored to a high-risk state regardless of defense.")
203
+ lines.append("> 2. **Safety Risk Exposure:** Measures structural integrity and resilience against runtime errors. `Net Exposure = (Danger + Safety_Neg + Flux) - (Safety + Tests + Docs)`. High scores mean risky operations (dynamic execution, type bypasses, unhandled mutations) exceed defensive guardrails (try/catch blocks, type checks, assertions). **Breach Cap:** If danger density is too high, the score is mathematically floored to a high-risk state regardless of defense. A value of near 30 is near minimum floor as gitglaxay tests for testing file pairs, testing folders but not actually their contents.")
204
204
  lines.append("> 3. **Tech Debt Exposure:** Measures the density of developer-annotated structural stress. `Density(TODOs [1x] + FIXMEs/Hacks [3x] + Empty Stubs [0.5x])`. High scores indicate a high volume of temporary workarounds, fragile logic, and incomplete implementations relative to the file size.")
205
205
  lines.append("> 4. **Verification (Testing) Risk Exposure:** Measures the density of unit testing and programmatic assertions. Evaluates `Test Density` + `Sibling Bonus` (if a dedicated test file exists). High scores (100% risk) mean the logic lacks internal test coverage and has no dedicated sibling test file, increasing the risk of silent failures during refactoring. **Mass Penalty:** Files over 300 LOC get an automatic risk penalty because massive files are inherently harder to test completely.")
206
206
  lines.append("> 5. **API Risk Exposure:** Measures the public surface area of a module. `Ratio(API Hits / Total Functions & Classes)`. Weighted by logarithmic volume. High scores indicate that a large percentage of the file's functions and classes are explicitly exported or publicly accessible by external systems.")
@@ -10,7 +10,7 @@
10
10
  import re
11
11
  import logging
12
12
  from typing import Dict, List, Optional, Tuple, Any, TypedDict
13
- from .gitgalaxy_standards_v011 import LENS_CONFIG, PRISM_CONFIG
13
+ from .gitgalaxy_standards_v1 import LENS_CONFIG, PRISM_CONFIG
14
14
 
15
15
  # ==============================================================================
16
16
  # GitGalaxy Phase 2: Structural Refractor (The Prism)
@@ -0,0 +1,174 @@
1
+ import re
2
+
3
+ class SecurityLens:
4
+ """
5
+ The GitGalaxy Physics Engine for Threat Detection.
6
+ Measures raw structural realities (Regex Hits) and compares them
7
+ against dynamically injected Policy Thresholds.
8
+ """
9
+
10
+ def __init__(self, policy=None):
11
+ # ------------------------------------------------------------------
12
+ # DYNAMIC POLICY INJECTION
13
+ # The lens no longer makes the rules. It receives its thresholds
14
+ # from gitgalaxy_standards.ThreatPolicy. If none is provided, it
15
+ # defaults to a safe baseline.
16
+ # ------------------------------------------------------------------
17
+ self.policy = policy or {
18
+ "secrets_risk_threshold": 0.001,
19
+ "hidden_malware_threshold": 0.60,
20
+ "logic_bomb_threshold": 0.50,
21
+ "injection_surface_threshold": 0.65,
22
+ "memory_corruption_threshold": 0.60
23
+ }
24
+
25
+ # ------------------------------------------------------------------
26
+ # RAW SENSORS (The Physics Engine)
27
+ # These remain untouched. They strictly measure structural reality.
28
+ # ------------------------------------------------------------------
29
+ self.THREAT_SIGNATURES = {
30
+ # 1. THE GLASSWORM (Obfuscation & Heat Signatures)
31
+ "heat_triggers": re.compile(
32
+ r'\b(?:atob|btoa|base64_decode|base64_encode|gzuncompress|str_rot13)\b|'
33
+ r'\\x[0-9a-fA-F]{2}|\\u[0-9a-fA-F]{4}|'
34
+ r'(?:\w{15,}[ \t]*=[ \t]*["\'][A-Za-z0-9+/]{40,}={0,2}["\'])|'
35
+ r'[\u200B-\u200D\uFEFF\u200E\u200F\u202A-\u202E]', # Invisible Unicode
36
+ re.I
37
+ ),
38
+
39
+ # 2. THE TROJAN (Identity Masking & Safety Bypasses)
40
+ "safety_neg": re.compile(
41
+ r'\b(?:atob|btoa|base64_decode|gzinflate|gzuncompress|str_rot13|urldecode)[ \t]*\([ \t]*(?:atob|btoa|base64_decode|gzinflate|gzuncompress|str_rot13|urldecode)\b|'
42
+ r'\b(?:auto_prepend_file|auto_append_file)\b|'
43
+ r'\b(?:ini_set|ini_restore|putenv)[ \t]*\([ \t]*["\'](?:disable_functions|safe_mode|open_basedir|allow_url_fopen)["\'][ \t]*,[ \t]*["\']?(?:0|off|false|)["\']?\)|'
44
+ r'\b(?:disable_functions|safe_mode|open_basedir)\b[ \t]*=[ \t]*(?:off|0|false|""|\'\')|'
45
+ r'process\.env\.NODE_TLS_REJECT_UNAUTHORIZED[ \t]*=[ \t]*["\']?0["\']?|'
46
+ r'\b(?:verify|strictSSL|rejectUnauthorized|CURLOPT_SSL_VERIFYPEER)[ \t]*[=:,][ \t]*(?:False|false|0)\b',
47
+ re.I
48
+ ),
49
+
50
+ # 3. EXFILTRATION VECTORS (System Gravity)
51
+ "io": re.compile(
52
+ r'\b(?:fetch|XMLHttpRequest|WebSocket|http\.request|https\.request|requests\.(?:post|put|get)|urllib\.request\.urlopen)\b\s*\(|'
53
+ r'\b(?:curl_exec|fsockopen|pfsockopen|stream_socket_client|file_get_contents)\b\s*\(|'
54
+ r'\b(?:dns_get_record|gethostbyname|socket\.gethostbyname|resolve(?:4|6|Cname|Txt)?)\b\s*\(|'
55
+ r'(?:https?|ftp|tcp|udp|wss?):\/\/(?:(?:\d{1,3}\.){3}\d{1,3}|\[[0-9a-fA-F:]+\]|.*?\.(?:ngrok\.io|ngrok-free\.app|localtunnel\.me|pastebin\.com|workers\.dev|s3\.amazonaws\.com|requestbin\.net|pipedream\.net))',
56
+ re.I | re.X
57
+ ),
58
+
59
+ # 4. THE EXECUTIONER (Dynamic Payloads)
60
+ "danger": re.compile(
61
+ r'\b(?:eval|Function|setTimeout|setInterval)\b\s*\(\s*(?:atob|base64|["\']|`)|'
62
+ r'\b(?:document\.write|location\.replace|assert|create_function|passthru|shell_exec|system)\b|'
63
+ r'child_process\.(?:exec|spawn|fork)|'
64
+ r'(?:window|global|this|globalThis)\[[ \t]*(?:["\'][a-zA-Z]["\'][ \t]*\+[ \t]*){1,15}["\'][a-zA-Z]["\'][ \t]*\][ \t]*\(|'
65
+ r'\$[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*\s*\(\s*\$_(?:POST|GET|COOKIE|REQUEST|HEADERS)|'
66
+ r'getattr\s*\(\s*__import__\s*\(|__builtins__\[|Assembly\.Load\s*\(',
67
+ re.I | re.X
68
+ ),
69
+
70
+ # 5. ENVIRONMENT POISONING (State Flux)
71
+ "flux": re.compile(
72
+ r'\b[A-Za-z0-9_]+\.prototype\.[A-Za-z0-9_]+[ \t]*=|'
73
+ r'\.__proto__[ \t]*=[ \t]*[{a-zA-Z]|'
74
+ r'\b(?:window|global|globalThis|document)\.(?:fetch|eval|setTimeout|setInterval|Promise|console|JSON)[ \t]*=|'
75
+ r'\$(?:GLOBALS|_(?:SERVER|GET|POST|COOKIE|REQUEST|ENV|SESSION))\[[^\]]+\][ \t]*=[ \t]*[^=]|'
76
+ r'\bextract[ \t]*\([ \t]*\$(?:_(?:GET|POST|REQUEST|COOKIE)|GLOBALS)\b|'
77
+ r'\b__builtins__\[[^\]]+\][ \t]*=|'
78
+ r'\bsys\.modules\[[^\]]+\][ \t]*=',
79
+ re.I
80
+ ),
81
+
82
+ # 6. SHADOW LOGIC (Necrosis / Graveyard)
83
+ "graveyard": re.compile(
84
+ r'(?://|#|--)[^\n]*?\b(?:http|bash|curl|wget|eval|base64|nc\s+-e|/dev/tcp)\b|'
85
+ r'/\*(?:(?!\*/).){0,500}?\b(?:http|bash|curl|wget|eval|base64|nc\s+-e|/dev/tcp)\b',
86
+ re.I
87
+ ),
88
+
89
+ # 7. SUB-ATOMIC DECRYPTION (Bitwise Hits)
90
+ "bitwise_hits": re.compile(
91
+ r'\b\w+[ \t]*=[ \t]*(?:\w+[ \t]*\^[ \t]*\w+[ \t]*){2,20}|'
92
+ r'(?:\w+\[[^\]\n]{1,50}\][ \t]*\^[ \t]*=?[ \t]*(?:0x[0-9a-fA-F]+|\d+|\w+)[ \t]*;[ \t]*){3,20}',
93
+ re.I
94
+ ),
95
+
96
+ # 8. SHADOW IMPORTS (The Switcharoo / Steganography)
97
+ "shadow_imports": re.compile(
98
+ r'\b(?:require|include|import|require_once|include_once|source|load|dofile)\b\s*\(?\s*'
99
+ r'["\'][^"\']+\.(?:png|jpg|jpeg|gif|ico|pdf|zip|tar|dat|tmp|log|txt|csv|wav|mp3)["\']',
100
+ re.I
101
+ ),
102
+
103
+ # 9. UNICODE SMUGGLING (Homoglyphs & Typosquatting)
104
+ "homoglyphs": re.compile(
105
+ r'\b(?:import|from|require|include|require_once|fetch|XMLHttpRequest)\b'
106
+ r'[^\n]*?(?:[\u0400-\u04FF]|'
107
+ r'[\u0370-\u03FF]|'
108
+ r'[\u1D400-\u1D7FF]|'
109
+ r'\u3164)',
110
+ re.I
111
+ ),
112
+
113
+ # 10. THE VAULT DOOR (Credential & Secret Leaks)
114
+ "private_info": re.compile(
115
+ r"\b(password|secret|token|api[_-]?key|client[_-]?secret|credentials|private[_-]?key|auth[_-]?token)\b[ \t]*(?:[:=]|=>)[ \t]*[\"'][A-Za-z0-9\-_+/=]{16,}[\"']",
116
+ re.I
117
+ ),
118
+
119
+ # 11. RAW MEMORY OVERRIDES (From previous context)
120
+ "memory_corruption": re.compile(
121
+ r'\b(?:malloc|calloc|realloc|free|memcpy|memset|memmove|strcpy|strcat|sprintf)\b\s*\(|'
122
+ r'\b(?:asm|__asm__|__asm)\b\s*[\(\{]',
123
+ re.I
124
+ )
125
+ }
126
+
127
+ def scan_content(self, file_content, total_loc):
128
+ """
129
+ Scans raw text and returns the raw hits for the engine to aggregate.
130
+ """
131
+ hits = {key: len(pattern.findall(file_content)) for key, pattern in self.THREAT_SIGNATURES.items()}
132
+ return hits
133
+
134
+ def evaluate_risk(self, aggregated_hits, total_loc):
135
+ """
136
+ Takes the raw physics hits, calculates the density, and checks
137
+ if it breaches the dynamically injected policy thresholds.
138
+ """
139
+ # Prevent division by zero
140
+ loc_safe = total_loc if total_loc > 0 else 1
141
+
142
+ exposures = {}
143
+
144
+ # 1. Hidden Malware Risk (Combines heat, bitwise math, and shadow imports)
145
+ malware_hits = aggregated_hits.get("heat_triggers", 0) + aggregated_hits.get("bitwise_hits", 0) + aggregated_hits.get("shadow_imports", 0) + aggregated_hits.get("homoglyphs", 0)
146
+ malware_density = malware_hits / loc_safe
147
+ if malware_density >= self.policy["hidden_malware_threshold"]:
148
+ exposures["Hidden Malware Risk"] = malware_density
149
+
150
+ # 2. Logic Bomb / Sabotage Risk
151
+ sabotage_hits = aggregated_hits.get("graveyard", 0) + (aggregated_hits.get("danger", 0) * 1.5)
152
+ sabotage_density = sabotage_hits / loc_safe
153
+ if sabotage_density >= self.policy["logic_bomb_threshold"]:
154
+ exposures["Logic Bomb Risk"] = sabotage_density
155
+
156
+ # 3. Data Injection Risk
157
+ injection_hits = aggregated_hits.get("io", 0) + aggregated_hits.get("danger", 0) + aggregated_hits.get("flux", 0)
158
+ injection_density = injection_hits / loc_safe
159
+ if injection_density >= self.policy["injection_surface_threshold"]:
160
+ exposures["Data Injection Risk"] = injection_density
161
+
162
+ # 4. Memory Corruption Risk
163
+ memory_hits = aggregated_hits.get("memory_corruption", 0)
164
+ memory_density = memory_hits / loc_safe
165
+ if memory_density >= self.policy["memory_corruption_threshold"]:
166
+ exposures["Memory Corruption Risk"] = memory_density
167
+
168
+ # 5. Secrets Risk (Highly sensitive)
169
+ secrets_hits = aggregated_hits.get("private_info", 0)
170
+ secrets_density = secrets_hits / loc_safe
171
+ if secrets_density >= self.policy["secrets_risk_threshold"]:
172
+ exposures["Secrets Leak Risk"] = secrets_density
173
+
174
+ return exposures
@@ -12,7 +12,7 @@ import logging
12
12
  import re
13
13
  import statistics
14
14
  from typing import Dict, Any, List, Optional, Tuple
15
- from . import gitgalaxy_standards_v011 as config
15
+ from . import gitgalaxy_standards_v1 as config
16
16
 
17
17
  # ==============================================================================
18
18
  # GitGalaxy Phase 4: Signal Processor (The Physics Engine)
@@ -78,8 +78,68 @@ class SignalProcessor:
78
78
  self.risk_tuning = getattr(config, "RISK_EQUATION_TUNING", {})
79
79
  self.is_paranoid = self.config.get("PARANOID_MODE", False)
80
80
 
81
- self.logger.info(f"Signal Processor Online | 13-Point Risk Schema loaded.")
81
+ # ======================================================================
82
+ # THE CONTEXT VS. ENTITY MATRIX (Domain Ontologies)
83
+ # ======================================================================
84
+ # We now fetch this dynamically from gitgalaxy_standards_v1.py instead of hardcoding it!
85
+ security_profiles = getattr(config, "LANGUAGE_SECURITY_PROFILES", {})
86
+ self.ECOSYSTEMS = security_profiles.get("ECOSYSTEMS", {})
87
+ self.NATIVE_WEIGHTS = security_profiles.get("NATIVE_WEIGHTS", {})
88
+ self.ALIEN_WEIGHTS = security_profiles.get("ALIEN_WEIGHTS", {})
89
+
90
+ self.logger.info(f"Signal Processor Online | Context-Aware Security Profiles loaded.")
91
+
92
+ # Aggressive penalties applied when the file is an ALIEN in its neighborhood
93
+ self.ALIEN_WEIGHTS = {
94
+ "systems_in_web": {"memory": 5.0, "logic_bomb": 3.0}, # C code hiding in a JS app = Trojan
95
+ "infra_in_web": {"logic_bomb": 4.0}, # Shell script hiding in a JS app = Backdoor
96
+ "web_in_systems": {"flux": 3.0} # JS embedded in C firmware = Bizarre architecture
97
+ }
98
+
99
+ self.logger.info(f"Signal Processor Online | Context-Aware Risk Schema loaded.")
100
+
101
+ def _get_context_multipliers(self, file_lang: str, folder_lang: str) -> Dict[str, float]:
102
+ """
103
+ Calculates risk multipliers by comparing a file's language to its neighborhood.
104
+ Prevents the 'Apollo Paradox' and catches 'Trojan Horse' entities.
105
+ """
106
+ # Default multipliers if no specific context rules apply
107
+ multipliers = {"memory": 1.0, "logic_bomb": 1.0, "flux": 1.0, "injection": 1.0}
108
+
109
+ file_lang = file_lang.lower()
110
+ folder_lang = folder_lang.lower() if folder_lang else file_lang
111
+
112
+ # Determine the ecosystem of the specific File
113
+ file_eco = "backend" # Default fallback
114
+ for eco, langs in self.ECOSYSTEMS.items():
115
+ if file_lang in langs:
116
+ file_eco = eco
117
+ break
118
+
119
+ # Determine the ecosystem of the surrounding Folder
120
+ folder_eco = "backend"
121
+ for eco, langs in self.ECOSYSTEMS.items():
122
+ if folder_lang in langs:
123
+ folder_eco = eco
124
+ break
125
+
126
+ # SCENARIO 1: The Entity matches the Context (Native)
127
+ if file_eco == folder_eco:
128
+ return self.NATIVE_WEIGHTS.get(file_eco, multipliers)
129
+
130
+ # SCENARIO 2: The Entity is an Alien (Context Mismatch)
131
+ alien_key = f"{file_eco}_in_{folder_eco}"
132
+ alien_penalties = self.ALIEN_WEIGHTS.get(alien_key, {})
133
+
134
+ # Apply standard weights of the file, but overwrite with severe alien penalties
135
+ base_weights = self.NATIVE_WEIGHTS.get(file_eco, multipliers).copy()
136
+ base_weights.update(alien_penalties)
137
+
138
+ if alien_penalties:
139
+ self.logger.warning(f"👽 ALIEN ENTITY DETECTED: {file_lang} file hiding in a {folder_eco} neighborhood. Applying severe penalties: {alien_penalties}")
82
140
 
141
+ return base_weights
142
+
83
143
  def _calculate_silo_risk(self, authors: dict) -> float:
84
144
  """
85
145
  Calculates the 'Bus Factor' risk of a file.
@@ -173,8 +233,13 @@ class SignalProcessor:
173
233
  fc = self.TIER_VARS[tier]["fc"]
174
234
  irc = self.TIER_VARS[tier]["irc"]
175
235
 
176
- # Environmental Context
236
+ # Environmental Context (Path-based overrides)
177
237
  mp_map = self._get_locational_multipliers(rel_path)
238
+
239
+ # ---> NEW: Context vs. Entity Ontology Matrix <---
240
+ # Fetch the folder's dominant language (Assumes your upstream parser injects this)
241
+ folder_lang = meta.get("metadata", {}).get("folder_dominant_lang", lang_id)
242
+ eco_mp = self._get_context_multipliers(lang_id, folder_lang)
178
243
 
179
244
  self.logger.debug(f"[{rel_path}] Physics Calc | Lang: {lang_id} (Fc: {fc:.2f}, Irc: {irc})")
180
245
 
@@ -223,9 +288,9 @@ class SignalProcessor:
223
288
  "civil_war": self._calc_civil_war(equations),
224
289
  # --- THE SECURITY & VULNERABILITY LENSES ---
225
290
  "obscured_payload": self._calc_obscured_payload(loc, equations, mp_map.get("obscured", 1.0)),
226
- "logic_bomb": self._calc_logic_bomb(loc, equations, mp_map.get("logic_bomb", 1.0)),
227
- "injection_surface": self._calc_injection_surface(loc, equations, mp_map.get("injection", 1.0)),
228
- "memory_corruption": self._calc_memory_corruption(loc, equations, mp_map.get("memory", 1.0), lang_id),
291
+ "logic_bomb": self._calc_logic_bomb(loc, equations, mp_map.get("logic_bomb", 1.0) * eco_mp.get("logic_bomb", 1.0)),
292
+ "injection_surface": self._calc_injection_surface(loc, equations, mp_map.get("injection", 1.0) * eco_mp.get("injection", 1.0)),
293
+ "memory_corruption": self._calc_memory_corruption(loc, equations, mp_map.get("memory", 1.0) * eco_mp.get("memory", 1.0), lang_id),
229
294
  "secrets_risk": self._calc_secrets_risk(loc, equations, mp_map.get("secrets", 1.0))
230
295
  }
231
296
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: gitgalaxy
3
- Version: 1.0.9
3
+ Version: 1.1.2
4
4
  Summary: A high-speed static analysis engine that sequences source code like DNA to map architectural risk and security threats.
5
5
  Author: Joe Esquibel
6
6
  License: PolyForm Noncommercial License 1.0.0
@@ -7,7 +7,7 @@ gitgalaxy/audit_recorder.py
7
7
  gitgalaxy/chronometer.py
8
8
  gitgalaxy/detector.py
9
9
  gitgalaxy/galaxyscope.py
10
- gitgalaxy/gitgalaxy_standards_v011.py
10
+ gitgalaxy/gitgalaxy_standards_v1.py
11
11
  gitgalaxy/gpu_recorder.py
12
12
  gitgalaxy/guidestar_lens.py
13
13
  gitgalaxy/language_lens.py
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "gitgalaxy"
7
- version = "1.0.9"
7
+ version = "1.1.2"
8
8
  authors = [
9
9
  { name="Joe Esquibel" },
10
10
  ]
@@ -1,181 +0,0 @@
1
- import re
2
- import copy
3
- import logging
4
- from typing import Dict, Any
5
-
6
- # ==============================================================================
7
- # GitGalaxy Security Lens (Passive Threat Observer)
8
- # Protocol: Glassworm, Trojan, and Exfiltration Hunting
9
- # ==============================================================================
10
-
11
- class SecurityLens:
12
- """
13
- PURPOSE:
14
- Acts as a Passive Observer within the GitGalaxy Physics Engine.
15
- It runs alongside the standard architectural audit, silently collecting
16
- malicious intent, obfuscation, and exfiltration metrics into RAM.
17
-
18
- MECHANISM:
19
- Injects high-priority threat signatures into the primary language rulesets
20
- using a 'sec_' prefix. This ensures standard metrics (like tech debt) are
21
- calculated normally, while security anomalies are passively cached for later extraction.
22
- """
23
-
24
- def __init__(self, parent_logger: logging.Logger = None):
25
- self.logger = parent_logger.getChild("security_lens") if parent_logger else logging.getLogger("security_lens")
26
- self.logger.setLevel(logging.INFO)
27
-
28
- # ======================================================================
29
- # THE THREAT REGISTRY (Security Overlay V2 - O(N) Safe)
30
- # ======================================================================
31
- self.THREAT_SIGNATURES = {
32
- # ------------------------------------------------------------------
33
- # 1. THE GLASSWORM (Obfuscation & Heat Signatures)
34
- # Targets decoding functions, massive blobs, and invisible steganography.
35
- # ------------------------------------------------------------------
36
- "heat_triggers": re.compile(
37
- r'\b(?:atob|btoa|base64_decode|base64_encode|gzuncompress|str_rot13)\b|'
38
- r'\\x[0-9a-fA-F]{2}|\\u[0-9a-fA-F]{4}|'
39
- r'(?:\w{15,}[ \t]*=[ \t]*["\'][A-Za-z0-9+/]{40,}={0,2}["\'])|'
40
- r'[\u200B-\u200D\uFEFF\u200E\u200F\u202A-\u202E]', # Invisible Unicode
41
- re.I
42
- ),
43
-
44
- # ------------------------------------------------------------------
45
- # 2. THE TROJAN (Identity Masking & Safety Bypasses)
46
- # Targets cross-algorithm double-decoding and runtime security downgrades.
47
- # ------------------------------------------------------------------
48
- "safety_neg": re.compile(
49
- r'\b(?:atob|btoa|base64_decode|gzinflate|gzuncompress|str_rot13|urldecode)[ \t]*\([ \t]*(?:atob|btoa|base64_decode|gzinflate|gzuncompress|str_rot13|urldecode)\b|'
50
- r'\b(?:auto_prepend_file|auto_append_file)\b|'
51
- r'\b(?:ini_set|ini_restore|putenv)[ \t]*\([ \t]*["\'](?:disable_functions|safe_mode|open_basedir|allow_url_fopen)["\'][ \t]*,[ \t]*["\']?(?:0|off|false|)["\']?\)|'
52
- r'\b(?:disable_functions|safe_mode|open_basedir)\b[ \t]*=[ \t]*(?:off|0|false|""|\'\')|'
53
- r'process\.env\.NODE_TLS_REJECT_UNAUTHORIZED[ \t]*=[ \t]*["\']?0["\']?|'
54
- r'\b(?:verify|strictSSL|rejectUnauthorized|CURLOPT_SSL_VERIFYPEER)[ \t]*[=:,][ \t]*(?:False|false|0)\b',
55
- re.I
56
- ),
57
-
58
- # ------------------------------------------------------------------
59
- # 3. EXFILTRATION VECTORS (System Gravity)
60
- # Targets dynamic outbound connections, tunneling proxies, and DNS exfiltration.
61
- # ------------------------------------------------------------------
62
- "io": re.compile(
63
- r'\b(?:fetch|XMLHttpRequest|WebSocket|http\.request|https\.request|requests\.(?:post|put|get)|urllib\.request\.urlopen)\b\s*\(|'
64
- r'\b(?:curl_exec|fsockopen|pfsockopen|stream_socket_client|file_get_contents)\b\s*\(|'
65
- r'\b(?:dns_get_record|gethostbyname|socket\.gethostbyname|resolve(?:4|6|Cname|Txt)?)\b\s*\(|'
66
- r'(?:https?|ftp|tcp|udp|wss?):\/\/(?:(?:\d{1,3}\.){3}\d{1,3}|\[[0-9a-fA-F:]+\]|.*?\.(?:ngrok\.io|ngrok-free\.app|localtunnel\.me|pastebin\.com|workers\.dev|s3\.amazonaws\.com|requestbin\.net|pipedream\.net))',
67
- re.I | re.X
68
- ),
69
-
70
- # ------------------------------------------------------------------
71
- # 4. THE EXECUTIONER (Dynamic Payloads)
72
- # HARDENED: Unbounded repetitions clamped to prevent ReDoS on minified code.
73
- # ------------------------------------------------------------------
74
- "danger": re.compile(
75
- r'\b(?:eval|Function|setTimeout|setInterval)\b\s*\(\s*(?:atob|base64|["\']|`)|'
76
- r'\b(?:document\.write|location\.replace|assert|create_function|passthru|shell_exec|system)\b|'
77
- r'child_process\.(?:exec|spawn|fork)|'
78
- # Clamped string concatenation to {1,15} to kill exponential backtracking
79
- r'(?:window|global|this|globalThis)\[[ \t]*(?:["\'][a-zA-Z]["\'][ \t]*\+[ \t]*){1,15}["\'][a-zA-Z]["\'][ \t]*\][ \t]*\(|'
80
- r'\$[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*\s*\(\s*\$_(?:POST|GET|COOKIE|REQUEST|HEADERS)|'
81
- r'getattr\s*\(\s*__import__\s*\(|__builtins__\[|Assembly\.Load\s*\(',
82
- re.I | re.X
83
- ),
84
-
85
- # ------------------------------------------------------------------
86
- # 5. ENVIRONMENT POISONING (State Flux)
87
- # Targets prototype pollution, native function hooking, and global overrides.
88
- # ------------------------------------------------------------------
89
- "flux": re.compile(
90
- r'\b[A-Za-z0-9_]+\.prototype\.[A-Za-z0-9_]+[ \t]*=|'
91
- r'\.__proto__[ \t]*=[ \t]*[{a-zA-Z]|'
92
- r'\b(?:window|global|globalThis|document)\.(?:fetch|eval|setTimeout|setInterval|Promise|console|JSON)[ \t]*=|'
93
- r'\$(?:GLOBALS|_(?:SERVER|GET|POST|COOKIE|REQUEST|ENV|SESSION))\[[^\]]+\][ \t]*=[ \t]*[^=]|'
94
- r'\bextract[ \t]*\([ \t]*\$(?:_(?:GET|POST|REQUEST|COOKIE)|GLOBALS)\b|'
95
- r'\b__builtins__\[[^\]]+\][ \t]*=|'
96
- r'\bsys\.modules\[[^\]]+\][ \t]*=',
97
- re.I
98
- ),
99
-
100
- # ------------------------------------------------------------------
101
- # 6. SHADOW LOGIC (Necrosis / Graveyard)
102
- # O(N) SAFE: Fast block scanning bounded to 500 chars to prevent ReDoS.
103
- # ------------------------------------------------------------------
104
- "graveyard": re.compile(
105
- r'(?://|#|--)[^\n]*?\b(?:http|bash|curl|wget|eval|base64|nc\s+-e|/dev/tcp)\b|'
106
- r'/\*(?:(?!\*/).){0,500}?\b(?:http|bash|curl|wget|eval|base64|nc\s+-e|/dev/tcp)\b',
107
- re.I
108
- ),
109
-
110
- # ------------------------------------------------------------------
111
- # 7. SUB-ATOMIC DECRYPTION (Bitwise Hits)
112
- # HARDENED: Replaced .*? with bounded character exclusions.
113
- # ------------------------------------------------------------------
114
- "bitwise_hits": re.compile(
115
- # Clamped to {2,20} and {3,20} to prevent infinite runaway loops on data arrays
116
- r'\b\w+[ \t]*=[ \t]*(?:\w+[ \t]*\^[ \t]*\w+[ \t]*){2,20}|'
117
- r'(?:\w+\[[^\]\n]{1,50}\][ \t]*\^[ \t]*=?[ \t]*(?:0x[0-9a-fA-F]+|\d+|\w+)[ \t]*;[ \t]*){3,20}',
118
- re.I
119
- ),
120
- # ------------------------------------------------------------------
121
- # 8. SHADOW IMPORTS (The Switcharoo / Steganography)
122
- # Targets legitimate code attempting to import, require, or execute
123
- # payloads hidden inside non-executable media or data files.
124
- # ------------------------------------------------------------------
125
- "shadow_imports": re.compile(
126
- r'\b(?:require|include|import|require_once|include_once|source|load|dofile)\b\s*\(?\s*'
127
- r'["\'][^"\']+\.(?:png|jpg|jpeg|gif|ico|pdf|zip|tar|dat|tmp|log|txt|csv|wav|mp3)["\']',
128
- re.I
129
- ),
130
- # ------------------------------------------------------------------
131
- # 9. UNICODE SMUGGLING (Homoglyphs & Typosquatting)
132
- # Targets look-alike characters (Cyrillic, Greek, Hangul Filler)
133
- # used to hijack legitimate imports or disguise network requests.
134
- # ------------------------------------------------------------------
135
- "homoglyphs": re.compile(
136
- r'\b(?:import|from|require|include|require_once|fetch|XMLHttpRequest)\b'
137
- r'[^\n]*?(?:[\u0400-\u04FF]|' # Cyrillic (e.g., false 'a', 'e', 'o')
138
- r'[\u0370-\u03FF]|' # Greek
139
- r'[\u1D400-\u1D7FF]|' # Math Alphanumerics
140
- r'\u3164)', # Hangul Filler (Invisible whitespace)
141
- re.I
142
- ),
143
- # ------------------------------------------------------------------
144
- # 10. THE VAULT DOOR (Credential & Secret Leaks)
145
- # Universal RHS-aware secret detection. Demands string literals
146
- # of at least 16 characters to prevent false positives on booleans/ints.
147
- # ------------------------------------------------------------------
148
- "private_info": re.compile(
149
- r"\b(password|secret|token|api[_-]?key|client[_-]?secret|credentials|private[_-]?key|auth[_-]?token)\b[ \t]*(?:[:=]|=>)[ \t]*[\"'][A-Za-z0-9\-_+/=]{16,}[\"']",
150
- re.I
151
- ),
152
- }
153
-
154
- def arm_lens(self, base_registry: Dict[str, Any], target_languages: list = None) -> Dict[str, Any]:
155
- """
156
- Injects the threat signatures as PASSIVE OBSERVERS into the registry.
157
- They will be scanned by the Splicer and cached in RAM, but will NOT destroy
158
- the standard architectural calculations.
159
- """
160
- self.logger.info("Arming Security Lens: Injecting Passive Observers into Registry...")
161
-
162
- secure_registry = copy.deepcopy(base_registry)
163
-
164
- if not target_languages:
165
- target_languages = ['javascript', 'typescript', 'php', 'python', 'ruby', 'shell', 'powershell']
166
-
167
- for lang in target_languages:
168
- if lang in secure_registry and 'rules' in secure_registry[lang]:
169
- rules = secure_registry[lang]['rules']
170
-
171
- # --- PASSIVE OBSERVER INJECTION ---
172
- for dimension, threat_regex in self.THREAT_SIGNATURES.items():
173
- # By prefixing with "sec_", we preserve the original "io" or "danger" rules
174
- # The Splicer automatically scans any key in this dictionary, meaning
175
- # these hits will quietly accumulate in the file's 'equations' output in RAM.
176
- rules[f"sec_{dimension}"] = threat_regex
177
-
178
- self.logger.debug(f"Passive Security Sensors attached to '{lang}'.")
179
-
180
- self.logger.info(f"Passive Security Lens active across {len(target_languages)} ecosystems.")
181
- return secure_registry
File without changes
File without changes
File without changes