Dealing with False Positives of Golang Apps on Windows

Golang is a great language to build cross platform apps but if you look at the Windows executable, you may notice it has a higher chance of triggering antivirus tools with a false positive compared to Linux or Mac.

Hello World Baseline

So let’s take the most basic of apps. Hello World just opens a new process on the machine, makes a syscall to write out some text to the terminal, and exits. This is a great baseline as we can be very certain there is nothing malicious in the code, no rogue 3rd party repositories, or forgotten calls that can look questionable to the security tool. Let’s see how we score:

package main

import "fmt"

func main() {
	fmt.Print("Hello World")
Go VersionSizeFlagsVirusTotal
1.21rc21,241KBstripped3 / 71
14 / 71
10 / 71
1.19.101,301KBstripped11 / 71
1.18.51,267KBstripped10 / 71
8 / 71
5 / 71
Scores were ran on July 2023

Interestingly we don’t expect any files or web calls with our app, but as you can see in the VirusTotal sandboxes, this is not quite true. Though its not coming from our app. Microsoft Windows is doing some housekeeping and lookup of our app with WER (Windows Error Reporting) and SPP (Microsoft Software Protection Platform). While the filenames and calls look pretty random, this is just how Microsoft choose to do this and we can’t change it.

If you ever see these entries like these in VirusTotal Behavior tab in sandbox, its just every app that is opened on Windows. I really wish they would name them better.

C:\Windows\System32\spp\store\2.0\cache\cache.dat (TCP) digicert.com (TCP) microsoft.com (TCP) microsoft.com (TCP) akamai.net

Possible Solution

As seen in social media, the answer comes down to ratioing.

You need enough “good” code to overcome the bootstraping code that will get marked suspicious. Later versions of Go have more new boilerplate code that will get marked suspicious. Small executable files like Hello World are going to have the hardest time with this.

Now adding addition code to just fill up space isn’t a great answer but sadly in this example, it works.

For example, I changed the hello world app to use zerolog which has a number of 3rd party dependencies and disabled stripping the package to reduce its size (a common thing for prod apps).

package main

import (

func main() {
	zerolog.TimeFieldFormat = zerolog.TimeFormatUnix
	log.Print("Hello World")
Go VersionSizeFlagsVirusTotal
1.21rc22,429KB4 / 71
1.20.52,423KB4 / 70
1.19.102,424KB3 / 71
1.18.52,310KB5 / 71
1.15.152,631KB1 / 71
Scores were ran on July 2023

Now this didn’t get us to 100% passing, but it did drop our false positive detection rate by half for most go versions. Interesting go 1.21 stayed close to its low number of 3 to 4, so once that releases from RC, it may be interesting to see if it can improve normal app false positive ratings.


I think projects should be using VirusTotal API in their CI process to keep an eye on there score but I don’t think you need to drastically change your app to get it to 100% passing. A lot of these vendors are not heavily used and they also have a responsibility to not mark a simple Hello World as malicious if they want to be trusted. No scanner will be 100% accurate, they are going to miss some in both directions, but hopefully are aiming to get more false positives than negatives.

If you have CI graphing this, it will make it easier for you to identify when you have added some code that is causing an increase false positive rate. Be careful when changing your Go version or reducing code size with package stripping or removing libraries. Sadly both of those things should be considered good things to do for your project but need to be balanced and done with your false positive ratio on Windows in mind.

openanalytics 231990 views

I'm a 35 year old UIUC Computer Engineer building mobile apps, websites and hardware integrations with an interest in 3D printing, biotechnology and Arduinos.

View Comments
There are currently no comments.

This site uses Akismet to reduce spam. Learn how your comment data is processed.