Files
rengine/tests/api/test_program_coverage.py
T
Yogesh OjhaandClaude Opus 5 a180a3020a feat(bounty-hub): say which program covers a target
The scope link ran one way: a program's scope showed whether each entry was
already a target. The question a hunter asks is the other one - I have this
asset, who pays for it - and nothing answered it.

`ProgramCoverageService` matches a host against every synced program's scope
through the machinery a watch already uses (`plan_scope`, `WatchItem.matches`,
`excluded_by`), so a wildcard entry covers its subtree, an exact entry covers
itself, and a program's own out-of-scope rows mark the match excluded rather
than hiding it. Measured against 7,173 synced scope rows on this instance:
`foo.bugcrowd.com` and `deep.nested.bugcrowd.com` resolve to Bugcrowd through
`*.bugcrowd.com/auth/*`, `notacme.com` is not a subtree of `*.acme.com`, and
`allegro.cz` comes back uncovered because that program lists it out of scope.

The target page carries it in the rail as Bounty: the program, its platform
and the scope entry that covers the target, hidden outside bug bounty mode.
`for_host` takes a bare hostname so a discovered asset can be asked the same
question next.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YYop31s6BqDUt4TBs5mbwa
2026-09-12 23:05:47 +05:30

61 lines
1.8 KiB
Python

from __future__ import annotations
import uuid
from dataclasses import dataclass, field
import pytest
from app.services.program_coverage import host_of, scope_match
from shared.definitions.bounty_programs import ScopeState
from shared.enums.target import TargetType
pytestmark = pytest.mark.api
@dataclass
class Scope:
asset_identifier: str
target_value: str
scope_state: str = ScopeState.IN_SCOPE.value
target_type: TargetType = TargetType.DOMAIN
id: uuid.UUID = field(default_factory=uuid.uuid4)
def _scope(
identifier: str, value: str, state: str = ScopeState.IN_SCOPE.value
) -> Scope:
return Scope(asset_identifier=identifier, target_value=value, scope_state=state)
def test_a_wildcard_scope_covers_the_subtree():
scopes = [_scope("*.acme.com", "acme.com")]
assert scope_match("shop.acme.com", scopes)[0] is not None
assert scope_match("acme.com", scopes)[0] is not None
def test_an_exact_scope_covers_only_itself():
scopes = [_scope("www.acme.com", "www.acme.com")]
assert scope_match("www.acme.com", scopes)[0] is not None
assert scope_match("shop.acme.com", scopes)[0] is None
def test_a_suffix_is_not_a_subtree():
scopes = [_scope("*.acme.com", "acme.com")]
assert scope_match("notacme.com", scopes)[0] is None
def test_an_out_of_scope_entry_is_reported_as_excluded():
scopes = [
_scope("*.acme.com", "acme.com"),
_scope("*.lab.acme.com", "lab.acme.com", ScopeState.OUT_OF_SCOPE.value),
]
scope, excluded = scope_match("box.lab.acme.com", scopes)
assert scope is not None
assert excluded
def test_a_url_scope_is_read_as_its_host():
assert host_of("https://shop.acme.com/login") == "shop.acme.com"
assert host_of("*.acme.com") == "acme.com"
assert host_of("acme.com:8443") == "acme.com"