T09 · Insecure Skill Coding Practices
- Location
scripts/main.py:15- Finding
Unsafe First-Match Chemical Classification Produces False Compatibility Results
- Content
View full analysis
Vulnerability Details
File Location:
scripts/main.py:15-94
Vulnerability Type: Unsafe classification and fail-open compatibility logic
Risk Level: HighVulnerable Code
python COMPATIBILITY_GROUPS = { "acids": { "compatible": ["acids"], "incompatible": ["bases", "oxidizers", "cyanides", "sulfides"], "examples": ["HCl", "H2SO4", "HNO3", "acetic acid"] }, "bases": { "compatible": ["bases"], "incompatible": ["acids", "oxidizers", "halogenated"], "examples": ["NaOH", "KOH", "ammonia", "Trizma"] }, "flammables": { "compatible": ["flammables"], "incompatible": ["oxidizers", "acids"], "examples": ["ethanol", "methanol", "acetone", "hexane"] }, "oxidizers": { "compatible": ["oxidizers"], "incompatible": ["flammables", "acids", "bases", "reducing"], "examples": ["H2O2", "KMnO4", "sodium hypochlorite", "nitric acid"] }, "toxics": { "compatible": ["toxics"], "incompatible": ["acids", "oxidizers"], "examples": ["cyanide salts", "arsenic compounds", "mercury"] }, "general": { "compatible": ["general", "salts", "buffers"], "incompatible": [], "examples": ["NaCl", "PBS", "sucrose", "glycerol"] } } def classify_chemical(self, name): """Classify chemical into storage group.""" name_lower = name.lower() for group, data in self.COMPATIBILITY_GROUPS.items(): for example in data["examples"]: if example.lower() in name_lower: return group # Check keywords acid_keywords = ["acid", "hcl", "sulfuric", "nitric", "acetic"] base_keywords = ["hydroxide", "naoh", "koh", "ammonia", "amine"] flammable_keywords = ["ethanol", "methanol", "acetone", "ether", "hexane"] oxidizer_keywords = ["peroxide", "permanganate", " ...[truncated 4085 chars]- Remediation
View remediation
Remediation Suggestions
- Replace the single-value classifier with a model that returns every applicable hazard class, such as
{"acids", "oxidizers"}. - Evaluate compatibility across all hazard-class combinations. Any incompatible combination should make the overall result incompatible.
- Remove the assumption that equal broad groups are automatically compatible. Require explicit chemical-specific or reviewed compatibility data.
- Return an
unknownorreview_requiredstatus for unrecognized chemicals instead of silently assigning them togeneral. - Require manual SDS or EHS verification for unknown names, mixtures, proprietary products, ambiguous matches, and multi-hazard chemicals.
- Use normalized identifiers such as CAS numbers or a curated chemical database instead of unrestricted substring matching.
- Add explicit precedence and multi-hazard rules for oxidizing acids and other overlapping categories.
- Distinguish definitive compatibility results from advisory results and display a prominent warning that automated classification is not a substitute for SDS review.
- Add regression tests covering:
- Nitric acid as both an acid and an oxidizer.
- Chemicals with multiple hazard classes.
- Two chemicals in the same broad group that are not automatically compatible.
- Unsupported hazardous names.
- Ambiguous substrings and mixtures.
- Empty and malformed input.
- Prevent storage-plan generation from placing
unknownorreview_requiredsubstances into ordinary storage groups until a qualified reviewer approves them.
- Replace the single-value classifier with a model that returns every applicable hazard class, such as
