fingerprintjs/fingerprintjs-pro-react

Failed to load the JS script of the agent

androane opened this issue · 15 comments

Hello. We're constantly getting this error

Error: Failed to load the JS script of the agent

On Microsoft Edge.

We're on versions

"@fingerprintjs/fingerprintjs-pro": "3.7.1",
"@fingerprintjs/fingerprintjs-pro-react": "1.3.1",

Can you reproduce it? If yes, please check the browser console for related error messages.

I am also getting this error often but not always. I cannot reproduce it myself but it does not seem browser specific as I see this error occurring for many of my site's visitors across various browsers. I would estimate this error occurs 5% of the time in my case.

After further research my plan is to set up a custom subdomain as browser ad blockers could be the cause. https://dev.fingerprint.com/docs/subdomain-integration

"@fingerprintjs/fingerprintjs-pro-react": "^2.3.3"

@joeschneider32 Ad blockers are most likely to be the reason in your case. Custom subdomain can't protect from «Failed to load the JS script of the agent» yet, so please consider proxying integrations.

Thanks @Finesse . I appreciate the help!

Does anyone know of an ad blocker that will create this error?

ilfa commented

@christo8989 sure!
"uBlock Origin" for Chrome with default settings.

@Finesse @ilfa I have the same issue in Android Build.
Note* No VPN no Ad Block.

I'm using "@fingerprintjs/fingerprintjs-pro-spa": "^1.0.2",

ilfa commented

We continued discussion with RizwanAliGujjar in fingerprintjs/fingerprintjs-pro-spa#46

I can confirm that the issue arises consistently on current Chrome version with Adblock Plus and "@fingerprintjs/fingerprintjs-pro": "3.8.1". After disabling Adblock Plus everything works fine.

On our production with "@fingerprintjs/fingerprintjs-pro": "3.5.5" we don't have any issues. I assume that the changes here are causing the issue? https://dev.fingerprint.com/changelog/3-6-0

Yes, it seems possible to me that Adblock Plus wasn't blocking the old CDN URL but is blocking the new one. As mentioned before, a proxy integration is the best way to protect the JavaScript agent not only from Adblock Plus now, but all ad-blockers in the future. You can have a look at our Protecting the JS Agent guide for a detailed explanation.

Hi, we implemented now a proxy solution using our web-server (Nginx) which was in our case much easier to set up than the cloud solutions suggested in the documentation.

Nginx proxy config (Similar solution can be done with Apache):

location ^~ /fpjs-cdn/ {
    proxy_ssl_server_name on;
    proxy_set_header X-Forwarded-Proto https;
    proxy_pass https://fpnpmcdn.net/;
}

Agent initialization:

FingerprintJS.load({
    ...
    endpoint: 'https://fp.our-website.com', // Custom subdomain setup (See https://dev.fingerprint.com/docs/custom-subdomain-setup)
    scriptUrlPattern: '/fpjs-cdn/v<version>/<apiKey>/loader_v<loaderVersion>.js' // This uses our Nginx proxy
}
makma commented

Hello @MiladSadinam ,
My name is Martin, I'm responsible for the proxy integrations at Fingerprint. Thank you for bringing this interesting topic.

In fact, the proxying of the identification, agent, and other types of requests that are performed by the Fingerprint Pro client-side libraries is much more complex than just "repeating" the requests. The proxy service needs to handle different aspects based on the internal data contract (I'll explain why the internal below) such as different cookie scopes, different data centers, how IP addresses in headers are serialized (and possibly spoofed by the malicious parties), up to date public suffix list, stripping /appending cookies/headers, caching, internal payload changes... As you can see many things can affect the accuracy of results significantly. Moreover, since browsers are evolving really fast, we must do the same as well.

Sadly, this implies that we must, more or less, regularly adjust or even abandon certain behaviors and introduce new ones in the proxy logic to ensure Fingerprint Pro is working and provides all the available features. Therefore we can't guarantee that any one-time setup will work in a month or in a year (the main motivation is that we need to react quickly to the browser ecosystem changes and a strict, well-defined data contract would be too limiting for us) that's the reason why we really can't provide any well-defined data contract because we'd probably need to break it in a couple of weeks.

Instead of that, we decided to create out-of-the-box proxy integrations that will follow all of these internal best practices and data contract details. Moreover, all of our integrations can update themselves so even if we introduce an internal breaking change, the proxy logic is updated and our customers can benefit from the best accuracy and additional features and most importantly, without explicit actions from their side.

Could you please share with me any feedback regarding the existing proxy integration offering and why it doesn't work for you? What aspects of which integrations are complicated? I'll be also more than happy to discuss your feedback directly and perhaps address it in one of our next releases - please contact me at martin.makarsky@fingerprint.com.
I appreciate any constructive feedback.

Thank you.
Cheers!
martin

makma commented

Hello @MiladSadinam,
I reviewed your code snippet (and your email) one more time and I realized my original message might have been misleading. All the mentioned adjustments needed on the proxy's side are true and affect the accuracy significantly (but apply to identification requests only). Nevertheless, I didn't realize that you do use the subdomain setup for the identification request and this custom Nginx rule for agent download requests only.

Therefore your implementation is not bad, per se. However, I can see some problems with this approach.

  • I'm not familiar with your infra nevertheless, if this Nginx config affects just one machine and is not distributed on the CDN, the delivery time of the script would be slower.
  • You do use the fpjs-cdn path for the downloading script. There's a high chance adblockers already detect such paths, I'd recommend using some random string instead.
  • The hardcoded https://fpnpmcdn.net/ endpoint is not part of the public data contract. It might be changed in the future without further notice.
  • Our out-of-the-box proxy integrations provide better accuracy than the subdomain setup for some browsers because of the specific behavior of the browsers when it comes to the subdomains and different subnets.

Hi Martin,

Regarding your comments:

  • I think you are correct with reduced performance, but I believe it is acceptable in our case.
  • I will gladly change the name fpjs-cdn
  • Concerning that, https://fpnpmcdn.net/ might change in the future, I see that in your documentations (https://dev.fingerprint.com/docs/js-agent) you are everywhere mentioning https://fpjscdn.net. Should I replace https://fpnpmcdn.net/ by https://fpjscdn.net? Both seem to me to deliver the agent script file. Alternatively, I could also add FingerprintJS.defaultScriptUrlPattern as a second option for scriptUrlPattern to further mitigate the problem.

Our usage of FingerprintJs is not very critical for our system. I think I will observe for now the effectiveness of the current setup and come back to the other proxy setups in case I observe problematic behavior.

Thank you again for your feedback and instructions.

makma commented

Hey @MiladSadinam,
I checked the implementation details with the team and both aliases fpnpmcdn.net and fpjscdn.net are the same. We may add new aliases, but the existing won’t be removed as long as somebody's using them.