How to / is it possible to ensure no internet access in JavaScript web application?

I have been interested in providing web apps that can be accessed from a website, but are used completely offline.
The reason for this is to prove that privacy is being protected at a technical level.
However, I have only been able to find a few solutions.

The obvious solution is to overwrite APIs that access the internet so that even external libraries can not access these.
This is more difficult than it seems, with just how many ways JavaScript can interact with other servers these days.
There is also the issue of making sure this code is executed before any external libraries. Otherwise, the external libraries can get access to these APIs before any global changes are made.

Nothing beats proper code reviews, but unless the entire web application is open source and popular enough to be checked by many developers, this isn’t really a good solution.

A better solution would be for users to have say an extension that watches for internet access and make sure it does not happen. This is possible with the dev tools, and isn’t too difficult if extensions are disabled, but is still a lot of effort, risk, and not easy for non-technical users.

In Electron apps, it does seem partially possible to block internet access, but it doesn’t block at the Node level:
https://stackoverflow.com/a/69620535/1764521

It does seem at this point, there are no easy solutions, and that doing the best possible at every stage is the best that could be done. I’d say that would be good enough from a developer’s perspective, but from the user’s perspective, I think it still seems a bit risky for sensitive data.

I have left my conversation below with AI below that tried finding solutions, which only resulted in only partially useful information. If anyone has any better solutions, please feel free to comment.

When create a PWA, is it possible to completely prevent internet access? If yes, how should this be done, especially in a way that the end user can trust?

No, it’s not possible to completely prevent internet access within a PWA itself. Here’s why:

  1. PWAs rely on browsers: PWAs are web applications that leverage browser functionalities. Browsers are inherently designed to access the internet, and limiting this function would go against their core purpose.
  2. Security concerns: Completely blocking internet access within a PWA raises significant security concerns. It would essentially create a closed environment, making it difficult to implement security updates, bug fixes, and new features. This could leave the PWA vulnerable to known and future exploits.

However, there are alternative approaches that can offer a similar user experience while maintaining transparency and trust:

1. Leverage Caching and Offline Functionality:

  • You can leverage the service worker API to cache essential app resources like data and static files. This allows the PWA to function partially even when offline.
  • Design the PWA to gracefully handle offline scenarios by informing users they’re offline and displaying appropriate UI elements like error messages or cached versions of content.

2. User-controlled Offline Mode:

  • Implement an optional “offline mode” toggle within the PWA. This allows users to choose to operate offline for specific features or functionalities.
  • Clearly communicate the limitations and functionality available in offline mode to build trust with users.

3. Emphasize Transparency:

  • Clearly state in the PWA’s description and store listing that it requires an internet connection for full functionality.
  • Be upfront about any limitations regarding offline capabilities.

Remember, the key is to provide a secure and reliable experience for users while remaining transparent about the PWA’s capabilities and limitations.

So there are no features in PWA manifest, service workers, or other APIs that allow for preventing internet access even if the PWA is locally stored?

You are correct. There are no features within the PWA manifest, service workers, or other Web APIs designed to completely prevent internet access for a PWA.

Here’s a breakdown of why:

  • PWA Manifest: The manifest file focuses on providing information about the PWA, such as its name, icons, and launch details. It doesn’t have functionalities related to controlling network access.
  • Service Workers: Service workers act as intermediaries between the PWA and the network. While they can manage caching and network requests, they cannot entirely block network access. Their purpose is to enhance the offline experience, not restrict it completely.
  • Web APIs: Web APIs provide functionalities for various tasks like fetching data, accessing sensors, and manipulating the UI. None of the standard Web APIs offer the ability to disable network access altogether.

It’s important to understand that PWAs rely on the browser environment, and browsers inherently have internet access as a core function. Restricting it within a PWA would not only be technically challenging but also potentially detrimental to the app’s functionality and security.

Are there not talks about this anywhere? Surely fully offline web apps are desired.

You’re right, there are ongoing discussions and explorations regarding the possibility of fully offline web applications. While completely preventing internet access within PWAs faces the limitations mentioned earlier, there are alternative approaches and ongoing efforts aiming to achieve a similar goal:

1. WebAssembly (WASM): WASM is a low-level assembly language that allows developers to compile code from various languages (like C++) and run it efficiently within web browsers. This opens the possibility of creating web apps that can bundle their own functionalities and data, potentially enabling offline usage to a greater extent.

2. Web App Manifest – “network_state” property (proposal): There’s an ongoing proposal to introduce a new property called “network_state” within the PWA manifest. This property, if implemented, could potentially allow developers to indicate the level of network connectivity required by the PWA. While it wouldn’t directly restrict access, it could inform users about potential limitations when offline and provide a more transparent experience.

3. Dedicated APIs for offline functionality: Discussions are happening regarding the potential for dedicated Web APIs that could enhance offline capabilities for web apps. These APIs could focus on functionalities like local data storage, synchronization, and background tasks, offering developers more tools to build robust offline experiences.

It’s important to note that these are ongoing discussions and proposals, and their implementation or final form may vary. However, they highlight the ongoing interest in and efforts towards providing better offline experiences and functionalities for web applications.

How about if I use Electron?

Electron offers a different approach compared to PWAs, and it can be used to create applications that function entirely offline. Here’s how:

Electron’s Offline Capabilities:

  • Bundled Application: Unlike PWAs that rely on the browser, Electron apps are self-contained, meaning they bundle all necessary resources (HTML, CSS, JavaScript, and other files) within the application package. This eliminates the need for internet access after the initial download and installation.
  • Native Functionality: Electron allows developers to access native system functionalities like file systems, local storage, and device hardware. This enables developers to create applications that can store data locally, perform tasks without requiring internet access, and offer a more desktop-like experience.

However, there are some trade-offs to consider:

  • Distribution complexity: Electron applications are not directly deployable through app stores like PWAs. They need to be packaged for specific operating systems and distributed through custom channels.
  • Platform dependency: Electron applications are native and run differently on various operating systems (Windows, macOS, Linux) compared to the cross-platform nature of PWAs. This means developers need to create and maintain separate codebases for different platforms.

Overall, Electron is a viable option if:

  • You prioritize complete offline functionality and native-like features.
  • You are comfortable with the complexities of building and distributing a desktop application.

If your primary focus is on:

  • Easy deployment and accessibility through web browsers.
  • Providing a web-based experience with enhanced offline capabilities, PWAs remain a valuable option.

Ultimately, the best approach depends on your specific project requirements and priorities.

However, in Electron, how is offline only proven to the user?

Proving that an Electron application functions entirely offline is a multifaceted process that involves a combination of technical considerations and user experience design:

1. Code Review and Testing:

  • Thorough code review: Conduct a comprehensive review of your application’s code to ensure there are no hidden dependencies on external resources or network calls. This involves verifying all functionalities and data access methods.
  • Offline testing: Rigorously test your application in a completely disconnected environment to simulate an offline scenario. This helps identify any unexpected behavior or potential issues related to missing resources.
  • Static code analysis tools: Utilize static code analysis tools to scan your codebase and identify potential network interactions or external dependencies that might not be readily apparent during manual review.

2. User Experience Design:

  • Clear communication: Inform users upfront about the app’s offline capabilities. This can be done through the application description, splash screen, or in-app messages.
  • Offline mode indicator: Implement a visual indicator like an icon or message to clearly communicate the app’s online/offline status to users.
  • Graceful handling of potential network issues: Handle potential network disruptions gracefully by displaying informative messages and providing alternative functionalities while offline.
  • Avoid misleading functionality: Avoid offering features or buttons that appear to be functional but are inoperable due to the lack of internet connection. Disable or gray out such features in offline mode.

3. Third-party library assessment:

  • Evaluate dependencies: If you utilize third-party libraries, carefully evaluate their potential network requirements. Opt for libraries with minimal dependencies or those explicitly designed for offline usage. Consider alternatives or implementing workarounds if necessary.

4. Documentation:

  • Provide clear documentation: Clearly document the application’s offline capabilities and limitations in the user manual or in-app help section. This helps users understand what to expect when using the app offline.

It’s important to remember that fully guaranteeing complete offline functionality can be challenging due to external factors like unforeseen updates or changes in the operating system or underlying libraries. However, by implementing these strategies, you can significantly increase user trust and confidence in your Electron application’s offline capabilities.

Is there nothing a bit clearer, such as a manifest property/permission?

Unfortunately, there isn’t a single, universally clear manifest property or permission in Electron that explicitly guarantees an application functions entirely offline. However, there are ongoing discussions and potential future advancements that might bring us closer to such a solution:

1. Declarative Net Request Permission (proposal): A proposal for a new API called “Declarative Net Request Permission” is under discussion. This API could potentially allow developers to declare their application’s network access requirements within the manifest file. While not a direct guarantee of offline functionality, it could provide a clearer indication to users about the app’s intended network usage.

2. Code signing and verification: While not a direct solution within Electron itself, advancements in code signing and verification technologies could offer a layer of trust to users. By cryptographically signing your application code and having it verified by a trusted authority, users could gain more confidence in the application’s integrity and potential offline capabilities.

It’s important to note that these are proposals and future advancements, and their implementation or final form is subject to change. However, they highlight the ongoing efforts to improve transparency and user trust regarding application behavior, including offline functionality.

For now, the strategies mentioned earlier, focusing on code review, testing, user experience design, and clear communication, remain the most effective ways to establish trust and confidence in your Electron application’s offline capabilities.

Exploring the goal of common WordPress and PHP attack paths.

After checking the access logs for any suspicious activity on the server, I noticed some common paths that seemed to come up a lot.
Checking about them through Gemini AI and online searches provided the following information:


Here’s a breakdown of the listed paths and why some are likely attacks:

Likely Attacks:

  • /wp-content/uploads/wp-casper.php: This file is not a standard WordPress file and likely a malicious script for uploading malware or exploiting vulnerabilities.
  • /wp-content/uploads/uploads.php: Uploading functionality is typically handled by WordPress core, not a separate script in the uploads folder. This suggests a potential attempt to bypass security measures.
  • /wp-content/uploads/wso112233.php: This filename format (wsoXXXX) is commonly associated with webshell tools used for gaining unauthorized access.
  • /wp-content/uploads/2023/wp-signup.php: While a legitimate signup script could exist in this location for some plugins, it’s uncommon. The presence of a year in the path makes it more suspicious.
  • /wp-includes/css/wp-config.php: This is a highly critical configuration file storing database credentials. Accessing it via a HTTP request is a clear attack attempt.

Suspicious but require further investigation:

  • /vendor/phpunit: PHPUnit is a legitimate testing framework used by developers. However, if you are not actively running tests or expecting PHPUnit usage, unknown access to this folder could be suspicious.
  • /vendor/bin/test.php: Similar to the above, this could be a legitimate testing script but requires verification of its purpose.
  • /wp-content/uploads/2022/themes.php”: Themes are usually stored in the /wp-content/themes folder. Having a themes.php script in the uploads folder is suspicious, especially with a year in the path.
  • /wp-content/uploads/2020/09/themes.php: Similar to the above, the presence of a themes.php script in the uploads folder with a date path is suspicious.

After searching online further, I found a long list of paths that shows common paths that are attacked:

https://www.luszcz.de/widwsisw/i/i0004en.php

WordPress paths and .env paths come up a lot!

Also, the reasoning for searching for phpunit, might be answered by the following article: https://thephp.cc/articles/phpunit-a-security-risk

It seems there has been a file included in it that can be exploited.
As usual, it is best to be careful to not include development code in production and also not expose dependency areas such as vendor publicly.

The CSP(Content Security Policy) of a page is blocking a request. How do I find out the CSP of the page using JavaScript?

When dealing with external requests, CORS errors can often occur.
CORS settings have generally become standardized to use CSP (Content Security Policy) settings.
These CSP settings can be set in multiple places, so it can be a little confusing what the final CSP is.
I asked AI (Bard), and got a useful (Bard has sometimes responded with incorrect responses) response.


The CSP(Content Security Policy) of a page is blocking a request. How do I find out the CSP of the page using JavaScript?


There are two ways to find out the CSP of a page using JavaScript:

  1. Check the HTTP response headers. This is the most reliable way to find the CSP, as it is the source of truth. To do this, you can use the document.documentURI property to get the URL of the page, and then use the XMLHttpRequest object to make a request to the URL. Once you have the response, you can check the Content-Security-Policy header to get the CSP.
  2. Check the <meta> tags. CSPs can also be specified using <meta> tags in the HTML head section. To check for a CSP in a <meta> tag, you can use the document.querySelector() method to find the <meta> tag with the http-equiv attribute set to Content-Security-Policy. If the <meta> tag is found, you can get the CSP from the content attribute.

