Skip to content

bug: Investigation.tlp and Investigation.tags omit descendant jobs and return inconsistent types #4061

Description

@harshitnub077

What happened

In IntelOwl, an Investigation associates with root jobs via Investigation.jobs. When subsequent pivots or playbook actions are executed within the investigation, the resulting child jobs are organized hierarchically as descendants in the job tree (django-treebeard MP_Node).

Currently, Investigation.tags and Investigation.tlp in api_app/investigations_manager/models.py only query self.jobs:

    @property
    def tags(self) -> List[str]:
        return list(set(self.jobs.values_list("tags__label", flat=True)))

    @property
    def tlp(self) -> TLP:
        return (
            max(TLP[tlp_string] for tlp_string in self.jobs.values_list("tlp", flat=True))
            if self.jobs.exists()
            else TLP.CLEAR.value
        )

This causes several concrete bugs:

  1. Omission of Descendant Job TLPs (Security / Data Classification Leak): If a root job is submitted with TLP:CLEAR and a subsequent pivot job analyzes an observable marked with TLP:AMBER or TLP:RED, investigation.tlp ignores all descendant jobs and evaluates to TLP.CLEAR. This surfaces an inaccurate classification in summarize_investigation (api_app/chatbot_manager/agent/tools/summarize_investigation.py:57), REST serializers (InvestigationSerializer), and the TLP filter (InvestigationFilter.filter_for_tlp).
  2. Omission of Descendant Job Tags: Tags attached to pivoted or child jobs are excluded from investigation.tags, breaking tag filtering (filter_for_tags) and chatbot investigation summaries.
  3. Inconsistent Return Type on Empty Investigations: Investigation.tlp declares -> TLP:. When self.jobs.exists() is False, it returns TLP.CLEAR.value (a str), whereas when jobs exist, it returns a TLP enum instance (TLP.CLEAR). Callers relying on enum properties (e.g., investigation.tlp.value) raise AttributeError: 'str' object has no attribute 'value' when an investigation has no jobs.
  4. Defects in TLP Enum Comparison (api_app/choices.py):
    • __compare raises TypeError(f"Can sum {self.__class__.__name__} with {type(other)}") instead of "Cannot compare".
    • TLP only defines __lt__ and __gt__, omitting __le__ and __ge__ and failing when compared against raw valid TLP string values.

Environment

  1. OS: Linux / macOS
  2. IntelOwl version: develop (commit 862df0a)

What did you expect to happen

  1. Investigation.tlp should evaluate the maximum TLP across all jobs in the investigation tree (both root jobs and descendant nodes), returning TLP.CLEAR as a consistent TLP instance when empty.
  2. Investigation.tags should aggregate distinct tags across both root and descendant jobs in the investigation tree.
  3. TLP comparisons should support complete comparison operators (<=, >=, <, >) and cleanly compare with valid string representations.

How to reproduce your issue

from api_app.investigations_manager.models import Investigation
from api_app.models import Job, Analyzable
from api_app.choices import Classification

# 1. Type inconsistency on empty investigation
empty_inv = Investigation.objects.create(name="Empty", owner=user)
print(type(empty_inv.tlp))  # <class 'str'> instead of <enum 'TLP'>

# 2. Descendant job TLP omission
analyzable = Analyzable.objects.create(name="target.com", classification=Classification.DOMAIN)
root_job = Job.objects.create(analyzable=analyzable, user=user, tlp="CLEAR")
inv = Investigation.objects.create(name="Pivot Test", owner=user)
inv.jobs.add(root_job)

# Add a child job with higher TLP
child_job = root_job.add_child(analyzable=analyzable, user=user, tlp="RED")
inv.refresh_from_db()

print(inv.tlp)  # CLEAR instead of RED

Error messages and logs

When accessing .value or enum attributes on an empty investigation:

AttributeError: 'str' object has no attribute 'value'

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions