Skip to content

Comments

fix: correctly filter IPs from CIDR during aggregation#684

Merged
Mzack9999 merged 1 commit intoprojectdiscovery:mainfrom
jjhwan-h:fix/ip-filtering
Sep 12, 2025
Merged

fix: correctly filter IPs from CIDR during aggregation#684
Mzack9999 merged 1 commit intoprojectdiscovery:mainfrom
jjhwan-h:fix/ip-filtering

Conversation

@jjhwan-h
Copy link
Contributor

@jjhwan-h jjhwan-h commented Sep 10, 2025

Summary

Fixes a regression where filtered IPs (-fi) were reintroduced after aggregation (-a).

Closes #523

Fix

  • If FilterIP is set:
    • expand pCidr into its IP list with getIPList
    • skip any IPs matching FilterIP
    • add remaining IPs back as /32 (or /128) CIDRs
    • do not append the original pCidr
  • Add guard when appending IPv4-mapped addresses:
    if ip4 := firstIP.To4(); ip4 != nil &&
       !(len(firstIP) == net.IPv6len && bytes.Equal(firstIP[:12], v4Mappedv6Prefix)) {
        firstIP = append(v4Mappedv6Prefix, ip4...)
    }
    

Summary by CodeRabbit

  • New Features
    • Filtering specific IPs during CIDR aggregation so resulting ranges exclude specified addresses.
  • Bug Fixes
    • Fixed handling of IPv4-mapped IPv6 inputs to avoid redundant mappings and ensure accurate range results.
  • Tests
    • Added coverage validating filtering combined with aggregation.
  • Style
    • Minor formatting and comment placement cleanup for readability.

@jjhwan-h jjhwan-h force-pushed the fix/ip-filtering branch 4 times, most recently from b60c971 to 18d432c Compare September 11, 2025 02:16
@coderabbitai
Copy link

coderabbitai bot commented Sep 11, 2025

Walkthrough

Adds logic to expand CIDRs to individual IP CIDRs when both FilterIP and Aggregate are set, exclude filtered IPs before aggregation, and adjusts IPv4→IPv6 mapping to avoid double-mapping for already-mapped addresses. Also adds a unit test covering the filtering+aggregation scenario.

Changes

Cohort / File(s) Summary
CLI processing: FilterIP + Aggregate path
cmd/mapcidr/main.go
Implements a branch that, when both FilterIP and Aggregate are enabled, enumerates IPs from input CIDRs, excludes FilterIP addresses, converts remaining addresses to single-IP CIDRs (/32 or /128), appends them for aggregation, and includes a minor formatting/comment relocation.
Tests for new behavior
cmd/mapcidr/main_test.go
Adds a TestProcess case "FilterIPWithAggregation" that exercises filtering prior to aggregation: input 10.0.0.0/30 with filter 10.0.0.1 and Aggregate=true expecting 10.0.0.0/32 and 10.0.0.2/31.
IP range mapping guard
ip.go
Updates ipNetToRange to only map IPv4 addresses to IPv4-mapped IPv6 form when the input is IPv4 and not already an IPv4-mapped IPv6 address, preventing double-mapping.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant U as User
  participant CLI as mapcidr CLI
  participant P as Processor
  participant R as Ranger/Aggregator

  U->>CLI: Run with -cl CIDRs, -fi FilterIP, -a
  CLI->>P: Parse options and inputs
  alt FilterIP && Aggregate
    P->>P: enumerate IPs in each CIDR
    P->>P: exclude IPs in FilterIP
    loop for each remaining IP
      P->>P: create single-IP CIDR (/32 or /128)
      P->>R: add single-IP CIDR to aggregation set
    end
    R-->>CLI: perform aggregation/coalesce/sort
  else Other modes
    P->>R: existing path (coalesce/sort/shuffle/approx/count)
    R-->>CLI: result
  end
  CLI-->>U: Output CIDRs
Loading
sequenceDiagram
  autonumber
  participant IP as Caller
  participant N as ipNetToRange

  IP->>N: firstIP, lastIP
  alt firstIP is IPv4 and not already IPv4-mapped-IPv6
    N->>N: map both ends to IPv4-mapped IPv6 form
  else Already mapped or native IPv6
    N->>N: leave addresses unchanged
  end
  N-->>IP: normalized range
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Pre-merge checks (3 passed, 1 warning, 1 inconclusive)

❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Linked Issues Check ❓ Inconclusive The PR's stated objective is to ensure filtered IPs remain excluded after aggregation (fixing issue #523); the changes include a new unit test that asserts the expected aggregated output and an ip.go guard addressing IPv4-mapped IPv6 handling, both relevant to the bug. However, the provided file-level summary for cmd/mapcidr/main.go only documents formatting/comment changes and does not show the promised logic (expanding CIDRs, skipping FilterIP entries, and re-adding remaining IPs as /32 or /128), so I cannot verify from the summaries that the core implementation required by the linked issue is present. Because the implementation evidence is incomplete in the summaries, compliance with the linked issue is inconclusive. Please provide the main.go diff (or an updated raw_summary) showing the expansion-and-filtering logic or confirm CI/unit tests (including the new FilterIPWithAggregation test) pass so reviewers can verify the fix; if the logic is missing, add the expansion-and-skip implementation described in the PR objectives.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title "fix: correctly filter IPs from CIDR during aggregation" is concise, specific, and accurately highlights the primary change (preventing filtered IPs from being reintroduced during aggregation) as described in the PR objectives and linked issue #523. It is a short single sentence without noise and will be clear to teammates scanning history.
Out of Scope Changes Check ✅ Passed The changes in the provided summaries are limited to a minor formatting/comment move in cmd/mapcidr/main.go, a focused unit-test addition in cmd/mapcidr/main_test.go, and a targeted guard change in ip.go to avoid double-mapping IPv4-mapped IPv6 addresses; all three are relevant to correctness around IP handling and aggregation. There is no evidence of unrelated files or large refactors that would be out of scope for fixing the filtering/aggregation regression.

