@capacitor/android 6.2.1 → 6.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -372,6 +372,12 @@ public class Bridge {
372
372
  }
373
373
 
374
374
  public boolean launchIntent(Uri url) {
375
+ // The proxy returns a remote body at the app origin, so block it before plugins can allow it.
376
+ String path = url.getPath();
377
+ if (path != null && path.startsWith(CAPACITOR_HTTP_INTERCEPTOR_START)) {
378
+ return true;
379
+ }
380
+
375
381
  /*
376
382
  * Give plugins the chance to handle the url
377
383
  */
@@ -999,7 +999,8 @@ public class Plugin {
999
999
  * Give the plugins a chance to take control when a URL is about to be loaded in the WebView.
1000
1000
  * Returning true causes the WebView to abort loading the URL.
1001
1001
  * Returning false causes the WebView to continue loading the URL.
1002
- * Returning null will defer to the default Capacitor policy
1002
+ * Returning null will defer to the default Capacitor policy.
1003
+ * Not called for Capacitor's internal HTTP proxy path, which is always blocked.
1003
1004
  */
1004
1005
  @SuppressWarnings("unused")
1005
1006
  public Boolean shouldOverrideLoad(Uri url) {
@@ -172,6 +172,11 @@ public class WebViewLocalServer {
172
172
  Uri loadingUrl = request.getUrl();
173
173
 
174
174
  if (null != loadingUrl.getPath() && loadingUrl.getPath().startsWith(Bridge.CAPACITOR_HTTP_INTERCEPTOR_START)) {
175
+ // Only fetch/XHR should reach the proxy; a document would run remote content at the app origin.
176
+ boolean httpEnabled = bridge.getConfig().getPluginConfiguration("CapacitorHttp").getBoolean("enabled", false);
177
+ if (!httpEnabled || isDocumentRequest(request)) {
178
+ return null;
179
+ }
175
180
  Logger.debug("Handling CapacitorHttp request: " + loadingUrl);
176
181
  try {
177
182
  return handleCapacitorHttpRequest(request);
@@ -197,6 +202,24 @@ public class WebViewLocalServer {
197
202
  }
198
203
  }
199
204
 
205
+ /** isForMainFrame() is false for an iframe and a fetch alike; only navigations send this header. */
206
+ private boolean isDocumentRequest(WebResourceRequest request) {
207
+ if (request.isForMainFrame()) {
208
+ return true;
209
+ }
210
+ Map<String, String> headers = request.getRequestHeaders();
211
+ if (headers == null) {
212
+ // The proxy needs the headers too, so the request fails there anyway.
213
+ return false;
214
+ }
215
+ for (String header : headers.keySet()) {
216
+ if ("Upgrade-Insecure-Requests".equalsIgnoreCase(header)) {
217
+ return true;
218
+ }
219
+ }
220
+ return false;
221
+ }
222
+
200
223
  private boolean isLocalFile(Uri uri) {
201
224
  String path = uri.getPath();
202
225
  return path.startsWith(capacitorContentStart) || path.startsWith(capacitorFileStart);
@@ -311,6 +334,9 @@ public class WebViewLocalServer {
311
334
  int responseCode = connection.getResponseCode();
312
335
  String reasonPhrase = getReasonPhraseFromResponseCode(responseCode);
313
336
 
337
+ // Nothing should render this. If anything does, sandbox keeps it inert and off the app origin.
338
+ responseHeaders.put("Content-Security-Policy", "sandbox; frame-ancestors 'none'");
339
+
314
340
  return new WebResourceResponse(mimeType, encoding, responseCode, reasonPhrase, responseHeaders, inputStream);
315
341
  }
316
342
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@capacitor/android",
3
- "version": "6.2.1",
3
+ "version": "6.2.2",
4
4
  "description": "Capacitor: Cross-platform apps with JavaScript and the web",
5
5
  "homepage": "https://capacitorjs.com",
6
6
  "author": "Ionic Team <hi@ionic.io> (https://ionic.io)",