mirror of
https://github.com/sparrowwallet/sparrow.git
synced 2026-07-30 19:46:16 +00:00
improve url validation for auth47 and lnurl-auth
This commit is contained in:
+1
-1
Submodule drongo updated: e96aa0d3f8...7d0699faa0
@@ -4,6 +4,7 @@ import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.sparrowwallet.drongo.ExtendedKey;
|
||||
import com.sparrowwallet.drongo.KeyPurpose;
|
||||
import com.sparrowwallet.drongo.Utils;
|
||||
import com.sparrowwallet.drongo.crypto.ChildNumber;
|
||||
import com.sparrowwallet.drongo.crypto.ECKey;
|
||||
import com.sparrowwallet.drongo.protocol.ScriptType;
|
||||
@@ -69,19 +70,17 @@ public class Auth47 {
|
||||
this.srbnName = srbnUrl.getUserInfo();
|
||||
this.callback = new URI(HTTPS_PROTOCOL + srbnUrl.getHost()).toURL();
|
||||
} else {
|
||||
this.callback = new URI(strCallback).toURL();
|
||||
URI callbackUri = new URI(strCallback);
|
||||
if(!Utils.isSecureUrl(callbackUri)) {
|
||||
throw new IllegalArgumentException("Invalid callback parameter (not https, http .onion or srbn): " + strCallback);
|
||||
}
|
||||
this.callback = callbackUri.toURL();
|
||||
}
|
||||
|
||||
this.expiry = parameterMap.get("e");
|
||||
this.resource = parameterMap.get("r");
|
||||
if(resource == null) {
|
||||
if(srbn) {
|
||||
this.resource = "srbn";
|
||||
} else if(strCallback.startsWith("http")) {
|
||||
this.resource = strCallback;
|
||||
} else {
|
||||
throw new IllegalArgumentException("Invalid callback parameter (not http/s or srbn): " + strCallback);
|
||||
}
|
||||
this.resource = srbn ? "srbn" : strCallback;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -41,9 +41,17 @@ public class LnurlAuth {
|
||||
public LnurlAuth(URI uri) throws MalformedURLException, URISyntaxException {
|
||||
String lnurl = uri.getSchemeSpecificPart();
|
||||
Bech32.Bech32Data bech32 = Bech32.decode(lnurl, 2000);
|
||||
if(!"lnurl".equals(bech32.hrp)) {
|
||||
throw new IllegalArgumentException("LNURL-auth bech32 prefix must be lnurl");
|
||||
}
|
||||
|
||||
byte[] urlBytes = Bech32.convertBits(bech32.data, 0, bech32.data.length, 5, 8, false);
|
||||
String strUrl = new String(urlBytes, StandardCharsets.UTF_8);
|
||||
this.url = new URI(strUrl).toURL();
|
||||
URI decodedUri = new URI(strUrl);
|
||||
if(!Utils.isSecureUrl(decodedUri)) {
|
||||
throw new IllegalArgumentException("LNURL-auth URL must be https or http .onion");
|
||||
}
|
||||
this.url = decodedUri.toURL();
|
||||
|
||||
Map<String, String> parameterMap = new LinkedHashMap<>();
|
||||
String query = url.getQuery();
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
package com.sparrowwallet.sparrow.net;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
public class Auth47Test {
|
||||
@Test
|
||||
public void acceptsHttpsCallbacksWithResource() throws Exception {
|
||||
Auth47 auth47 = new Auth47(new URI("auth47://nonce?c=https://example.com/auth&r=example"));
|
||||
|
||||
assertEquals("https", auth47.getCallback().getProtocol());
|
||||
assertEquals("example.com", auth47.getCallback().getHost());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void acceptsSrbnCallbacks() throws Exception {
|
||||
Auth47 auth47 = new Auth47(new URI("auth47://nonce?c=srbn://alice@relay.example.com"));
|
||||
|
||||
assertEquals("https", auth47.getCallback().getProtocol());
|
||||
assertEquals("relay.example.com", auth47.getCallback().getHost());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void rejectsHttpClearnetCallbacks() {
|
||||
assertThrows(IllegalArgumentException.class, () ->
|
||||
new Auth47(new URI("auth47://nonce?c=http://example.com/auth&r=example")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void rejectsNonHttpCallbacksWithResource() {
|
||||
assertThrows(IllegalArgumentException.class, () ->
|
||||
new Auth47(new URI("auth47://nonce?c=file:///tmp/auth47&r=example")));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
package com.sparrowwallet.sparrow.net;
|
||||
|
||||
import com.sparrowwallet.drongo.protocol.Bech32;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.net.URI;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
public class LnurlAuthTest {
|
||||
private static final String K1 = "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f";
|
||||
|
||||
@Test
|
||||
public void acceptsHttpsCallbacks() throws Exception {
|
||||
LnurlAuth lnurlAuth = new LnurlAuth(lightningUri("https://example.com/lnurl-auth?tag=login&k1=" + K1));
|
||||
|
||||
assertEquals("example.com", lnurlAuth.getDomain());
|
||||
assertEquals("login to example.com", lnurlAuth.getLoginMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void acceptsHttpOnionCallbacks() throws Exception {
|
||||
LnurlAuth lnurlAuth = new LnurlAuth(lightningUri("http://abcdefghijklmnopqrstuvwxyzabcdefghijklmnop.onion/lnurl-auth?tag=login&k1=" + K1));
|
||||
|
||||
assertEquals("abcdefghijklmnopqrstuvwxyzabcdefghijklmnop.onion", lnurlAuth.getDomain());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void rejectsHttpClearnetCallbacks() {
|
||||
assertThrows(IllegalArgumentException.class, () ->
|
||||
new LnurlAuth(lightningUri("http://example.com/lnurl-auth?tag=login&k1=" + K1)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void rejectsNonHttpCallbacks() {
|
||||
assertThrows(IllegalArgumentException.class, () ->
|
||||
new LnurlAuth(lightningUri("ftp://example.com/lnurl-auth?tag=login&k1=" + K1)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void rejectsNonLnurlBech32Prefix() {
|
||||
assertThrows(IllegalArgumentException.class, () ->
|
||||
new LnurlAuth(lightningUri("lnurlx", "https://example.com/lnurl-auth?tag=login&k1=" + K1)));
|
||||
}
|
||||
|
||||
private static URI lightningUri(String url) throws Exception {
|
||||
return lightningUri("lnurl", url);
|
||||
}
|
||||
|
||||
private static URI lightningUri(String prefix, String url) throws Exception {
|
||||
byte[] urlBytes = url.getBytes(StandardCharsets.UTF_8);
|
||||
byte[] lnurlData = Bech32.convertBits(urlBytes, 0, urlBytes.length, 8, 5, true);
|
||||
return new URI("lightning:" + Bech32.encode(prefix, Bech32.Encoding.BECH32, lnurlData));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user