Skip to content

Commit

Permalink
Merge pull request #20 from dejvokep/development
Browse files Browse the repository at this point in the history
Support FlameCord and add an option to disable data logging
  • Loading branch information
dejvokep committed May 26, 2024
2 parents 8f912e2 + aa5d777 commit 0036b22
Show file tree
Hide file tree
Showing 33 changed files with 357 additions and 168 deletions.
2 changes: 1 addition & 1 deletion LICENSE-header.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Copyright 2022 https://dejvokep.dev/
Copyright 2024 https://dejvokep.dev/

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down
44 changes: 21 additions & 23 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,7 @@
access and IP-forwarding bypass exploit, mainly for those who cannot access or configure their firewall systems. The
plugin has been serving protection for everyone since 2019,
connecting [BungeeGuard](https://github.com/lucko/BungeeGuard) (from which it took the inspiration) and the good old
IP-whitelisting feature.

[![SafeNET is powered by Senior Hosting. Use code "YAML" for 10% off!](https://cdn.discordapp.com/attachments/927561782279675977/945372759289126973/Group_129.png)](https://senior-host.com/)
IP-whitelisting feature and delivering all features in one, compact and versatile package.

# ❓ What is IP-forwarding bypass?

Expand All @@ -16,14 +14,14 @@ whatever account freely (including yours as an admin).

Each player has their own profile, which contains information about them (UUID, skin textures...). These data are given
to the proxy server when a player joins and then forwarded by the proxy to each of the backend servers, when you're
being connected to them. This plugin uses a passphrase, which is inserted into the player's profile and then forwarded
to the backend servers to check for integrity.
being connected to them. This plugin uses a passphrase, which is forwarded to the backend servers to check for
integrity.

After an exploit has been found, which allows for packets to be uncaught during a specific timeframe, effectively
bypassing the authentication and leaving your server vulnerable, this system's been enriched with sessions. A special
session key is generated each time the server starts, is attached to player's profile when authenticated and is verified
when the player is on the edge of joining the server (spawning into the world). Sessions patch any possible way around
the initial authentication.
After an exploit has been found, which allows for packets to be uncaught by plugins during a specific timeframe,
effectively bypassing the authentication and leaving your server vulnerable, this system's been enriched with sessions.
A special session key is generated each time the server starts, is attached to player's profile when authenticated and
verified when the player is on the edge of joining the server (spawning into the world). Sessions patch any possible way
around the initial authentication.

# 👍 Why to use SafeNET over other plugins?

Expand All @@ -32,21 +30,21 @@ use the IP-whitelist, this is the way to go. The plugin also supports [GeyserMC]
including [Floodgate](https://github.com/GeyserMC/Floodgate/)), which other plugins do not. Logs everything to the
console for easy verification and control over connection flow.

The plugin has been downloaded 14K+ times, and (on average) is active on 300+ networks managing over 1500 backend
servers.
The plugin has been downloaded 20K+ times, and is active on 300+ networks managing over 1500 backend servers.

# 🔧 Setup and support

Download the latest release from the panel on the right. **BungeeCord 1.19 and ProtocolLib 5.0.0 or newer are
required (if running [Paper servers](https://papermc.io/), ProtocolLib installation is not needed).** Alternatively,
use LEGACY version, which allows for use of older ProtocolLib releases. If you're stillusing version 3.5 or older,
**immediately upgrade** to at least 3.6.
> **NOTE!** SafeNET should only be used if you cannot access, set up nor manage a firewall on your network (shared
> hosts).
Download the latest release from the panel on the right. The plugin supports **all major**:

- proxy servers (BungeeCord, Waterfall, FlameCord...) running **the latest release** (build [1637](https://ci.md-5.net/job/BungeeCord/1637/) or newer),
- backend servers (Bukkit, Spigot, Paper, Purpur...) running **1.8 - 1.20 releases**.

| SafeNET | BungeeCord | ProtocolLib (not required if running [Paper servers](https://papermc.io/)) | Game |
|-----------------|--------------------------------------------------------------------------|----------------------------------------------------------------------------|------------|
| 3.8 | Latest build ([1637](https://ci.md-5.net/job/BungeeCord/1637/) or newer) | 5.0.0 (or newer) | 1.8 - 1.19 |
| 3.8-LEGACY | Latest build ([1637](https://ci.md-5.net/job/BungeeCord/1637/) or newer) | 4.8.0 (or older) | 1.8 - 1.18 |
| 3.5 (and older) | **VULNERABLE, DO NOT USE!** | - | - |
The plugin must be installed on all servers on your network. Consult the documentation linked below for further
information and setup instructions.

You can view the setup instructions at [the wiki](https://dejvokep.gitbook.io/safenet/). If you need help with anything,
feel free join the [Discord server](https://discord.gg/BbhADEy) (nonstop 24/7 🤖 support). Or, just to talk with us 👋
You can view the setup instructions and other details on [the wiki](https://dejvokep.gitbook.io/safenet/). If you need
help with anything,
feel free join the [Discord server](https://discord.gg/BbhADEy). Or, just to talk with us 👋
6 changes: 3 additions & 3 deletions pom.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright 2022 https://dejvokep.dev/
Copyright 2024 https://dejvokep.dev/
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand All @@ -25,7 +25,7 @@
<groupId>dev.dejvokep</groupId>
<artifactId>safe-net</artifactId>
<packaging>pom</packaging>
<version>3.8</version>
<version>3.9</version>
<modules>
<module>safe-net-core</module>
<module>safe-net-bungeecord</module>
Expand Down Expand Up @@ -104,7 +104,7 @@
<dependency>
<groupId>dev.dejvokep</groupId>
<artifactId>boosted-yaml</artifactId>
<version>1.3.1</version>
<version>1.3.5</version>
<scope>provided</scope>
</dependency>
</dependencies>
Expand Down
8 changes: 4 additions & 4 deletions safe-net-bungeecord/pom.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright 2022 https://dejvokep.dev/
Copyright 2024 https://dejvokep.dev/
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand All @@ -25,7 +25,7 @@
<parent>
<artifactId>safe-net</artifactId>
<groupId>dev.dejvokep</groupId>
<version>3.8</version>
<version>3.9</version>
</parent>
<packaging>jar</packaging>
<description>${project.parent.description}</description>
Expand Down Expand Up @@ -139,15 +139,15 @@
<dependency>
<groupId>net.md-5</groupId>
<artifactId>bungeecord-api</artifactId>
<version>1.19-R0.1-SNAPSHOT</version>
<version>1.20-R0.3-SNAPSHOT</version>
<type>jar</type>
<scope>provided</scope>
</dependency>
<!-- BungeeCord server -->
<dependency>
<groupId>net.md-5</groupId>
<artifactId>bungeecord-proxy</artifactId>
<version>1.19-R0.1-SNAPSHOT</version>
<version>1.20-R0.3-SNAPSHOT</version>
<type>jar</type>
<scope>provided</scope>
</dependency>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2022 https://dejvokep.dev/
* Copyright 2024 https://dejvokep.dev/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -44,7 +44,7 @@ public class SafeNetBungeeCord extends Plugin {
/**
* Supported version of the BungeeCord server.
*/
private static final String BUNGEE_CORD_VERSION = "build 1637 (1.19 update) or newer";
private static final String BUNGEECORD_VERSION = "build 1637 (1.19 update) or newer";

// Message sender
private final Messenger messenger = new Messenger();
Expand All @@ -61,7 +61,7 @@ public class SafeNetBungeeCord extends Plugin {
public void onEnable() {
// If BungeeCord is not of a support version
if (isUnsupportedBungeeCord()) {
getLogger().severe(String.format("This version of SafeNET requires BungeeCord %s to run! Shutting down...", BUNGEE_CORD_VERSION));
getLogger().severe(String.format("This version of SafeNET requires BungeeCord %s to run! Shutting down...", BUNGEECORD_VERSION));
ProxyServer.getInstance().stop();
return;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2022 https://dejvokep.dev/
* Copyright 2024 https://dejvokep.dev/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2022 https://dejvokep.dev/
* Copyright 2024 https://dejvokep.dev/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2022 https://dejvokep.dev/
* Copyright 2024 https://dejvokep.dev/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2022 https://dejvokep.dev/
* Copyright 2024 https://dejvokep.dev/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -17,6 +17,8 @@

import dev.dejvokep.safenet.bungeecord.SafeNetBungeeCord;
import dev.dejvokep.safenet.bungeecord.ipwhitelist.AddressHolder;
import dev.dejvokep.safenet.bungeecord.listener.result.SafeNetLoginResult;
import dev.dejvokep.safenet.bungeecord.listener.result.StackTraceVerifier;
import net.md_5.bungee.api.ChatColor;
import net.md_5.bungee.api.chat.TextComponent;
import net.md_5.bungee.api.connection.PendingConnection;
Expand Down Expand Up @@ -88,6 +90,8 @@ public class LoginListener implements Listener {

// The passphrase error message
private TextComponent disconnectMessage;
// Verifier
private final StackTraceVerifier stackTraceVerifier;

/**
* Utilizes the login result field of the {@link InitialHandler} class. Loads the passphrase error disconnect
Expand All @@ -98,6 +102,7 @@ public class LoginListener implements Listener {
public LoginListener(@NotNull SafeNetBungeeCord plugin) {
// Set
this.plugin = plugin;
this.stackTraceVerifier = new StackTraceVerifier(plugin);
// Reload
reload();

Expand Down Expand Up @@ -146,7 +151,6 @@ public void onPreLogin(LoginEvent event) {
* Reloads the internal data.
*/
public void reload() {
// Set
disconnectMessage = new TextComponent(ChatColor.translateAlternateColorCodes('&', plugin.getConfiguration().getString("disconnect-message", DEFAULT_DISCONNECT_MESSAGE)));
}

Expand All @@ -164,7 +168,7 @@ private boolean setResult(@NotNull PendingConnection pendingConnection) {

try {
// Set
loginResultField.set(pendingConnection, new SafeNetLoginResult(((InitialHandler) pendingConnection).getLoginProfile(), plugin.getPassphraseVault()));
loginResultField.set(pendingConnection, new SafeNetLoginResult(((InitialHandler) pendingConnection).getLoginProfile(), plugin.getPassphraseVault(), stackTraceVerifier));
} catch (Exception ex) {
// Log
plugin.getLogger().log(Level.SEVERE, "An error occurred whilst setting the custom login result into the connection!", ex);
Expand All @@ -176,7 +180,7 @@ private boolean setResult(@NotNull PendingConnection pendingConnection) {
}

/**
* Cancels a event and sets a disconnect message.
* Cancels an event and sets a disconnect message.
*
* @param event the event to cancel
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2022 https://dejvokep.dev/
* Copyright 2024 https://dejvokep.dev/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package dev.dejvokep.safenet.bungeecord.listener;
package dev.dejvokep.safenet.bungeecord.listener.result;

import dev.dejvokep.safenet.core.PassphraseVault;
import net.md_5.bungee.connection.LoginResult;
Expand All @@ -24,54 +24,41 @@
import java.util.Arrays;

/**
* Class extending {@link LoginResult} which securely passes the passphrase to server connector, if called by handler
* boss (see {@link #SERVER_CONNECTOR_CLASS} and {@link #HANDLER_BOSS_CLASS}) and by respective methods of these classes
* ({@link #SERVER_CONNECTOR_CONNECTED_METHOD} and {@link #HANDLER_BOSS_CHANNEL_ACTIVE_METHOD}).
* Class extending {@link LoginResult} which securely passes the passphrase to server connector.
* <p>
* If the server is in online-mode, values from the previous login result are used. If in offline-mode, the server does
* not supply the login result. As this custom login result is there every time (not depending on the mode), the
* returned values are <code>null</code> (replacing the <code>null</code> login profile), except the properties. The
* returned properties are (if not called by methods mentioned above) always an empty array, as during the testing
* phase, a lot of problems were found when using some plugins if the value was <code>null</code>.
* <p>
* <i>The use of custom login results to forward plugin data to backend servers was inspired by BungeeGuard.</i>
* <i>The use of custom login results to forward plugin data to backend servers was inspired by BungeeGuard, although
* was perfected to properly handle edge cases and wide selection of server software implementations.</i>
*/
public class SafeNetLoginResult extends LoginResult {

/**
* Server connector class.
*/
public static final String SERVER_CONNECTOR_CLASS = "net.md_5.bungee.ServerConnector";
/**
* Connected method in server connector.
*/
public static final String SERVER_CONNECTOR_CONNECTED_METHOD = "connected";
/**
* Handler boss class.
*/
public static final String HANDLER_BOSS_CLASS = "net.md_5.bungee.netty.HandlerBoss";
/**
* Channel active method in handler boss.
*/
public static final String HANDLER_BOSS_CHANNEL_ACTIVE_METHOD = "channelActive";

// Property array with passphrase
private Property[] withPassphrase;
// Vault
private final PassphraseVault passphraseVault;
// Verifier
private final StackTraceVerifier stackTraceVerifier;

/**
* Copies references of variables from the login result obtained from a {@link net.md_5.bungee.api.event.LoginEvent}.
* If the given result is <code>null</code>, all variables used by the result are set to <code>null</code>.
* Copies references of variables from the login result obtained from a
* {@link net.md_5.bungee.api.event.LoginEvent}. If the given result is <code>null</code>, all variables used by the
* result are set to <code>null</code>.
*
* @param fromLogin the login result obtained from a {@link net.md_5.bungee.api.event.LoginEvent}
* @param passphraseVault the store providing the secret passphrase and other needed data
* @param fromLogin the login result obtained from a {@link net.md_5.bungee.api.event.LoginEvent}
* @param passphraseVault the store providing the secret passphrase and other needed data
* @param stackTraceVerifier the stack trace verifier
*/
SafeNetLoginResult(@Nullable LoginResult fromLogin, @NotNull PassphraseVault passphraseVault) {
public SafeNetLoginResult(@Nullable LoginResult fromLogin, @NotNull PassphraseVault passphraseVault, @NotNull StackTraceVerifier stackTraceVerifier) {
// Call as in offline mode
super(null, null, new Property[0]);
// Set
this.passphraseVault = passphraseVault;
this.stackTraceVerifier = stackTraceVerifier;

// If the result from the event contains any data - online mode
if (fromLogin != null) {
Expand All @@ -89,25 +76,7 @@ public class SafeNetLoginResult extends LoginResult {

@Override
public Property[] getProperties() {
// The stack trace
StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
// If unable to verify
if (stackTrace.length < 4)
return super.getProperties();

// Server connector caller
StackTraceElement serverConnector = stackTrace[2];
// Handler boss caller
StackTraceElement handlerBoss = stackTrace[3];

// Verify callers
if (serverConnector.getClassName().equals(SERVER_CONNECTOR_CLASS) && serverConnector.getMethodName().equals(SERVER_CONNECTOR_CONNECTED_METHOD)
&& handlerBoss.getClassName().equals(HANDLER_BOSS_CLASS) && handlerBoss.getMethodName().equals(HANDLER_BOSS_CHANNEL_ACTIVE_METHOD))
// Return properties with the passphrase
return withPassphrase;
else
// Return normal properties
return super.getProperties();
return stackTraceVerifier.verify(Thread.currentThread().getStackTrace()) ? withPassphrase : super.getProperties();
}

@Override
Expand All @@ -125,7 +94,7 @@ private void resetCustomProperties() {
// Make a copy of the original properties, or create a new instance with a space for the passphrase
withPassphrase = getProperties() == null ? new Property[1] : Arrays.copyOf(getProperties(), getProperties().length + 1);
// Add the passphrase
withPassphrase[withPassphrase.length - 1] = new Property(PassphraseVault.PASSPHRASE_PROPERTY_NAME, passphraseVault.getPassphrase(), "");
withPassphrase[withPassphrase.length - 1] = new Property(passphraseVault.getPropertyName(), passphraseVault.getPassphrase(), "");
}

}
Loading

0 comments on commit 0036b22

Please sign in to comment.