From edd40f394d284b871e6a6696a6b0198ec9e965dd Mon Sep 17 00:00:00 2001 From: Haowei Wen Date: Sat, 17 Oct 2020 22:59:55 +0800 Subject: [PATCH] Fix skinDomains can match unwanted domains --- .../support/SkinWhitelistTransformUnit.java | 23 ++++--- .../test/SkinWhitelistTest.java | 60 +++++++++++++++++++ 2 files changed, 76 insertions(+), 7 deletions(-) create mode 100644 src/test/java/moe/yushi/authlibinjector/test/SkinWhitelistTest.java diff --git a/src/main/java/moe/yushi/authlibinjector/transform/support/SkinWhitelistTransformUnit.java b/src/main/java/moe/yushi/authlibinjector/transform/support/SkinWhitelistTransformUnit.java index 47ffc4e..3afbef8 100644 --- a/src/main/java/moe/yushi/authlibinjector/transform/support/SkinWhitelistTransformUnit.java +++ b/src/main/java/moe/yushi/authlibinjector/transform/support/SkinWhitelistTransformUnit.java @@ -19,16 +19,13 @@ package moe.yushi.authlibinjector.transform.support; import static org.objectweb.asm.Opcodes.ALOAD; import static org.objectweb.asm.Opcodes.ASM7; import static org.objectweb.asm.Opcodes.IRETURN; - import java.net.URI; import java.net.URISyntaxException; import java.util.List; import java.util.Optional; import java.util.concurrent.CopyOnWriteArrayList; - import org.objectweb.asm.ClassVisitor; import org.objectweb.asm.MethodVisitor; - import moe.yushi.authlibinjector.transform.CallbackMethod; import moe.yushi.authlibinjector.transform.CallbackSupport; import moe.yushi.authlibinjector.transform.TransformContext; @@ -36,6 +33,18 @@ import moe.yushi.authlibinjector.transform.TransformUnit; public class SkinWhitelistTransformUnit implements TransformUnit { + public static boolean domainMatches(String pattern, String domain) { + // for security concern, empty pattern matches nothing + if (pattern.isEmpty()) { + return false; + } + if (pattern.startsWith(".")) { + return domain.endsWith(pattern); + } else { + return domain.equals(pattern); + } + } + private static final String[] DEFAULT_WHITELISTED_DOMAINS = { ".minecraft.net", ".mojang.com" @@ -56,13 +65,13 @@ public class SkinWhitelistTransformUnit implements TransformUnit { throw new IllegalArgumentException("Invalid URL '" + url + "'"); } - for (String whitelisted : DEFAULT_WHITELISTED_DOMAINS) { - if (domain.endsWith(whitelisted)) { + for (String pattern : DEFAULT_WHITELISTED_DOMAINS) { + if (domainMatches(pattern, domain)) { return true; } } - for (String whitelisted : WHITELISTED_DOMAINS) { - if (domain.endsWith(whitelisted)) { + for (String pattern : WHITELISTED_DOMAINS) { + if (domainMatches(pattern, domain)) { return true; } } diff --git a/src/test/java/moe/yushi/authlibinjector/test/SkinWhitelistTest.java b/src/test/java/moe/yushi/authlibinjector/test/SkinWhitelistTest.java new file mode 100644 index 0000000..6e3cfca --- /dev/null +++ b/src/test/java/moe/yushi/authlibinjector/test/SkinWhitelistTest.java @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2020 Haowei Wen and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +package moe.yushi.authlibinjector.test; + +import static moe.yushi.authlibinjector.transform.support.SkinWhitelistTransformUnit.domainMatches; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import org.junit.Test; + +public class SkinWhitelistTest { + + @Test + public void testEmptyPattern() { + assertFalse(domainMatches("", "example.com")); + } + + @Test + public void testDotMatchesSubdomain() { + assertTrue(domainMatches(".example.com", "a.example.com")); + } + + @Test + public void testDotMatchesSubdomain2() { + assertTrue(domainMatches(".example.com", "b.a.example.com")); + } + + @Test + public void testDotNotMatchesToplevel() { + assertFalse(domainMatches(".example.com", "example.com")); + } + + @Test + public void testNonDotMatchesToplevel() { + assertTrue(domainMatches("example.com", "example.com")); + } + + @Test + public void testNonDotNotMatchesSubdomain() { + assertFalse(domainMatches("example.com", "a.example.com")); + } + + @Test + public void testNonDotNotMatchesOther() { + assertFalse(domainMatches("example.com", "eexample.com")); + } +}