-
Notifications
You must be signed in to change notification settings - Fork 14
Require trusted peers for PROXY source attribution #175
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
13 commits
Select commit
Hold shift + click to select a range
71521f2
Require trusted peers for PROXY protocol attribution
BenCodez 8f3cdc2
Preserve valid PROXY and CONNECT compatibility
BenCodez 7adfa2d
Preserve legacy PROXY behavior when trust setting is absent
BenCodez 3aec138
Preserve legacy PROXY behavior when trust setting is absent
BenCodez 011eef1
Detect legacy Bukkit configs without TrustedProxyIps
BenCodez 2053bce
Detect legacy Bungee configs without TrustedProxyIps
BenCodez 3c96e9f
Detect legacy Velocity configs without TrustedProxyIps
BenCodez 3fe23a4
Test legacy PROXY config compatibility
BenCodez d0b4d1f
Fix legacy PROXY compatibility test header
BenCodez 272d51f
Document trusted proxy upgrade compatibility
BenCodez a5c6970
Document trusted proxy upgrade compatibility
BenCodez 69d67bb
Fail closed without trusted proxy peers
BenCodez 80e6c50
Reject ambiguous link-local PROXY peers
BenCodez File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
111 changes: 111 additions & 0 deletions
111
VotifierPlus/src/main/java/com/vexsoftware/votifier/net/IpLiteral.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,111 @@ | ||
| package com.vexsoftware.votifier.net; | ||
|
|
||
| import java.net.InetAddress; | ||
| import java.net.UnknownHostException; | ||
| import java.util.ArrayList; | ||
| import java.util.List; | ||
|
|
||
| /** Parses address literals without resolving host names or accepting scoped IPv6 addresses. */ | ||
| final class IpLiteral { | ||
| private IpLiteral() { | ||
| } | ||
|
|
||
| static byte[] parse(String value, int family) throws InvalidVoteException { | ||
| if (value == null || value.isEmpty()) { | ||
| throw new InvalidVoteException("Invalid PROXY address literal"); | ||
| } | ||
| if (family == 4) { | ||
| String[] parts = value.split("\\.", -1); | ||
| if (parts.length != 4) { | ||
| throw new InvalidVoteException("Invalid PROXY IPv4 literal"); | ||
| } | ||
| byte[] address = new byte[4]; | ||
| for (int i = 0; i < 4; i++) { | ||
| String part = parts[i]; | ||
| if (part.isEmpty() || part.length() > 3 || (part.length() > 1 && part.charAt(0) == '0')) { | ||
| throw new InvalidVoteException("Invalid PROXY IPv4 literal"); | ||
| } | ||
| int octet = 0; | ||
| for (int j = 0; j < part.length(); j++) { | ||
| char c = part.charAt(j); | ||
| if (c < '0' || c > '9') { | ||
| throw new InvalidVoteException("Invalid PROXY IPv4 literal"); | ||
| } | ||
| octet = octet * 10 + c - '0'; | ||
| } | ||
| if (octet > 255) { | ||
| throw new InvalidVoteException("Invalid PROXY IPv4 literal"); | ||
| } | ||
| address[i] = (byte) octet; | ||
| } | ||
| return address; | ||
| } | ||
| if (family != 6 || value.indexOf(':') < 0) { | ||
| throw new InvalidVoteException("Invalid PROXY IPv6 literal"); | ||
| } | ||
| for (int i = 0; i < value.length(); i++) { | ||
| char c = value.charAt(i); | ||
| if (!((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F') || c == ':' || c == '.')) { | ||
| throw new InvalidVoteException("Invalid PROXY IPv6 literal"); | ||
| } | ||
| } | ||
| return parseIpv6(value); | ||
| } | ||
|
|
||
| private static byte[] parseIpv6(String value) throws InvalidVoteException { | ||
| String[] halves = value.split("::", -1); | ||
| if (halves.length > 2) throw new InvalidVoteException("Invalid PROXY IPv6 literal"); | ||
|
|
||
| List<Integer> left = parseIpv6Half(halves[0], halves.length == 1); | ||
| List<Integer> right = halves.length == 2 ? parseIpv6Half(halves[1], true) : List.of(); | ||
| int omitted = 8 - left.size() - right.size(); | ||
| if (halves.length == 1 ? omitted != 0 : omitted < 1) { | ||
| throw new InvalidVoteException("Invalid PROXY IPv6 literal"); | ||
| } | ||
|
|
||
| byte[] address = new byte[16]; | ||
| int index = 0; | ||
| for (int group : left) index = writeGroup(address, index, group); | ||
| index += omitted * 2; | ||
| for (int group : right) index = writeGroup(address, index, group); | ||
| return address; | ||
| } | ||
|
|
||
| private static List<Integer> parseIpv6Half(String half, boolean mayEndWithIpv4) throws InvalidVoteException { | ||
| List<Integer> groups = new ArrayList<>(); | ||
| if (half.isEmpty()) return groups; | ||
| String[] parts = half.split(":", -1); | ||
| for (int i = 0; i < parts.length; i++) { | ||
| String part = parts[i]; | ||
| if (part.isEmpty()) throw new InvalidVoteException("Invalid PROXY IPv6 literal"); | ||
| if (part.indexOf('.') >= 0) { | ||
| if (!mayEndWithIpv4 || i != parts.length - 1) { | ||
| throw new InvalidVoteException("Invalid PROXY IPv6 literal"); | ||
| } | ||
| byte[] ipv4 = parse(part, 4); | ||
| groups.add((ipv4[0] & 0xFF) << 8 | ipv4[1] & 0xFF); | ||
| groups.add((ipv4[2] & 0xFF) << 8 | ipv4[3] & 0xFF); | ||
| continue; | ||
| } | ||
| if (part.length() > 4) throw new InvalidVoteException("Invalid PROXY IPv6 literal"); | ||
| int group = 0; | ||
| for (int j = 0; j < part.length(); j++) group = group * 16 + Character.digit(part.charAt(j), 16); | ||
| groups.add(group); | ||
| } | ||
| return groups; | ||
| } | ||
|
|
||
| private static int writeGroup(byte[] address, int index, int group) { | ||
| address[index++] = (byte) (group >>> 8); | ||
| address[index++] = (byte) group; | ||
| return index; | ||
| } | ||
|
|
||
| static String format(byte[] address) throws InvalidVoteException { | ||
| try { | ||
| return InetAddress.getByAddress(address).getHostAddress(); | ||
| } catch (UnknownHostException ex) { | ||
| throw new InvalidVoteException("Invalid PROXY address length"); | ||
| } | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.