VR/USEM Compensating Control OOTB hardcoded substate == '25' in SI ExceptionSettingsAJAX

Branimir Morfov
Tera Contributor

Why Hardcoding substate == '25' in VR AJAX  Logic "ExceptionSettingsAJAX" Is a Bad Practice

 

OOTB Facts:

1. As we know, selecting Mitigating Control (or substate 25) as a reason in "review_exception" UI Page as a reason, acts as a trigger for the defaultly set Compensating Control Questionarie. 

2. The substates are defined in two different tables for sn_vul_vulnerability and sn_vul_vulnerable_item, 

3. Mitigating Control reason in both tables has the same ID of 25 (nice one ServiceNow)

4. In the Script Include "ExceptionSettingsAJAX" there is only one condition triggered by state, obviously for both tables where it has a match (see point 3)

 

In Vulnerability Response, it may be tempting to use a hardcoded check such as object.substate == '25' inside an AJAX Script Include to decide whether to launch the compensating control questionnaire. On the surface, this seems harmless, especially when both sn_vul_vulnerability and sn_vul_vulnerable_item currently use the same substate value 25 for Mitigating Control in Place.

However, this is still a bad design choice and should be replaced with a system property or a configurable mapping.

 

The issue is not whether 25 works today. The issue is that the logic assumes that:

- Both source tables will always keep the same internal choice value
- The value 25 will always represent Mitigating Control in Place
- No future admin or implementation team will change the choice configuration
- Every environment will stay aligned after clone, customization, or upgrade That is too much hidden coupling for a business-critical decision.

Why this is risky?

Hardcoding 25 creates a fragile dependency between server-side code and choice metadata. Choice values are configuration, not business logic constants. Even if both VUL and VIT currently share the same value, that is an implementation detail, not something the AJAX layer should assume forever.

Main risks:

- A future admin may change the substate value on one table and not the other.
- One environment may drift from another during implementation or testing.
- The code becomes harder to understand because the meaning of 25 is not self-documenting.
- Troubleshooting becomes slower because the questionnaire path depends on an invisible magic number.
- Any business change requires a code update instead of a simple configuration change.

 

Why a property is better?

This decision should be externalized into configuration. A system property makes the logic:

- easier to understand
- easier to support
- safer across environments
- easier to change without modifying script logic

 

A property-based approach also makes the intent explicit. Instead of asking “why 25?”, the code asks “does this substate match the configured compensating-control reason?”

 

Recommended design
At minimum, replace the hardcoded value with a property such as:

sn_vul.compensating_control_substate

For a stronger design, use separate properties per table:

sn_vul.comp_ctrl_substate_vul
sn_vul.comp_ctrl_substate_vit


That is the better long-term pattern because sn_vul_vulnerability and sn_vul_vulnerable_item are different tables and should not be forced to share the same internal value forever.

 

Best-practice conclusion

Even if substate = 25 is currently identical on both VUL and VIT tables, keeping that value hardcoded in the AJAX logic is not best practice. It embeds configuration into code, creates an avoidable maintenance risk, and makes future changes harder than they need to be.

 

The better design is to move the trigger value into a system property, or even better, table-specific properties. That keeps the logic configurable, explicit, and resilient across environments and future updates.

0 REPLIES 0