Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Nov 26, 2025

Addresses review feedback on PR #68 regarding IPv6 handling vulnerabilities and validation issues.

Changes

  • IPv6 validation (src/cli.ts): Replace custom regex with Node.js net.isIPv6() for reliable validation of all IPv6 formats including IPv4-mapped addresses

  • Container iptables IPv6 (containers/agent/setup-iptables.sh): Add ip6tables rules for IPv6 DNS servers

    • Separate IPv4/IPv6 DNS server handling
    • Clear both IPv4 and IPv6 NAT rules on startup
    • Allow IPv6 loopback traffic
  • IPv6 chain filtering (src/host-iptables.ts): Fix FW_WRAPPER_V6 chain security bypass where IPv6 only filtered UDP DNS then returned. Now mirrors IPv4 chain:

    • Allow established/related connections
    • Allow localhost traffic
    • Allow essential ICMPv6 (required for NDP, Path MTU Discovery, etc.)
    • Allow DNS to trusted IPv6 servers only
    • Block multicast (ff00::/8) and link-local (fe80::/10)
    • Block all other UDP with logging
    • Default deny all other traffic (including TCP)
  • IPv6 validation tests (src/cli.test.ts): Added comprehensive test coverage for isValidIPv6():

    • IPv4-mapped IPv6 addresses (::ffff:192.0.2.1)
    • Malformed input edge cases
// Before: complex regex with edge case failures
const ipv6Regex = /^(?:(?:[0-9a-fA-F]{1,4}:){7}...$/;
return ipv6Regex.test(ip);

// After: reliable built-in validation
import { isIPv6 } from 'net';
return isIPv6(ip);

✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Copilot AI changed the title [WIP] Restrict DNS traffic to trusted servers only fix: address ipv6 validation and filtering review comments Nov 26, 2025
Copilot finished work on behalf of Mossaka November 26, 2025 23:28
Copilot AI requested a review from Mossaka November 26, 2025 23:28
Copy link
Collaborator

@Mossaka Mossaka left a comment

Choose a reason for hiding this comment

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

Comment on lines +8 to +12
is_ipv6() {
local ip="$1"
# Check if it contains a colon (IPv6 addresses always contain colons)
[[ "$ip" == *:* ]]
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

isn't this test overly simplified?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, the check is intentionally simple because the DNS servers passed to this script via AWF_DNS_SERVERS are already validated in src/cli.ts using Node.js's net.isIPv6() before the container starts. The shell script only needs to distinguish between pre-validated IPv4 and IPv6 addresses, so checking for a colon is sufficient - IPv6 addresses always contain colons, IPv4 never do.

If you'd prefer more robust validation in the shell script itself, I can add a more comprehensive check using regex or by attempting to parse with standard utilities.

@Mossaka Mossaka requested a review from Copilot November 26, 2025 23:39
Copilot AI requested a review from Mossaka November 26, 2025 23:42
Copilot finished work on behalf of Mossaka November 26, 2025 23:42
Copilot finished reviewing on behalf of Mossaka November 26, 2025 23:46
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR addresses IPv6 validation and filtering vulnerabilities identified in PR #68 review feedback. The changes improve IPv6 support across the firewall implementation but introduce a critical security vulnerability.

Key Changes

  • Replaced custom IPv6 regex validation with Node.js built-in net.isIPv6() for more reliable validation
  • Added IPv6 support to container-level iptables NAT rules for DNS traffic
  • Implemented comprehensive IPv6 filtering rules in host-level iptables that mirror IPv4 chain security

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.

File Description
src/cli.ts Replaced custom IPv6 regex with net.isIPv6() for robust validation of all IPv6 formats including IPv4-mapped addresses
containers/agent/setup-iptables.sh Added IPv6 DNS server support with is_ipv6() helper, ip6tables NAT rules for IPv6 DNS servers, and IPv6 loopback traffic handling
src/host-iptables.ts Added comprehensive IPv6 chain filtering (established/related, localhost, DNS, multicast/link-local blocking, default deny) but only when IPv6 DNS servers are configured - this creates a critical security bypass

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

'-d', '::1/128',
'-j', 'ACCEPT',
]);

Copy link

Copilot AI Nov 26, 2025

Choose a reason for hiding this comment

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

The IPv6 filtering rules don't explicitly allow ICMPv6 traffic. While the ESTABLISHED,RELATED rule may cover some ICMPv6 (like error messages related to existing connections), certain essential ICMPv6 traffic may be blocked:

  • Neighbor Discovery Protocol (NDP): Required for IPv6 address resolution (replaces ARP in IPv4)
  • Path MTU Discovery: ICMPv6 "Packet Too Big" messages (type 2) are critical for avoiding fragmentation
  • Router Discovery: May be needed in some network configurations

Consider adding an ICMPv6 allow rule after the localhost rules to ensure IPv6 networking functions properly:

// Allow essential ICMPv6 (required for IPv6 functionality)
await execa('ip6tables', [
  '-t', 'filter', '-A', CHAIN_NAME_V6,
  '-p', 'ipv6-icmp',
  '-j', 'ACCEPT',
]);

If you want to be more restrictive, allow only specific ICMPv6 types (1: destination unreachable, 2: packet too big, 3: time exceeded, 128-129: echo request/reply, 133-137: NDP).

