Important: ua-parser-js exploit and Kotlin/JS

On the 22nd of October at 5:06 pm CEST a message was posted on the #javascript channel of the Kotlin Slack about a potential security issue, at which time we began our investigations. On the 23rd of October, it was reported that malware was found in a very popular npm package named ua-parser-js. The package had been compromised, and a password stealer and cryptocurrency miner installed on target machines. 

Kotlin Multiplatform (targeting JS) and Kotlin/JS use a very popular testing framework named Karma. This in turn has a dependency on the affected package (ua-parser-js). In addition, many developers that target JavaScript, actually use Karma (just like we do on the Kotlin team) as their testing framework. 

As such, we feel it is important for you to be aware of the situation and what you can do to check to see if you’re affected and how to resolve the issue. 

How do I know if I’m affected?

If you’re using directly or indirectly ua-parser-js versions 0.7.29, 0.8.0, and 1.0.0, you can consider your system compromised. This is independently of whether or not you are running tests. Once the dependency is installed, init scripts are automatically launched (unless you executed npm with the --ignore-scripts option or globally had set ignore-scripts true). 

How do I know if I have this package on my system?

There are multiple ways to know if a specific package is installed (either locally or globally) on your system, including:

  • Using npm list command and filtering the output for ua-parser-js 
  • Using npm-check package to check dependencies

A more fail-safe way is to check for the specific `ua-parser-js` on your system, by running the following command

On macOS/Linux 

grep -r --include=package.json '"_id": "ua-parser-js' {x}

On Windows (using Powershell)

Get-ChildItem -Path '{x}' -Recurse -include "package.json" -ErrorAction SilentlyContinue | Select-String -pattern '"_id": "ua-parser-js'

Where {x} is the root folder you want to start the search on. This will output all directories containing the package.json file which uses the package. You can of course search for the specific affected versions instead of all versions if you want. 

It is important to check not only your development environment, but also your build environment or anywhere else you think this package may have been installed (directly or indirectly). 

Also check for any of the following entries during installation of your npm packages (which could be for instance when using karma):

ua-parser-js@0.7.29: this package has been hijacked
ua-parser-js@0.8.0: this package has been hijacked
ua-parser-js@1.0.0: this package has been hijacked

How do I resolve the issue?

Update to a version that is not affected by the issue. The following updates have been released: 0.7.30, 0.8.1 and 1.0.1. Make sure you remove any packages that are affected and rotate any potential credentials that may have been compromised. 

Is it sufficient to remove/update the package?

Given that the package has been compromised to not only perform cryptomining, but also steal credentials, it would be recommended to change any potential credentials that may have been compromised. 

It is also recommended to see if you have any binaries named jsextension or jsextention.exe running, as listed in the comments from the original issue running on your system.

Am I infected even if I haven’t run anything that uses this package?

It is safe to assume that if the package is installed, the system is compromised, something GitHub Advisory also points out.

Was there any time frame for this attack?

It seems that the timeframe in which the attack could have taken place (i.e. from the time the compromised package was updated to the time it was detected) was Oct 22, 2021 at 14:15 CEST to Oct 22, 2021 18:23 CEST. In other words, if none of your packages have updated their dependencies in this short period of time, then most likely you do not have the affected version and consequently most likely not impacted. 

Is Kotlin affected?

As mentioned above, Kotlin Multiplatform (targeting JS) and Kotlin/JS version 1.5.0 and later use a transitive dependency to the affected package. If you ran karma tests for the first time between the hours of Oct 22, 2021 at 14:15 CEST to Oct 22, 2021 18:23 CEST, then you’re most likely affected. 

How can I prevent this from happening in the future?

One recommendation is to use lock files for your dependencies (package-lock.json, yarn.lock, etc) which lock versions of dependencies used, giving you control over any updates, and monitor vulnerabilities of packages you use to be able to timely update them once one of them was compromised. When not using lock files, you may for instance start your application with one version but then during any phase, be it development, build, or deployment, your package manager may update dependencies without you realizing.

For instructions on how to use Yarn.lock with Kotlin/JS projects, read our follow-up blog post.

Finally, please note that the story around this vulnerability is still somewhat developing. We’ll post any updates as needed.