Here is an example of how to find the CSP of a page using JavaScript:

JavaScript
function getCSP() {
  // Check the HTTP response headers.
  const xhr = new XMLHttpRequest();
  xhr.open('GET', document.documentURI);
  xhr.send();
  xhr.onload = function() {
    if (xhr.status === 200) {
      const csp = xhr.getResponseHeader('Content-Security-Policy');
      if (csp) {
        return csp;
      }
    }
  };

  // Check the <meta> tags.
  const metaTag = document.querySelector('meta[http-equiv="Content-Security-Policy"]');
  if (metaTag) {
    return metaTag.content;
  }

  // If no CSP is found, return null.
  return null;
}

// Get the CSP of the page.
const csp = getCSP();

// Do something with the CSP, such as logging it to the console.
console.log(csp);
Use code with caution.

If the CSP of the page is blocking a request, you can try the following:

  • Whitelisting the request in the CSP. This is the most secure option, as it allows you to explicitly specify which requests are allowed. To do this, you need to add the source of the request to the CSP. For example, if the CSP is blocking a request to https://example.com/script.js, you would need to add the following to the CSP:
script-src https://example.com/
  • Using a report-only CSP. This option allows you to test changes to your CSP without blocking any requests. To do this, you need to add the report-only directive to the CSP header. For example:
Content-Security-Policy-Report-Only: script-src https://example.com/

This will cause the browser to report any violations of the CSP to the specified URI, but the requests will not be blocked.

  • Disabling the CSP. This is the least secure option, as it disables all CSP protections. To do this, you need to remove the Content-Security-Policy header from the HTTP response.

Important: Be very careful when disabling or changing a CSP, as this can make your website vulnerable to attack.


If a page has CSP both in the response headers and in one or more meta tags, how are they merged?


If a page has CSP both in the response headers and in one or more meta tags, the CSP in the response headers is used. The meta tags are ignored.

This is because the CSP in the response headers is the most authoritative source of the CSP for the page. The meta tags are only used if there is no CSP in the response headers.

This behavior is specified in the CSP specification:

If multiple policies are received for the same resource, the HTTP response header value takes precedence over the HTML meta element value.

If you need to specify a CSP for a page, it is best to do so in the response headers. This will ensure that the CSP is applied consistently, regardless of whether the page is loaded from the server or from a cache.

If you are using a meta tag to specify a CSP, be aware that it will be ignored if there is a CSP in the response headers. You should also be aware that meta tags are not supported in all browsers.


What about if multiple CSP meta tags exist?


If a page has multiple CSP meta tags, they are merged into a single CSP. The order in which the meta tags are merged is not specified in the CSP specification, so it is best to avoid using multiple meta tags to specify a CSP.

If you need to specify a CSP for a page, it is best to do so in the response headers. This will ensure that the CSP is applied consistently, regardless of whether the page is loaded from the server or from a cache.

If you are using meta tags to specify a CSP, be aware that they may be merged in an unexpected order. You should also be aware that meta tags are not supported in all browsers.

Here is an example of how multiple CSP meta tags may be merged:

HTML
<head>
  <meta http-equiv="Content-Security-Policy" content="script-src 'self'">
  <meta http-equiv="Content-Security-Policy" content="style-src 'self'">
</head>
Use code with caution.

This would be merged into the following CSP:

script-src 'self'; style-src 'self'

The order of the directives in the merged CSP is not guaranteed. It is possible that the style-src directive could come before the script-src directive.

It is best to avoid using multiple CSP meta tags to specify a CSP. If you need to specify a CSP for a page, it is best to do so in the response headers.


From these responses it can be concluded that:

  • CSP headers ('Content-Security-Policy') are prioritized and should be used where possible.
  • Multiple meta tags with CSP are possible. However, this is not recommended.
  • When both CSP headers and meta tags are used, the CSP headers only are applied.
  • When multiple meta tags are used, depending on the browser implementation, they may be merged.