refactor secure url check for additional call sites
This commit is contained in:
parent
e96aa0d3f8
commit
7d0699faa0
@ -14,6 +14,7 @@ import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.math.BigInteger;
|
||||
import java.net.URI;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.charset.CharsetDecoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
@ -93,6 +94,15 @@ public class Utils {
|
||||
return ((st > 0) || (len < bytes.length)) ? Arrays.copyOfRange(bytes, st, len) : bytes;
|
||||
}
|
||||
|
||||
public static boolean isSecureUrl(URI uri) {
|
||||
if(uri == null || uri.getScheme() == null || uri.getHost() == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
String scheme = uri.getScheme().toLowerCase(Locale.ROOT);
|
||||
return "https".equals(scheme) || ("http".equals(scheme) && uri.getHost().toLowerCase(Locale.ROOT).endsWith(".onion"));
|
||||
}
|
||||
|
||||
public static String bytesToHex(byte[] bytes) {
|
||||
char[] hexChars = new char[bytes.length * 2];
|
||||
for ( int j = 0; j < bytes.length; j++ ) {
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
package com.sparrowwallet.drongo.uri;
|
||||
|
||||
import com.sparrowwallet.drongo.Network;
|
||||
import com.sparrowwallet.drongo.Utils;
|
||||
import com.sparrowwallet.drongo.address.Address;
|
||||
import com.sparrowwallet.drongo.address.InvalidAddressException;
|
||||
import com.sparrowwallet.drongo.silentpayments.SilentPayment;
|
||||
@ -275,10 +276,10 @@ public class BitcoinURI {
|
||||
if(payjoinUrl != null) {
|
||||
try {
|
||||
URI uri = new URI(payjoinUrl);
|
||||
if(uri.getScheme().equals("https") || uri.getHost().endsWith(".onion")) {
|
||||
if(Utils.isSecureUrl(uri)) {
|
||||
return uri;
|
||||
} else {
|
||||
log.error("Insecure payjoin URL provided, must be https or .onion: " + payjoinUrl);
|
||||
log.error("Insecure payjoin URL provided, must be https or http .onion: " + payjoinUrl);
|
||||
}
|
||||
} catch(URISyntaxException e) {
|
||||
log.error("Invalid payjoin URL provided", e);
|
||||
|
||||
48
src/test/java/com/sparrowwallet/drongo/UtilsTest.java
Normal file
48
src/test/java/com/sparrowwallet/drongo/UtilsTest.java
Normal file
@ -0,0 +1,48 @@
|
||||
package com.sparrowwallet.drongo;
|
||||
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
public class UtilsTest {
|
||||
@Test
|
||||
public void isSecureUrlAcceptsHttps() throws Exception {
|
||||
Assertions.assertTrue(Utils.isSecureUrl(new URI("https://example.com/callback")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isSecureUrlAcceptsUppercaseHttps() throws Exception {
|
||||
Assertions.assertTrue(Utils.isSecureUrl(new URI("HTTPS://example.com/callback")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isSecureUrlAcceptsHttpOnion() throws Exception {
|
||||
Assertions.assertTrue(Utils.isSecureUrl(new URI("http://abcdefghijklmnopqrstuvwxyzabcdefghijklmnop.onion/callback")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isSecureUrlRejectsHttpClearnet() throws Exception {
|
||||
Assertions.assertFalse(Utils.isSecureUrl(new URI("http://example.com/callback")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isSecureUrlRejectsNonHttpOnion() throws Exception {
|
||||
Assertions.assertFalse(Utils.isSecureUrl(new URI("ftp://abcdefghijklmnopqrstuvwxyzabcdefghijklmnop.onion/callback")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isSecureUrlRejectsOpaqueHttps() throws Exception {
|
||||
Assertions.assertFalse(Utils.isSecureUrl(new URI("https:opaque")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isSecureUrlRejectsSchemeless() throws Exception {
|
||||
Assertions.assertFalse(Utils.isSecureUrl(new URI("callback")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isSecureUrlRejectsNull() {
|
||||
Assertions.assertFalse(Utils.isSecureUrl(null));
|
||||
}
|
||||
}
|
||||
@ -3,9 +3,13 @@ package com.sparrowwallet.drongo.uri;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Locale;
|
||||
|
||||
public class BitcoinUriTest {
|
||||
private static final String ADDRESS = "bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4";
|
||||
|
||||
@Test
|
||||
public void testSamourai() throws BitcoinURIParseException {
|
||||
String uri = "bitcoin:BC1QT4NRM47695YWDG9N30N68JARMXRJNKFMR36994?amount=0,001";
|
||||
@ -14,4 +18,34 @@ public class BitcoinUriTest {
|
||||
Assertions.assertEquals("BC1QT4NRM47695YWDG9N30N68JARMXRJNKFMR36994".toLowerCase(Locale.ROOT), bitcoinURI.getAddress().toString());
|
||||
Assertions.assertEquals(Long.valueOf(100000), bitcoinURI.getAmount());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void acceptsHttpsPayjoinUrl() throws BitcoinURIParseException {
|
||||
BitcoinURI bitcoinURI = payjoinUri("https://example.com/payjoin");
|
||||
Assertions.assertNotNull(bitcoinURI.getPayjoinUrl());
|
||||
Assertions.assertEquals("https://example.com/payjoin", bitcoinURI.getPayjoinUrl().toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void acceptsHttpOnionPayjoinUrl() throws BitcoinURIParseException {
|
||||
BitcoinURI bitcoinURI = payjoinUri("http://abcdefghijklmnopqrstuvwxyzabcdefghijklmnop.onion/payjoin");
|
||||
Assertions.assertNotNull(bitcoinURI.getPayjoinUrl());
|
||||
Assertions.assertEquals("http://abcdefghijklmnopqrstuvwxyzabcdefghijklmnop.onion/payjoin", bitcoinURI.getPayjoinUrl().toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void rejectsNonHttpOnionPayjoinUrl() throws BitcoinURIParseException {
|
||||
BitcoinURI bitcoinURI = payjoinUri("file://abcdefghijklmnopqrstuvwxyzabcdefghijklmnop.onion/payjoin");
|
||||
Assertions.assertNull(bitcoinURI.getPayjoinUrl());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void rejectsMalformedPayjoinUrl() throws BitcoinURIParseException {
|
||||
BitcoinURI bitcoinURI = payjoinUri("payjoin");
|
||||
Assertions.assertNull(bitcoinURI.getPayjoinUrl());
|
||||
}
|
||||
|
||||
private static BitcoinURI payjoinUri(String payjoinUrl) throws BitcoinURIParseException {
|
||||
return new BitcoinURI("bitcoin:" + ADDRESS + "?pj=" + URLEncoder.encode(payjoinUrl, StandardCharsets.UTF_8));
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user