Skip to content

[Recorded Future] Missing criticality level 5 ("Very Critical") in RISK_RULES_MAPPER — critical rules silently dropped #6256

@Lhorus6

Description

@Lhorus6

Description

Recorded Future has introduced a new risk rule criticality level 5 labeled "Very Critical" in their API responses.
Example with the 'CVE-2025-66376':

Image

The current [RISK_RULES_MAPPER](https://github.com/OpenCTI-Platform/connectors/blob/49147f7f81a7231faad44038be95563d86c254ff/external-import/recorded-future/src/rflib/constants.py#L33) in rflib/constants.py only maps criticality levels 0 through 4, causing all rules with criticality: 5 to be silently ignored during ingestion.

Image

This is particularly impactful because criticality 5 rules represent the most severe threat intelligence signals.

Environment

OCTI v7.260317.0

Reproducible Steps

Steps to create the smallest reproducible scenario:

  1. Deploy the Recorded Future connector to ingest Risk List Vulnerability
  2. Identifies a vulnerability with rule_score == 5 and check it in OpenCTI

Example of vulnerability with a rule_score == 5: the 'CVE-2025-66376

Expected Output

Retrieve all the risk rules

Actual Output

Rules with criticality: 5 are dropped without any log warning or error. The matching loop in risk_list.py iterates over RISK_RULES_MAPPER and finds no entry where rule_score == 5, so:

  • ❌ The rule is not added to the entity description
  • ❌ The rule is not added as a label
  • ❌ No warning or error is logged

Proposed fix

Add the missing criticality level

HERE

RISK_RULES_MAPPER = [
    {"rule_score": 0, "severity": "No current evidence of risk", "risk_score": "0"},
    {"rule_score": 1, "severity": "Unusual", "risk_score": "5-24"},
    {"rule_score": 2, "severity": "Suspicious", "risk_score": "25-64"},
    {"rule_score": 3, "severity": "Malicious", "risk_score": "65-89"},
    {"rule_score": 4, "severity": "Very Malicious", "risk_score": "90-99"},
    {"rule_score": 5, "severity": "Very Critical", "risk_score": "99"},
]

Add a fallback mechanism for unknown criticality levels

HERE and HERE

matched = False
for corresponding_rule in RISK_RULES_MAPPER:
    if rule_criticality == corresponding_rule["rule_score"]:
        matched = True
        # existing processing logic
        break

if not matched:
    self.helper.connector_logger.warning(
        f"[RISK LIST] Unknown criticality level: {rule_criticality} for rule: {risk_rule_name}. "
        "Please update RISK_RULES_MAPPER in constants.py."
    )
    # Fallback: still ingest the rule with unknown severity
    labels.append(risk_rule_name)

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions