Medium chrome Logic Error 📄 Reporter bug report 🔧 Commit mapped

Overview

Medium
Severity
CVSS
No
Exploited ITW
Fixed
Fix Status
ImpactIncorrect authorization in WebView
DescriptionIncorrect authorization in WebView
ComponentWebView
Bug ClassLogic Error
Tracker498730641
Fix commitc5544d8f4463 (chromium/src) +106/-10
CISA KEVNot listed
CreditedGoogle
Disclosed2026-09-08

Background

`allow_universal_access_from_file_urls`
A WebPreference (enabled by default in Android WebView) that lets documents loaded from file: URLs access resources of any origin.
`RenderFrameHostImpl::ValidateURLAndOrigin`
The browser-side check that decides whether a renderer-supplied URL and origin are legal to commit for a given frame.
Same-document navigation
A commit such as history.pushState that changes the document’s URL without loading a new document, and which a renderer can drive by IPC.
`ChildProcessSecurityPolicyImpl`
The browser-side authority that tracks which origins and URLs each renderer process is permitted to commit, granting per-process exemptions like HasOriginCheckExemptionForWebView.

Root Cause Analysis

The vulnerable path was RenderFrameHostImpl::ValidateURLAndOrigin, which granted the allow_universal_access_from_file_urls exemption whenever the renderer-supplied origin.scheme() was url::kFileScheme, without checking whether the browser’s own last_committed_origin_ was actually a file: origin. This violated the invariant that a document may only claim a file: origin if it was genuinely loaded from a file: URL, letting a compromised non-file: renderer send a same-document commit asserting a file: origin that passed validation. Compounding this, DidCommitNavigationInternal granted process-wide origin-check exemptions in ChildProcessSecurityPolicyImpl before calling ValidateDidCommitParams, so a renderer could obtain those exemptions from parameters that were never fully validated.

The fix adds the last_committed_origin_.scheme() == url::kFileScheme conjunct so the exemption only applies to documents that were already file: documents, and moves the ValidateDidCommitParams call earlier so commit parameters are fully validated before any exemption is granted. Because legitimate file: documents retain their original file: origin in last_committed_origin_ across same-document navigations, repeated pushState calls still pass the tightened check.

Key insight
The core mistake was authorizing the file: universal-access exemption from the renderer-claimed origin alone rather than the browser’s already-committed origin; the fix conditions the exemption on last_committed_origin_ genuinely being a file: origin and validates commit parameters before any exemption is granted.

Attack Path

  1. Compromise a non-file renderer An attacker gains code execution in a renderer process hosting a non-file: document (e.g., foo.com) in a WebView where allow_universal_access_from_file_urls is enabled.
  2. Forge a same-document commit The compromised renderer sends a same-document commit (e.g., a pushState) whose params->origin is replaced with a file: origin while keeping the original URL.
  3. Pass the weak validation ValidateURLAndOrigin sees origin.scheme() == url::kFileScheme and returns true under the universal-access exemption without checking last_committed_origin_.
  4. Prematurely obtain exemptions Because exemptions were granted before ValidateDidCommitParams, the process picks up a file: origin-check exemption in ChildProcessSecurityPolicyImpl.
  5. Spoof file origin The non-file: renderer now holds a file: origin and its associated cross-origin access privileges it was never entitled to.

Impact Assessment

An attacker with a compromised, non-file: renderer process in an affected WebView gains the ability to spoof a file: origin and acquire the broad cross-origin access that allow_universal_access_from_file_urls normally reserves for genuine file: documents, effecting an incorrect-authorization / origin-confusion escalation. This occurs in the renderer/browser boundary of Android WebView embedders where allow_universal_access_from_file_urls is enabled. Preconditions are that the setting is enabled and the attacker already controls a renderer capable of sending a crafted same-document commit IPC.

Changed Functions

FunctionChangeNotes
if
content/browser/renderer_host/render_frame_host_impl.cc
modified

Files Changed

  • content/browser/renderer_host/render_frame_host_impl.cc
  • content/browser/security_exploit_browsertest.cc

Audit Directions

  • Renderer-claimed vs. browser-tracked origin
    Flag any authorization decision that keys off a renderer-supplied origin/URL without cross-checking the browser’s last_committed_origin_ or other trusted browser-side state.
  • Ordering of validation and privilege grants
    Verify that every ValidateDidCommitParams-style security check runs before any call that grants process-wide exemptions in ChildProcessSecurityPolicyImpl, so privileges are never derived from unvalidated commit parameters.
  • WebPreference-gated exemptions
    Review other WebPreference-gated bypasses (e.g., allow_universal_access_from_file_urls, LoadDataWithBaseURL paths) to confirm each is anchored to a verified document provenance rather than a single scheme comparison.
From c5544d8f4463bad62746cd29acf7f0807c586b7e Mon Sep 17 00:00:00 2001
From: Paulius Trucinskas <[email protected]>
Date: Tue, 04 Aug 2026 09:59:17 -0700
Subject: [PATCH] Fix File Scheme Origin Spoofing

When allow_universal_access_from_file_urls WebPreference is enabled
(e.g., in Android WebView), ValidateURLAndOrigin() previously permitted
any renderer to commit a file: origin without verifying whether the
browser-side document was originally loaded from a file: URL. A
compromised non-file renderer process could perform a same-document
commit claiming a file: origin, passing validation and prematurely
obtaining process origin check exemptions in
ChildProcessSecurityPolicy.

This CL fixes the issue by:
1. Requiring that last_committed_origin_ already has a file: scheme in
RenderFrameHostImpl::ValidateURLAndOrigin() before allowing the
allow_universal_access_from_file_urls exemption.
2. Moving ValidateDidCommitParams() in DidCommitNavigationInternal() so
that commit parameters are fully validated before any process-wide
origin exemptions are granted.
3. Adding regression tests in security_exploit_browsertest.cc verifying
that non-file documents cannot commit file: origins, and that
legitimate file: documents can safely perform multiple same-document
pushState calls without losing their committed file: origin status.

Bug: 498730641
Change-Id: I855cb331547776959423feb3eb409e0734f3e160
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/8158742
Reviewed-by: Rakina Zata Amni <[email protected]>
Reviewed-by: Ashley Newson <[email protected]>
Commit-Queue: Paulius Tručinskas <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1673438}
---

diff --git a/content/browser/renderer_host/render_frame_host_impl.cc b/content/browser/renderer_host/render_frame_host_impl.cc
index 9fde6e2..7921961 100644
--- a/content/browser/renderer_host/render_frame_host_impl.cc
+++ b/content/browser/renderer_host/render_frame_host_impl.cc
@@ -15908,7 +15908,16 @@
   // the setting is disabled (e.g., due to document.open), they are allowed a
   // narrower exemption in ChildProcessSecurityPolicyImpl::CanCommitOriginAndUrl
   // due to compatibility requirements for existing apps.
-  if (origin.scheme() == url::kFileScheme) {
+  //
+  // This exemption is conditioned on the browser-side last committed origin
+  // already being a file origin, so that documents which were not loaded from
+  // file URLs cannot use it to commit unexpected origins.
+  //
+  // In case of multiple same-document navigations, the last_committed_origin_
+  // is kept as the original file: origin, so each same-document navigation can
+  // still pass this check.
+  if (origin.scheme() == url::kFileScheme &&
+      last_committed_origin_.scheme() == url::kFileScheme) {
     auto prefs = GetOrCreateWebPreferences();
     if (prefs.allow_universal_access_from_file_urls) {
       return true;
@@ -16240,6 +16249,15 @@
     return false;
   }
 
+  if (!ValidateDidCommitParams(navigation_request.get(), params.get(),
+                               is_same_document_navigation)) {
+    if (navigation_request) {
+      navigation_request->set_navigation_discard_reason(
+          NavigationDiscardReason::kFailedSecurityCheck);
+    }
+    return false;
+  }
+
   // Any opaque origin loaded with LoadDataWithBaseURL can bypass some of the
   // URL and origin validation checks in unlocked processes, including both the
   // original document and any about:blank frames that inherit the same origin.
@@ -16255,6 +16273,10 @@
   // setting is later disabled and then a previously-exempted URL is inherited
   // by a new same-origin document via document.open.
   //
+  // These exemptions are granted only after `params->origin` has been
+  // validated above, so that they are not based on values that the browser
+  // would otherwise reject.
+  //
   // TODO(crbug.com/40092527): Move these to UpdatePermissionsForNavigation
   // once origin can be reliably computed by NavigationRequest at commit time.
   if (navigation_request && navigation_request->IsLoadDataWithBaseURL() &&
@@ -16283,15 +16305,6 @@
     base::debug::SetCrashKeyString(crash_key, "true");
   }
 
-  if (!ValidateDidCommitParams(navigation_request.get(), params.get(),
-                               is_same_document_navigation)) {
-    if (navigation_request) {
-      navigation_request->set_navigation_discard_reason(
-          NavigationDiscardReason::kFailedSecurityCheck);
-    }
-    return false;
-  }
-
   // TODO(clamy): We should stop having a special case for same-document
   // navigation and just put them in the general map of NavigationRequests.
   if (navigation_request &&
diff --git a/content/browser/security_exploit_browsertest.cc b/content/browser/security_exploit_browsertest.cc
index fea640bf..c64bb87 100644
--- a/content/browser/security_exploit_browsertest.cc
+++ b/content/browser/security_exploit_browsertest.cc
@@ -1103,6 +1103,89 @@
   EXPECT_EQ(bad_message::RFH_INVALID_ORIGIN_ON_COMMIT, kill_waiter.Wait());
 }
 
+// Test that same-document navigations cannot claim to commit a file: origin
+// when the last committed origin is not a file URL, even if
+// allow_universal_access_from_file_urls is enabled. The universal access
+// setting allows file: documents to navigate to other origins, but does not
+// allow non-file documents to become file: documents.
+IN_PROC_BROWSER_TEST_F(SecurityExploitBrowserTest,
+                       CrossOriginSameDocumentCommitUniversalAccessFileOrigin) {
+  auto prefs = shell()->web_contents()->GetOrCreateWebPreferences();
+  prefs.allow_universal_access_from_file_urls = true;
+  shell()->web_contents()->SetWebPreferences(prefs);
+
+  GURL start_url(embedded_test_server()->GetURL("foo.com", "/title1.html"));
+  EXPECT_TRUE(NavigateToURL(shell(), start_url));
+
+  RenderFrameHostImpl* rfh = static_cast<RenderFrameHostImpl*>(
+      shell()->web_contents()->GetPrimaryMainFrame());
+  url::Origin file_origin = url::Origin::Create(GURL("file:///"));
+  EXPECT_FALSE(ChildProcessSecurityPolicyImpl::GetInstance()
+                   ->HasOriginCheckExemptionForWebView(
+                       rfh->GetProcess()->GetDeprecatedID(), file_origin));
+
+  // Do a same-document navigation, using an interceptor that replaces the
+  // origin with a file: origin while keeping the original URL. The browser
+  // should reject this because the previously committed origin is not file:.
+  PwnCommitIPC(shell()->web_contents(), start_url, start_url, file_origin);
+  RenderProcessHostBadIpcMessageWaiter kill_waiter(rfh->GetProcess());
+  // ExecJs will sometimes finish before the renderer gets killed, so we must
+  // ignore the result.
+  std::ignore = ExecJs(rfh, "history.pushState({}, '', location.href);");
+  EXPECT_EQ(bad_message::RFH_INVALID_ORIGIN_ON_COMMIT, kill_waiter.Wait());
+
+  // The process should not have been granted an origin check exemption based
+  // on the rejected commit's origin.
+  EXPECT_FALSE(ChildProcessSecurityPolicyImpl::GetInstance()
+                   ->HasOriginCheckExemptionForWebView(
+                       rfh->GetProcess()->GetDeprecatedID(), file_origin));
+}
+
+// Test that a file: URL document with allow_universal_access_from_file_urls
+// enabled can perform multiple same-document pushState navigations to different
+// cross-origin URLs without losing its file: committed origin or causing
+// browser-side validation failures on subsequent pushState calls.
+// NOTE: Universal access from file scheme behaves differently on macOS, so the
+// test is disabled on macOS (crbug.com/981018).
+#if BUILDFLAG(IS_MAC)
+#define MAYBE_MultipleCrossOriginSameDocumentPushStateFromFileUrl \
+  DISABLED_MultipleCrossOriginSameDocumentPushStateFromFileUrl
+#else
+#define MAYBE_MultipleCrossOriginSameDocumentPushStateFromFileUrl \
+  MultipleCrossOriginSameDocumentPushStateFromFileUrl
+#endif
+IN_PROC_BROWSER_TEST_F(
+    SecurityExploitBrowserTest,
+    MAYBE_MultipleCrossOriginSameDocumentPushStateFromFileUrl) {
+  auto prefs = shell()->web_contents()->GetOrCreateWebPreferences();
+  prefs.allow_universal_access_from_file_urls = true;
+  shell()->web_contents()->SetWebPreferences(prefs);
+
+  GURL file_url = GetTestUrl("", "simple_page.html");
+  ASSERT_TRUE(file_url.SchemeIsFile());
+  ASSERT_TRUE(NavigateToURL(shell(), file_url));
+
+  RenderFrameHostImpl* rfh = static_cast<RenderFrameHostImpl*>(
+      shell()->web_contents()->GetPrimaryMainFrame());
+  url::Origin initial_origin = rfh->GetLastCommittedOrigin();
+  EXPECT_EQ(url::kFileScheme, initial_origin.scheme());
+
+  // Perform first pushState to a cross-origin HTTPS URL.
+  EXPECT_TRUE(
+      ExecJs(rfh, "history.pushState({}, '', 'https://example.com/1');"));
+  EXPECT_TRUE(rfh->IsRenderFrameLive());
+  EXPECT_EQ(initial_origin, rfh->GetLastCommittedOrigin());
+
+  // Perform second pushState to a different cross-origin HTTPS URL.
+  // Verify that the browser still retains the file: origin on
+  // last_committed_origin_ and allows the second same-document navigation
+  // to succeed.
+  EXPECT_TRUE(
+      ExecJs(rfh, "history.pushState({}, '', 'https://example.org/2');"));
+  EXPECT_TRUE(rfh->IsRenderFrameLive());
+  EXPECT_EQ(initial_origin, rfh->GetLastCommittedOrigin());
+}
+
 // Test that receiving a commit with a URL with an invalid scheme properly
 // terminates the renderer process. See https://crbug.com/324934416.
 // TODO(crbug.com/40092527): This test can be removed once the browser
Loading diff…

Regression Test / PoC

shipped with the fix
diff --git a/content/browser/security_exploit_browsertest.cc b/content/browser/security_exploit_browsertest.cc
index fea640bf..c64bb87 100644
--- a/content/browser/security_exploit_browsertest.cc
+++ b/content/browser/security_exploit_browsertest.cc
@@ -1103,6 +1103,89 @@
   EXPECT_EQ(bad_message::RFH_INVALID_ORIGIN_ON_COMMIT, kill_waiter.Wait());
 }
 
+// Test that same-document navigations cannot claim to commit a file: origin
+// when the last committed origin is not a file URL, even if
+// allow_universal_access_from_file_urls is enabled. The universal access
+// setting allows file: documents to navigate to other origins, but does not
+// allow non-file documents to become file: documents.
+IN_PROC_BROWSER_TEST_F(SecurityExploitBrowserTest,
+                       CrossOriginSameDocumentCommitUniversalAccessFileOrigin) {
+  auto prefs = shell()->web_contents()->GetOrCreateWebPreferences();
+  prefs.allow_universal_access_from_file_urls = true;
+  shell()->web_contents()->SetWebPreferences(prefs);
+
+  GURL start_url(embedded_test_server()->GetURL("foo.com", "/title1.html"));
+  EXPECT_TRUE(NavigateToURL(shell(), start_url));
+
+  RenderFrameHostImpl* rfh = static_cast<RenderFrameHostImpl*>(
+      shell()->web_contents()->GetPrimaryMainFrame());
+  url::Origin file_origin = url::Origin::Create(GURL("file:///"));
+  EXPECT_FALSE(ChildProcessSecurityPolicyImpl::GetInstance()
+                   ->HasOriginCheckExemptionForWebView(
+                       rfh->GetProcess()->GetDeprecatedID(), file_origin));
+
+  // Do a same-document navigation, using an interceptor that replaces the
+  // origin with a file: origin while keeping the original URL. The browser
+  // should reject this because the previously committed origin is not file:.
+  PwnCommitIPC(shell()->web_contents(), start_url, start_url, file_origin);
+  RenderProcessHostBadIpcMessageWaiter kill_waiter(rfh->GetProcess());
+  // ExecJs will sometimes finish before the renderer gets killed, so we must
+  // ignore the result.
+  std::ignore = ExecJs(rfh, "history.pushState({}, '', location.href);");
+  EXPECT_EQ(bad_message::RFH_INVALID_ORIGIN_ON_COMMIT, kill_waiter.Wait());
+
+  // The process should not have been granted an origin check exemption based
+  // on the rejected commit's origin.
+  EXPECT_FALSE(ChildProcessSecurityPolicyImpl::GetInstance()
+                   ->HasOriginCheckExemptionForWebView(
+                       rfh->GetProcess()->GetDeprecatedID(), file_origin));
+}
+
+// Test that a file: URL document with allow_universal_access_from_file_urls
+// enabled can perform multiple same-document pushState navigations to different
+// cross-origin URLs without losing its file: committed origin or causing
+// browser-side validation failures on subsequent pushState calls.
+// NOTE: Universal access from file scheme behaves differently on macOS, so the
+// test is disabled on macOS (crbug.com/981018).
+#if BUILDFLAG(IS_MAC)
+#define MAYBE_MultipleCrossOriginSameDocumentPushStateFromFileUrl \
+  DISABLED_MultipleCrossOriginSameDocumentPushStateFromFileUrl
+#else
+#define MAYBE_MultipleCrossOriginSameDocumentPushStateFromFileUrl \
+  MultipleCrossOriginSameDocumentPushStateFromFileUrl
+#endif
+IN_PROC_BROWSER_TEST_F(
+    SecurityExploitBrowserTest,
+    MAYBE_MultipleCrossOriginSameDocumentPushStateFromFileUrl) {
+  auto prefs = shell()->web_contents()->GetOrCreateWebPreferences();
+  prefs.allow_universal_access_from_file_urls = true;
+  shell()->web_contents()->SetWebPreferences(prefs);
+
+  GURL file_url = GetTestUrl("", "simple_page.html");
+  ASSERT_TRUE(file_url.SchemeIsFile());
+  ASSERT_TRUE(NavigateToURL(shell(), file_url));
+
+  RenderFrameHostImpl* rfh = static_cast<RenderFrameHostImpl*>(
+      shell()->web_contents()->GetPrimaryMainFrame());
+  url::Origin initial_origin = rfh->GetLastCommittedOrigin();
+  EXPECT_EQ(url::kFileScheme, initial_origin.scheme());
+
+  // Perform first pushState to a cross-origin HTTPS URL.
+  EXPECT_TRUE(
+      ExecJs(rfh, "history.pushState({}, '', 'https://example.com/1');"));
+  EXPECT_TRUE(rfh->IsRenderFrameLive());
+  EXPECT_EQ(initial_origin, rfh->GetLastCommittedOrigin());
+
+  // Perform second pushState to a different cross-origin HTTPS URL.
+  // Verify that the browser still retains the file: origin on
+  // last_committed_origin_ and allows the second same-document navigation
+  // to succeed.
+  EXPECT_TRUE(
+      ExecJs(rfh, "history.pushState({}, '', 'https://example.org/2');"));
+  EXPECT_TRUE(rfh->IsRenderFrameLive());
+  EXPECT_EQ(initial_origin, rfh->GetLastCommittedOrigin());
+}
+
 // Test that receiving a commit with a URL with an invalid scheme properly
 // terminates the renderer process. See https://crbug.com/324934416.
 // TODO(crbug.com/40092527): This test can be removed once the browser
Loading diff…

Original Bug Report

reported by [email protected]

Sandbox Escape: File Scheme Origin Spoofing via Same-Document Navigation in WebView

Project Fortify, an experimental security project, has identified the following potential security issue. If you’re a feature owner CC-ed on this bug, please do your best to review these reports without the security team.

Overview: A logic error in RenderFrameHostImpl::DidCommitNavigationInternal allows a compromised renderer to spoof its origin during a same-document navigation. When allow_universal_access_from_file_urls is enabled (common in Android WebView), the browser trusts the renderer-provided file:// origin without validation and grants a process-wide security exemption. This allows the compromised renderer to bypass site isolation and read arbitrary local files.

Affected files:

  • content/browser/renderer_host/render_frame_host_impl.cc

Estimated timestamp from git blame: 2024-12-10

Summary

A potential critical vulnerability exists in RenderFrameHostImpl::DidCommitNavigationInternal where process-wide origin check exemptions are granted to a renderer process based on renderer-supplied parameters before those parameters are rigorously validated. In environments where the allow_universal_access_from_file_urls preference is enabled (frequently used in Android WebView), a compromised renderer can exploit this to gain permanent access to arbitrary local files (file:// origins), effectively escaping the renderer sandbox.

Vulnerability Details

The issue resides in how mojom::DidCommitProvisionalLoadParams are handled during a renderer-initiated same-document navigation.

  1. Missing Origin Mismatch Check: When a compromised renderer sends a DidCommitSameDocumentNavigation IPC, the browser attempts to find a matching pending NavigationRequest. Since it’s a renderer-initiated same-document navigation, the NavigationRequest is nullptr. In RenderFrameHostImpl::DidCommitNavigationInternal, the check meant to detect origin spoofing is bypassed because navigation_request is null:

    // content/browser/renderer_host/render_frame_host_impl.cc
    if (navigation_request &&
        navigation_request->commit_params().navigation_token !=
            params->navigation_token) {
       // ... crash logic ...
    }
    
  2. Premature Exemption Grant: Further down in DidCommitNavigationInternal, the browser grants a process-wide origin exemption based entirely on the unvalidated, attacker-controlled params->origin:

    if (GetOrCreateWebPreferences().allow_universal_access_from_file_urls &&
        params->origin.scheme() == url::kFileScheme) {
      ChildProcessSecurityPolicyImpl::GetInstance()
          ->GrantOriginCheckExemptionForWebView(GetProcess()->GetDeprecatedID(),
                                                params->origin);
    }
    
  3. Validation Bypass: The function then calls ValidateDidCommitParams, which delegates to ValidateURLAndOrigin. This function contains an early return that explicitly trusts file:// schemes if universal access is enabled:

    if (origin.scheme() == url::kFileScheme) {
      auto prefs = GetOrCreateWebPreferences();
      if (prefs.allow_universal_access_from_file_urls) {
        return true;
      }
    }
    

    This early return bypasses CanCommitOriginAndUrl, skipping the strict consistency checks between the URL and the origin.

  4. State Update: Finally, because features::IsEnforceSameDocumentOriginInvariantsEnabled() is disabled by default, the browser updates its canonical state (last_committed_origin_) to the attacker’s spoofed file:// origin.

Potential Exploitation Steps

(Note: These are suggested steps; our tooling agent cannot execute a live proof of concept.)

  1. An attacker gains arbitrary code execution within a sandboxed renderer process in an Android WebView application that has allow_universal_access_from_file_urls enabled.
  2. The compromised renderer crafts a mojom::FrameHost::DidCommitSameDocumentNavigation IPC.
  3. In the payload, the attacker sets params->origin to a target file origin (e.g., file:///data/data/com.target.app/databases/secret.db).
  4. The browser receives the IPC. Because it’s a same-document navigation, the NavigationRequest is null, bypassing the token mismatch check.
  5. The browser executes the universal access logic, sees the file:// scheme, and grants the renderer a permanent process-wide exemption for that origin in ChildProcessSecurityPolicyImpl.
  6. The browser updates last_committed_origin_ to the spoofed file:// origin.
  7. The renderer can now instantiate a FileURLLoader (e.g., via a fetch() call). Because it holds an exemption and the browser’s state matches the requested origin, security checks pass, allowing the attacker to read local files and escape the sandbox.

Proposed Fix

Do not grant the ChildProcessSecurityPolicyImpl origin check exemption based on unvalidated IPC parameters. The exemption logic in DidCommitNavigationInternal should be deferred until after ValidateDidCommitParams has run, or it should rely on browser-side state rather than renderer-provided claims. Alternatively, the early return in ValidateURLAndOrigin should be restructured to ensure that consistency checks (like params->url matching params->origin) are not completely bypassed even when universal access is enabled.

Evaluated with Chrome root at commit: e9e0fcbb690b1a8c1a26c81c2a9ea23d6e178368


Results so far have been promising, but there can be wrong deductions. If this proves to be a false positive, please close as WAI; data from false positives will be used to improve accuracy over time. And please feel free to reach out to me directly if you have concerns or feedback on the project.

View on issue tracker