Skip to content

Alert ip/range filter matches alerts whose decisions do not cover the address #4698

Open

Description

@AdzerKI

What happened?

The alert ip/range filter checks start_ip, end_ip and ip_size with three separate alert.HasDecisionsWith() predicates, so each bound can be met by a different decision of the same alert. An alert with many decisions, like the community blocklist, matches almost any address.

cscli alerts delete --ip 10.99.0.3 (a local test host) deleted 40 alerts on our LAPI, community blocklist alerts included: active CAPI decisions went from 23994 to 3536 until the next pull.

What did you expect to happen?

Only alerts with a decision that covers the address are matched.

How can we reproduce it?

Create one alert with ban decisions for 1.2.3.4 and 9.9.9.9, then query /v1/alerts?ip=5.5.5.5 or run cscli alerts list --ip 5.5.5.5: the alert is returned. Same for range=5.5.5.0/24&contains=false and for IPv6.

Anything else we need to know?

All the bounds belong in one alert.HasDecisionsWith(...), the way decisionIPv4Filter and decisionIPv6Filter do it for decisions. Fix with a test: AdzerKI@d0671d3b

Crowdsec version

Details
$ cscli version
version: v1.8.1-debian-pragmatic-amd64-909b5157
Codename: alphaga
BuildDate: 2026-09-03_10:57:01
GoVersion: 1.26.3
Platform: linux

pkg/database/alertfilter.go is the same on master.

OS version

Ubuntu 24.04

Activity

  1. github-actions commented on Sep 22, 2026

    @github-actions

    @AdzerKI: Thanks for opening an issue, it is currently awaiting triage.

    In the meantime, you can:

    1. Check Crowdsec Documentation to see if your issue can be self resolved.
    2. You can also join our Discord.
    3. Check Releases to make sure your agent is on the latest version.
    Details

    I am a bot created to help the crowdsecurity developers manage community feedback and contributions. You can check out my manifest file to understand my behavior and what I can do. If you want to use this for your project, you can check out the BirthdayResearch/oss-governance-bot repository.

  2. github-actions commented on Sep 22, 2026

    @github-actions

    @AdzerKI: There are no 'kind' label on this issue. You need a 'kind' label to start the triage process.

    • /kind feature
    • /kind enhancement
    • /kind refactoring
    • /kind bug
    • /kind packaging
    Details

    I am a bot created to help the crowdsecurity developers manage community feedback and contributions. You can check out my manifest file to understand my behavior and what I can do. If you want to use this for your project, you can check out the BirthdayResearch/oss-governance-bot repository.

  3. AdzerKI commented on Sep 23, 2026

    @AdzerKI
    Author

    /kind bug

  4. Healzangels commented on Oct 18, 2026

    @Healzangels

    Same here on the docker image, v1.8.1-909b5157 (Platform: docker), through the API rather than cscli.

    A watcher machine on an address in api.server.trusted_ips sent

    DELETE /v1/alerts?ip=192.0.2.123
    

    (TEST-NET-1, an address this LAPI had never seen) and got {"nbDeleted":"43"}. The 43 alerts were the community-blocklist pull alerts. Active decisions went from 18,439 to 232, and all of those were origin="crowdsec"; cs_active_decisions no longer had any CAPI series. No local alert matched: those carry one decision each, so all three bounds have to come from the same decision. A GET /v1/alerts with the same query lists the same alerts, which is the safe way to see the over-match first.

    Two notes that may help others until #4710 is merged:

    1. cscli alerts delete --ip is not a shorthand for --scope ip --value <IP>, despite its help text. SanitizeScope (cmd/crowdsec-cli/clialert/sanitize.go) only validates the address and normalises a scope that was passed, so the request carries ip= alone and goes down the same path. Passing --scope ip explicitly adds SourceScopeEQ("Ip"), which keeps the pull alerts out (their source scope is CommunityBlocklistPullSourceScope, or lists:<name> for blocklists). Either the help text or the flag handling could be aligned.
    2. Recovery: restarting crowdsec restored the full list right away. On start apic.startup is true, CAPIPullIsOld finds no CAPI alert younger than 1h30, and the startup pull asks for the whole list (added 15000 entries, deleted 0 entries). I didn't wait to see what a regular 2-hourly pull would have brought back.

    +1 for #4710: its single-HasDecisionsWith approach matches what decisionIPv4Filter/decisionIPv6Filter already do for decisions.

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

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions