diff --git a/pom.xml b/pom.xml
index 1d0736cf95..3a54508162 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,7 +6,7 @@
com.ghostchu.peerbanhelper
peerbanhelper
- 7.1.0-beta1
+ 7.1.0
jar
PeerBanHelper
diff --git a/src/main/java/com/ghostchu/peerbanhelper/btn/BtnConfig.java b/src/main/java/com/ghostchu/peerbanhelper/btn/BtnConfig.java
index f3a9af208f..1f8bc7fd3b 100644
--- a/src/main/java/com/ghostchu/peerbanhelper/btn/BtnConfig.java
+++ b/src/main/java/com/ghostchu/peerbanhelper/btn/BtnConfig.java
@@ -34,7 +34,8 @@ public BtnNetwork btnNetwork() {
var submit = server.getMainConfig().getBoolean("btn.submit");
var appId = server.getMainConfig().getString("btn.app-id");
var appSecret = server.getMainConfig().getString("btn.app-secret");
- BtnNetwork btnNetwork = new BtnNetwork(server, scriptEngine, userAgent, configUrl, submit, appId, appSecret, matchCache);
+ var scriptExecute = server.getMainConfig().getBoolean("btn.allow-script-execute");
+ BtnNetwork btnNetwork = new BtnNetwork(server, scriptEngine, userAgent, configUrl, submit, appId, appSecret, matchCache, scriptExecute);
log.info(tlUI(Lang.BTN_NETWORK_ENABLED));
return btnNetwork;
} else {
diff --git a/src/main/java/com/ghostchu/peerbanhelper/btn/BtnNetwork.java b/src/main/java/com/ghostchu/peerbanhelper/btn/BtnNetwork.java
index 0d1ade59c3..4d6794d7a1 100644
--- a/src/main/java/com/ghostchu/peerbanhelper/btn/BtnNetwork.java
+++ b/src/main/java/com/ghostchu/peerbanhelper/btn/BtnNetwork.java
@@ -37,6 +37,7 @@ public class BtnNetwork {
@Getter
private final Map, BtnAbility> abilities = new HashMap<>();
private final ScriptEngine scriptEngine;
+ private final boolean scriptExecute;
@Getter
private ScheduledExecutorService executeService = null;
private String configUrl;
@@ -54,7 +55,7 @@ public class BtnNetwork {
private PeerRecordDao peerRecordDao;
private ModuleMatchCache moduleMatchCache;
- public BtnNetwork(PeerBanHelperServer server, ScriptEngine scriptEngine, String userAgent, String configUrl, boolean submit, String appId, String appSecret, ModuleMatchCache moduleMatchCache) {
+ public BtnNetwork(PeerBanHelperServer server, ScriptEngine scriptEngine, String userAgent, String configUrl, boolean submit, String appId, String appSecret, ModuleMatchCache moduleMatchCache, boolean scriptExecute) {
this.server = server;
this.scriptEngine = scriptEngine;
this.userAgent = userAgent;
@@ -63,6 +64,7 @@ public BtnNetwork(PeerBanHelperServer server, ScriptEngine scriptEngine, String
this.appId = appId.trim();
this.appSecret = appSecret.trim();
this.moduleMatchCache = moduleMatchCache;
+ this.scriptExecute = scriptExecute;
setupHttpClient();
resetScheduler();
checkIfNeedRetryConfig();
@@ -112,7 +114,7 @@ public void configBtnNetwork() {
// abilities.put(BtnAbilitySubmitRulesHitRate.class, new BtnAbilitySubmitRulesHitRate(this, ability.get("submit_hitrate").getAsJsonObject()));
// }
if (ability.has("rules")) {
- abilities.put(BtnAbilityRules.class, new BtnAbilityRules(this, scriptEngine, ability.get("rules").getAsJsonObject()));
+ abilities.put(BtnAbilityRules.class, new BtnAbilityRules(this, scriptEngine, ability.get("rules").getAsJsonObject(), scriptExecute));
}
if (ability.has("reconfigure")) {
abilities.put(BtnAbilityReconfigure.class, new BtnAbilityReconfigure(this, ability.get("reconfigure").getAsJsonObject()));
diff --git a/src/main/java/com/ghostchu/peerbanhelper/btn/BtnRuleParsed.java b/src/main/java/com/ghostchu/peerbanhelper/btn/BtnRuleParsed.java
index 0c9cefc20c..9d5e158596 100644
--- a/src/main/java/com/ghostchu/peerbanhelper/btn/BtnRuleParsed.java
+++ b/src/main/java/com/ghostchu/peerbanhelper/btn/BtnRuleParsed.java
@@ -33,14 +33,14 @@ public class BtnRuleParsed {
private Map> portRules;
private Map scriptRules;
- public BtnRuleParsed(ScriptEngine scriptEngine, BtnRule btnRule) {
+ public BtnRuleParsed(ScriptEngine scriptEngine, BtnRule btnRule, boolean scriptExecute) {
this.scriptEngine = scriptEngine;
this.version = btnRule.getVersion();
this.ipRules = parseIPRule(btnRule.getIpRules());
this.portRules = parsePortRule(btnRule.getPortRules());
this.peerIdRules = parseRule(btnRule.getPeerIdRules());
this.clientNameRules = parseRule(btnRule.getClientNameRules());
- this.scriptRules = compileScripts(btnRule.getScriptRules());
+ this.scriptRules = scriptExecute ? compileScripts(btnRule.getScriptRules()) : new HashMap<>();
}
private Map compileScripts(Map scriptRules) {
diff --git a/src/main/java/com/ghostchu/peerbanhelper/btn/ability/BtnAbilityRules.java b/src/main/java/com/ghostchu/peerbanhelper/btn/ability/BtnAbilityRules.java
index b297c39f94..43ce0321e1 100644
--- a/src/main/java/com/ghostchu/peerbanhelper/btn/ability/BtnAbilityRules.java
+++ b/src/main/java/com/ghostchu/peerbanhelper/btn/ability/BtnAbilityRules.java
@@ -38,16 +38,18 @@ public class BtnAbilityRules extends AbstractBtnAbility {
private final long randomInitialDelay;
private final File btnCacheFile = new File(Main.getDataDirectory(), "btn.cache");
private final ScriptEngine scriptEngine;
+ private final boolean scriptExecute;
@Getter
private BtnRuleParsed btnRule;
- public BtnAbilityRules(BtnNetwork btnNetwork, ScriptEngine scriptEngine, JsonObject ability) {
+ public BtnAbilityRules(BtnNetwork btnNetwork, ScriptEngine scriptEngine, JsonObject ability, boolean scriptExecute) {
this.btnNetwork = btnNetwork;
this.scriptEngine = scriptEngine;
this.interval = ability.get("interval").getAsLong();
this.endpoint = ability.get("endpoint").getAsString();
this.randomInitialDelay = ability.get("random_initial_delay").getAsLong();
+ this.scriptExecute = scriptExecute;
setLastStatus(true, new TranslationComponent(Lang.BTN_STAND_BY));
}
@@ -60,7 +62,7 @@ private void loadCacheFile() throws IOException {
} else {
try {
BtnRule btnRule = JsonUtil.getGson().fromJson(Files.readString(btnCacheFile.toPath()), BtnRule.class);
- this.btnRule = new BtnRuleParsed(scriptEngine, btnRule);
+ this.btnRule = new BtnRuleParsed(scriptEngine, btnRule, scriptExecute);
} catch (Throwable ignored) {
}
}
@@ -122,7 +124,7 @@ private void updateRule() {
} else {
try {
BtnRule btr = JsonUtil.getGson().fromJson(r.body(), BtnRule.class);
- this.btnRule = new BtnRuleParsed(scriptEngine, btr);
+ this.btnRule = new BtnRuleParsed(scriptEngine, btr, scriptExecute);
Main.getEventBus().post(new BtnRuleUpdateEvent());
try {
Files.writeString(btnCacheFile.toPath(), r.body(), StandardCharsets.UTF_8);
diff --git a/src/main/java/com/ghostchu/peerbanhelper/config/MainConfigUpdateScript.java b/src/main/java/com/ghostchu/peerbanhelper/config/MainConfigUpdateScript.java
index 1e63f29a61..348853e2fa 100644
--- a/src/main/java/com/ghostchu/peerbanhelper/config/MainConfigUpdateScript.java
+++ b/src/main/java/com/ghostchu/peerbanhelper/config/MainConfigUpdateScript.java
@@ -29,6 +29,12 @@ private void validate() {
// }
}
+ @UpdateScript(version = 23)
+ public void btnScriptExecuteSwitch() {
+ conf.set("btn.allow-script-execute", false);
+ }
+
+
@UpdateScript(version = 22)
public void miscChanges() {
conf.set("privacy", null);
diff --git a/src/main/java/com/ghostchu/peerbanhelper/config/ProfileUpdateScript.java b/src/main/java/com/ghostchu/peerbanhelper/config/ProfileUpdateScript.java
index 597aab070c..dcb476f2d7 100644
--- a/src/main/java/com/ghostchu/peerbanhelper/config/ProfileUpdateScript.java
+++ b/src/main/java/com/ghostchu/peerbanhelper/config/ProfileUpdateScript.java
@@ -25,6 +25,8 @@ public ProfileUpdateScript(YamlConfiguration conf) {
this.conf = conf;
}
+
+
@UpdateScript(version = 22)
public void workaroundForBadWebUI() {
if(conf.getInt("module.auto-range-ban.ipv6") == 32) { // WebUI bug
diff --git a/src/main/java/com/ghostchu/peerbanhelper/module/impl/rule/BtnNetworkOnline.java b/src/main/java/com/ghostchu/peerbanhelper/module/impl/rule/BtnNetworkOnline.java
index 7caca10c0f..1eb5a9f238 100644
--- a/src/main/java/com/ghostchu/peerbanhelper/module/impl/rule/BtnNetworkOnline.java
+++ b/src/main/java/com/ghostchu/peerbanhelper/module/impl/rule/BtnNetworkOnline.java
@@ -66,6 +66,7 @@ public class BtnNetworkOnline extends AbstractRuleFeatureModule implements Reloa
private ScriptEngine scriptEngine;
@Autowired
private ScriptStorageDao scriptStorageDao;
+ private boolean allowScript;
@Override
@@ -156,6 +157,7 @@ public ReloadResult reloadModule() throws Exception {
public void reloadConfig() {
this.banDuration = getConfig().getLong("ban-duration", 0);
+ this.allowScript = getConfig().getBoolean("allow-script-execute");
getCache().invalidateAll();
}
@@ -174,9 +176,11 @@ public boolean isThreadSafe() {
if (checkExceptionResult.action() == PeerAction.SKIP) {
return checkExceptionResult;
}
- var scriptResult = checkScript(torrent, peer, downloader, ruleExecuteExecutor);
- if (scriptResult.action() != PeerAction.NO_ACTION) {
- return scriptResult;
+ if(allowScript) {
+ var scriptResult = checkScript(torrent, peer, downloader, ruleExecuteExecutor);
+ if (scriptResult.action() != PeerAction.NO_ACTION) {
+ return scriptResult;
+ }
}
return checkShouldBan(torrent, peer, downloader, ruleExecuteExecutor);
}
diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml
index a5df61ac9e..a86f3ea351 100644
--- a/src/main/resources/config.yml
+++ b/src/main/resources/config.yml
@@ -1,4 +1,4 @@
-config-version: 22
+config-version: 23
# 设置程序语言
# Set the program language
# default 跟随操作系统 (Follow the operating system)
@@ -77,6 +77,11 @@ btn:
# The BTN instance URL, you need find a BTN instance
# By default, PBH-BTN official BTN instance will be used
config-url: "https://sparkle.ghostchu.com/ping/config"
+ # 是否允许 PeerBanHelper 接收来自 BTN 服务器的 Aviator 脚本
+ # 请仅在受信任的 BTN 服务器上启用此功能,运行来自未知来源的脚本可能会导致设备遭到攻击
+ # Allow PeerBanHelper to receive Aviator script from BTN server
+ # Enable this option only on trusted BTN server, running script from unknown source may cause your device under attack
+ allow-script-execute: false
# 封禁列表处理
# PBH 能够除了调用 BT 客户端的封禁 API 外,还能够进行如下操作,以便适配更多其它客户端
# Banlist invoker
diff --git a/webui/src/api/model/config.ts b/webui/src/api/model/config.ts
index 06d94f0313..87ea662797 100644
--- a/webui/src/api/model/config.ts
+++ b/webui/src/api/model/config.ts
@@ -41,6 +41,7 @@ export interface Btn {
app_id: string
app_secret: string
config_url: string
+ allow_script_execute: boolean
}
export interface BanlistInvoker {
diff --git a/webui/src/views/settings/components/config/components/btn.vue b/webui/src/views/settings/components/config/components/btn.vue
index bf374b30e1..31f6790923 100644
--- a/webui/src/views/settings/components/config/components/btn.vue
+++ b/webui/src/views/settings/components/config/components/btn.vue
@@ -28,6 +28,18 @@
+
+
+
+
+ {{ t('page.settings.tab.config.btn.allowScript.warning') }}
+
+
diff --git a/webui/src/views/settings/components/config/locale/en-US.ts b/webui/src/views/settings/components/config/locale/en-US.ts
index 9850abee81..002a05e536 100644
--- a/webui/src/views/settings/components/config/locale/en-US.ts
+++ b/webui/src/views/settings/components/config/locale/en-US.ts
@@ -49,6 +49,11 @@ export default {
'All peers connected to torrents (Including: IP, Port, PeerID, UserAgent, Peer Protocol, Flags, Uploaded, Downloaded, UploadRate, DownloadRate, PeerProgress, YourProgress and Downloader Name)',
'page.settings.tab.config.btn.enableSubmit.modal.content3':
'Are you sure you want to enable submit?',
+ 'page.settings.tab.config.btn.allowScript': 'Allow BTN server push scripts',
+ 'page.settings.tab.config.btn.allowScript.warning':
+ 'Warning, this means that the remote server can execute any code on your device, please enable with caution!',
+ 'page.settings.tab.config.btn.allowScript.tips':
+ 'This option will allow BTN server push scripts to your device, this may increase the accuracy of the ban',
'page.settings.tab.config.ipDatabase.title': 'IP Database',
'page.settings.tab.config.ipDatabase.autoUpdate': 'Enable auto update',
diff --git a/webui/src/views/settings/components/config/locale/zh-CN.ts b/webui/src/views/settings/components/config/locale/zh-CN.ts
index 22d6fd4b1a..e2847b050c 100644
--- a/webui/src/views/settings/components/config/locale/zh-CN.ts
+++ b/webui/src/views/settings/components/config/locale/zh-CN.ts
@@ -48,6 +48,11 @@ export default {
'page.settings.tab.config.btn.enableSubmit.modal.content2':
'您的 Torrent 列表(包括:Torrent 种子摘要的二次不可逆哈希和 Torrent 大小),连接到您的 Torrent 的所有 Peers (包括:IP地址、端口号、PeerID、UserAgent(ClientName),Peer协议,Peer总下载量,Peer总上传量,Peer瞬时上传速度,Peer瞬时下载速度,Peer下载进度,以及您的下载器名称)',
'page.settings.tab.config.btn.enableSubmit.modal.content3': '确定要开启提交吗?',
+ 'page.settings.tab.config.btn.allowScript': '允许 BTN 服务器下发脚本',
+ 'page.settings.tab.config.btn.allowScript.warning':
+ '警告,这意味着远程服务器可以在你的设备上执行任意代码,请谨慎开启',
+ 'page.settings.tab.config.btn.allowScript.tips':
+ '打开此选项后将允许 PeerBanHelper 接收并执行来自 BTN 服务器的动态脚本,这有助于提高反吸血精确度和反吸血效果。',
'page.settings.tab.config.ipDatabase.title': 'IP 数据库',
'page.settings.tab.config.ipDatabase.autoUpdate': '启用自动更新',