Suggested change
// Allow essential ICMPv6 (required for IPv6 functionality)
await execa('ip6tables', [
'-t', 'filter', '-A', CHAIN_NAME_V6,
'-p', 'ipv6-icmp',
'-j', 'ACCEPT',
]);

Copilot uses AI. Check for mistakes.
Comment on lines 97 to 99
export function isValidIPv6(ip: string): boolean {
// Comprehensive IPv6 validation covering:
// - Full form: 2001:0db8:85a3:0000:0000:8a2e:0370:7334
// - Compressed form: 2001:db8:85a3::8a2e:370:7334
// - Loopback: ::1
// - Unspecified: ::
// - IPv4-mapped: ::ffff:192.0.2.1
const ipv6Regex = /^(?:(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|(?:[0-9a-fA-F]{1,4}:){1,7}:|(?:[0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|(?:[0-9a-fA-F]{1,4}:){1,5}(?::[0-9a-fA-F]{1,4}){1,2}|(?:[0-9a-fA-F]{1,4}:){1,4}(?::[0-9a-fA-F]{1,4}){1,3}|(?:[0-9a-fA-F]{1,4}:){1,3}(?::[0-9a-fA-F]{1,4}){1,4}|(?:[0-9a-fA-F]{1,4}:){1,2}(?::[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:(?::[0-9a-fA-F]{1,4}){1,6}|:(?::[0-9a-fA-F]{1,4}){1,7}|::)$/;
return ipv6Regex.test(ip);
return isIPv6(ip);
}
Copy link

Copilot AI Nov 26, 2025

Choose a reason for hiding this comment

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

The updated isValidIPv6() function lacks test coverage. Given that this is a critical validation function used to separate IPv4 and IPv6 DNS servers, it should have comprehensive tests to verify:

  1. Valid IPv6 addresses (standard form, compressed, with leading zeros, etc.)
  2. IPv4-mapped IPv6 addresses (::ffff:192.0.2.1)
  3. Invalid inputs (malformed addresses, IPv4 addresses, empty strings, etc.)
  4. Edge cases (::1, ::, etc.)

Consider adding unit tests in a new file tests/unit/cli.test.ts or expanding existing tests to cover this function:

describe('isValidIPv6', () => {
  it('should return true for valid IPv6 addresses', () => {
    expect(isValidIPv6('2001:db8::1')).toBe(true);
    expect(isValidIPv6('::1')).toBe(true);
    expect(isValidIPv6('fe80::1')).toBe(true);
  });

  it('should return false for IPv4 addresses', () => {
    expect(isValidIPv6('8.8.8.8')).toBe(false);
    expect(isValidIPv6('192.168.1.1')).toBe(false);
  });

  it('should return false for invalid input', () => {
    expect(isValidIPv6('not-an-ip')).toBe(false);
    expect(isValidIPv6('')).toBe(false);
  });
});

Copilot uses AI. Check for mistakes.
@Mossaka
Copy link
Collaborator

Mossaka commented Nov 27, 2025

@copilot apply changes based on the comments in this thread

Copy link
Contributor Author

Copilot AI commented Nov 27, 2025

@copilot apply changes based on the comments in this thread

Applied in 6e0de58:

  • Added ICMPv6 allow rule for essential IPv6 functionality (NDP, Path MTU Discovery, etc.)
  • Added comprehensive test coverage for isValidIPv6() including IPv4-mapped addresses and malformed input edge cases

Copilot finished work on behalf of Mossaka November 27, 2025 00:13
@Mossaka Mossaka marked this pull request as ready for review November 27, 2025 00:18
@Mossaka Mossaka merged commit 9a21aaf into dns-trusted Nov 27, 2025
@Mossaka Mossaka deleted the copilot/sub-pr-68 branch November 27, 2025 00:18
Mossaka added a commit that referenced this pull request Dec 2, 2025
* feat(security): restrict dns traffic to trusted servers only

Addresses DNS-based data exfiltration vulnerability where DNS traffic
  (port 53) was allowed to ANY destination, enabling attackers to encode
  sensitive data in DNS queries to malicious DNS servers.

Signed-off-by: Jiaxiao (mossaka) Zhou <[email protected]>

* fix: address ipv6 validation and filtering review comments (#69)

* Initial plan

* fix: address pr review comments for ipv6 validation and filtering

Co-authored-by: Mossaka <[email protected]>

* fix: improve ipv6 chain comments for clarity

Co-authored-by: Mossaka <[email protected]>

* fix: add icmpv6 rules and ipv6 validation tests

Co-authored-by: Mossaka <[email protected]>

---------

Co-authored-by: copilot-swe-agent[bot] <[email protected]>
Co-authored-by: Mossaka <[email protected]>

* fix: add ip6tables availability checks for robustness (#77)

* Initial plan

* fix: add ip6tables availability checks for robustness

Co-authored-by: Mossaka <[email protected]>

* fix: address code review feedback for ip6tables checks

Co-authored-by: Mossaka <[email protected]>

---------

Co-authored-by: copilot-swe-agent[bot] <[email protected]>
Co-authored-by: Mossaka <[email protected]>

---------

Signed-off-by: Jiaxiao (mossaka) Zhou <[email protected]>
Co-authored-by: Copilot <[email protected]>
Co-authored-by: Mossaka <[email protected]>
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.

2 participants