Poem

I hop through nets, a tidy byte delight,
I prune one IP, let neighbors keep their light.
Aggregates gather where filtered footprints stay slight,
No double-mapped shadows in my moonlit sight.
Masks snug, routes tidy — a rabbit's coding night. 🐰✨

Tip

👮 Agentic pre-merge checks are now available in preview!

Pro plan users can now enable pre-merge checks in their settings to enforce checklists before merging PRs.

  • Built-in checks – Quickly apply ready-made checks to enforce title conventions, require pull request descriptions that follow templates, validate linked issues for compliance, and more.
  • Custom agentic checks – Define your own rules using CodeRabbit’s advanced agentic capabilities to enforce organization-specific policies and workflows. For example, you can instruct CodeRabbit’s agent to verify that API documentation is updated whenever API schema files are modified in a PR. Note: Upto 5 custom checks are currently allowed during the preview period. Pricing for this feature will be announced in a few weeks.

Please see the documentation for more information.

Example:

reviews:
  pre_merge_checks:
    custom_checks:
      - name: "Undocumented Breaking Changes"
        mode: "warning"
        instructions: |
          Pass/fail criteria: All breaking changes to public APIs, CLI flags, environment variables, configuration keys, database schemas, or HTTP/GraphQL endpoints must be documented in the "Breaking Change" section of the PR description and in CHANGELOG.md. Exclude purely internal or private changes (e.g., code not exported from package entry points or explicitly marked as internal).

Please share your feedback with us on this Discord post.

✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
ip.go (1)

282-285: Good guard against double IPv4-mapped IPv6 conversion; small symmetry nit

The check avoids double-mapping. For readability, consider using To4() for lastIP too.

-    firstIP = append(v4Mappedv6Prefix, ip4...)
-    lastIP = append(v4Mappedv6Prefix, lastIP...)
+    firstIP = append(v4Mappedv6Prefix, ip4...)
+    lastIP = append(v4Mappedv6Prefix, lastIP.To4()...)
cmd/mapcidr/main_test.go (1)

223-233: Regression covered — LGTM

Test asserts the exact aggregates post-filter; matches the reported issue. Consider adding an IPv6 variant and a case where FilterIP contains a CIDR to harden coverage.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0770c57 and 0767afd.

📒 Files selected for processing (3)
  • cmd/mapcidr/main.go (1 hunks)
  • cmd/mapcidr/main_test.go (1 hunks)
  • ip.go (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
cmd/mapcidr/main_test.go (1)
cmd/mapcidr/main.go (1)
  • Options (41-69)

@jjhwan-h
Copy link
Contributor Author

The issue was already resolved in #678.
This PR only adds the missing tests to cover that case.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
ip.go (1)

282-285: Map lastIP via To4() as well for symmetry and future-proofing.

Today this block only runs when the inputs aren’t already v4-mapped, so lastIP should be 4 bytes and the current code is safe. Using lastIP.To4() explicitly makes the intent clear and resilient to upstream representation shifts.

-    if ip4 := firstIP.To4(); ip4 != nil && !(len(firstIP) == net.IPv6len && bytes.Equal(firstIP[:12], v4Mappedv6Prefix)) {
-        firstIP = append(v4Mappedv6Prefix, ip4...)
-        lastIP = append(v4Mappedv6Prefix, lastIP...)
-    }
+    if ip4 := firstIP.To4(); ip4 != nil && !(len(firstIP) == net.IPv6len && bytes.Equal(firstIP[:12], v4Mappedv6Prefix)) {
+        firstIP = append(v4Mappedv6Prefix, ip4...)
+        if ip4Last := lastIP.To4(); ip4Last != nil {
+            lastIP = append(v4Mappedv6Prefix, ip4Last...)
+        }
+    }

Optionally, consider a tiny helper isV4Mapped(ip net.IP) bool to reuse the prefix check across the file. Also, please add a test with an input like ::ffff:10.0.0.0/120 to ensure no re-wrapping occurs.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0767afd and f844ff8.

📒 Files selected for processing (3)
  • cmd/mapcidr/main.go (1 hunks)
  • cmd/mapcidr/main_test.go (1 hunks)
  • ip.go (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • cmd/mapcidr/main.go
🚧 Files skipped from review as they are similar to previous changes (1)
  • cmd/mapcidr/main_test.go
🔇 Additional comments (1)
ip.go (1)

282-285: Guard correctly avoids double-mapping IPv4-mapped IPv6.

Nice catch. Because To4() returns non-nil for v4-mapped IPv6 too, the previous logic could re-wrap already mapped addresses, leading to malformed 28-byte slices. The added prefix check prevents that.

@Mzack9999 Mzack9999 self-requested a review September 12, 2025 10:33
@Mzack9999
Copy link
Member

@jjhwan-h Thanks for the PR and adding more test coverage!

@Mzack9999 Mzack9999 merged commit 5e24eb4 into projectdiscovery:main Sep 12, 2025
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Issue] IP filtering isn't working as expected

2 participants