From ca4063471f215d3f7525e51592d9c72138a52855 Mon Sep 17 00:00:00 2001 From: Chace Daniels Date: Wed, 12 Jul 2023 08:07:41 -0700 Subject: [PATCH] fix(cookies): sanitize url before retrieving/setting cookies Co-authored-by: Mike Summerfeldt <20338451+IT-MikeS@users.noreply.github.com> Co-authored-by: Mark Anderson --- .../plugin/CapacitorCookieManager.java | 51 +++++++-- .../getcapacitor/plugin/CapacitorCookies.java | 107 +++++------------- .../Plugins/CapacitorCookieManager.swift | 2 +- 3 files changed, 68 insertions(+), 92 deletions(-) diff --git a/android/capacitor/src/main/java/com/getcapacitor/plugin/CapacitorCookieManager.java b/android/capacitor/src/main/java/com/getcapacitor/plugin/CapacitorCookieManager.java index a78e805795..58e211fbd5 100644 --- a/android/capacitor/src/main/java/com/getcapacitor/plugin/CapacitorCookieManager.java +++ b/android/capacitor/src/main/java/com/getcapacitor/plugin/CapacitorCookieManager.java @@ -1,11 +1,13 @@ package com.getcapacitor.plugin; +import android.util.Log; import com.getcapacitor.Bridge; import java.net.CookieManager; import java.net.CookiePolicy; import java.net.CookieStore; import java.net.HttpCookie; import java.net.URI; +import java.net.URISyntaxException; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; @@ -22,6 +24,8 @@ public class CapacitorCookieManager extends CookieManager { private final String serverUrl; + private final String TAG = "CapacitorCookies"; + /** * Create a new cookie manager with the default cookie store and policy */ @@ -43,21 +47,28 @@ public CapacitorCookieManager(CookieStore store, CookiePolicy policy, Bridge bri this.serverUrl = bridge.getServerUrl(); } - public String getSanitizedDomain(String url) { + public String getSanitizedDomain(String url) throws URISyntaxException { if (url == null || url.isEmpty()) { - url = this.localUrl; + url = this.serverUrl; } try { new URI(url); - } catch (Exception ex) { - return this.serverUrl; + } catch (Exception ignored) { + url = this.localUrl; + + try { + new URI(url); + } catch (Exception error) { + Log.e(TAG, "Failed to get sanitized URL.", error); + throw error; + } } return url; } - private String getDomainFromCookieString(String cookie) { + private String getDomainFromCookieString(String cookie) throws URISyntaxException { String[] domain = cookie.toLowerCase(Locale.ROOT).split("domain="); return getSanitizedDomain(domain.length <= 1 ? null : domain[1].split(";")[0].trim()); } @@ -68,7 +79,15 @@ private String getDomainFromCookieString(String cookie) { * @return value the cookies as a string, using the format of the 'Cookie' HTTP request header */ public String getCookieString(String url) { - return webkitCookieManager.getCookie(url); + try { + url = getSanitizedDomain(url); + Log.i(TAG, "Getting cookies at: '" + url + "'"); + return webkitCookieManager.getCookie(url); + } catch (Exception error) { + Log.e(TAG, "Failed to get cookies at the given URL.", error); + } + + return null; } /** @@ -120,8 +139,14 @@ public HttpCookie[] getCookies(String url) { * @param value the cookie as a string, using the format of the 'Set-Cookie' HTTP response header */ public void setCookie(String url, String value) { - webkitCookieManager.setCookie(url, value); - flush(); + try { + url = getSanitizedDomain(url); + Log.i(TAG, "Setting cookie '" + value + "' at: '" + url + "'"); + webkitCookieManager.setCookie(url, value); + flush(); + } catch (Exception error) { + Log.e(TAG, "Failed to set cookie.", error); + } } /** @@ -169,11 +194,13 @@ public void put(URI uri, Map> responseHeaders) { // process each of the headers for (String headerValue : Objects.requireNonNull(responseHeaders.get(headerKey))) { - // Set at server url - setCookie(uri.toString(), headerValue); + try { + // Set at the requested server url + setCookie(uri.toString(), headerValue); - // Set at local url or domain - setCookie(getDomainFromCookieString(headerValue), headerValue); + // Set at the defined domain in the response or at default capacitor hosted url + setCookie(getDomainFromCookieString(headerValue), headerValue); + } catch (Exception ignored) {} } } } diff --git a/android/capacitor/src/main/java/com/getcapacitor/plugin/CapacitorCookies.java b/android/capacitor/src/main/java/com/getcapacitor/plugin/CapacitorCookies.java index f4fafe865b..8d92d62313 100644 --- a/android/capacitor/src/main/java/com/getcapacitor/plugin/CapacitorCookies.java +++ b/android/capacitor/src/main/java/com/getcapacitor/plugin/CapacitorCookies.java @@ -31,115 +31,64 @@ public boolean isEnabled() { return pluginConfig.getBoolean("enabled", false); } - /** - * Helper function for getting the serverUrl from the Capacitor Config. Returns an empty - * string if it is invalid and will auto-reject through {@code call} - * @param call the {@code PluginCall} context - * @return the string of the server specified in the Capacitor config - */ - private String getServerUrl(@Nullable PluginCall call) { - String url = (call == null) ? this.bridge.getServerUrl() : call.getString("url", this.bridge.getServerUrl()); - - if (url == null || url.isEmpty()) { - url = this.bridge.getLocalUrl(); - } - - URI uri = getUri(url); - if (uri == null) { - if (call != null) { - call.reject("Invalid URL. Check that \"server\" is passed in correctly"); - } - - return ""; - } - - return url; - } - - /** - * Try to parse a url string and if it can't be parsed, return null - * @param url the url string to try to parse - * @return a parsed URI - */ - private URI getUri(String url) { - try { - return new URI(url); - } catch (Exception ex) { - return null; - } - } - @JavascriptInterface public String getCookies() { - try { - String url = getServerUrl(null); - if (!url.isEmpty()) { - String cookieString = cookieManager.getCookieString(url); - return (null == cookieString) ? "" : cookieString; - } - } catch (Exception e) { - e.printStackTrace(); - } - - return ""; + String cookieString = cookieManager.getCookieString(null); + return (null == cookieString) ? "" : cookieString; } @JavascriptInterface public void setCookie(String domain, String action) { - String url = cookieManager.getSanitizedDomain(domain); - - if (!url.isEmpty()) { - cookieManager.setCookie(url, action); - } + cookieManager.setCookie(domain, action); } @PluginMethod public void getCookies(PluginCall call) { - String url = getServerUrl(call); - if (!url.isEmpty()) { - JSObject cookiesMap = new JSObject(); - HttpCookie[] cookies = cookieManager.getCookies(url); - for (HttpCookie cookie : cookies) { - cookiesMap.put(cookie.getName(), cookie.getValue()); - } - call.resolve(cookiesMap); + String url = call.getString("url"); + JSObject cookiesMap = new JSObject(); + HttpCookie[] cookies = cookieManager.getCookies(url); + for (HttpCookie cookie : cookies) { + cookiesMap.put(cookie.getName(), cookie.getValue()); } + call.resolve(cookiesMap); } @PluginMethod public void setCookie(PluginCall call) { String key = call.getString("key"); + if (null == key) { + call.reject("Must provide key"); + } String value = call.getString("value"); - String url = getServerUrl(call); + if (null == value) { + call.reject("Must provide value"); + } + String url = call.getString("url"); String expires = call.getString("expires", ""); String path = call.getString("path", "/"); - - if (!url.isEmpty()) { - cookieManager.setCookie(url, key, value, expires, path); - call.resolve(); - } + cookieManager.setCookie(url, key, value, expires, path); + call.resolve(); } @PluginMethod public void deleteCookie(PluginCall call) { String key = call.getString("key"); - String url = getServerUrl(call); - if (!url.isEmpty()) { - cookieManager.setCookie(url, key + "=; Expires=Wed, 31 Dec 2000 23:59:59 GMT"); - call.resolve(); + if (null == key) { + call.reject("Must provide key"); } + String url = call.getString("url"); + cookieManager.setCookie(url, key + "=; Expires=Wed, 31 Dec 2000 23:59:59 GMT"); + call.resolve(); } @PluginMethod public void clearCookies(PluginCall call) { - String url = getServerUrl(call); - if (!url.isEmpty()) { - HttpCookie[] cookies = cookieManager.getCookies(url); - for (HttpCookie cookie : cookies) { - cookieManager.setCookie(url, cookie.getName() + "=; Expires=Wed, 31 Dec 2000 23:59:59 GMT"); - } - call.resolve(); + String url = call.getString("url"); + HttpCookie[] cookies = cookieManager.getCookies(url); + for (HttpCookie cookie : cookies) { + cookieManager.setCookie(url, cookie.getName() + "=; Expires=Wed, 31 Dec 2000 23:59:59 GMT"); } + call.resolve(); } @PluginMethod diff --git a/ios/Capacitor/Capacitor/Plugins/CapacitorCookieManager.swift b/ios/Capacitor/Capacitor/Plugins/CapacitorCookieManager.swift index 998fa2f4cf..1c61477c87 100644 --- a/ios/Capacitor/Capacitor/Plugins/CapacitorCookieManager.swift +++ b/ios/Capacitor/Capacitor/Plugins/CapacitorCookieManager.swift @@ -21,7 +21,7 @@ public class CapacitorCookieManager { } public func getServerUrl() -> URL? { - return self.config?.serverURL + return self.config?.serverURL ?? self.config?.localURL } private func isUrlSanitized(_ urlString: String) -> Bool {