# Security false positives

> Security vulnerabilities incorrectly reported by automated static analysis tools.



## Introduction

We occasionally receive false reports of security
vulnerabilities in Dart and Flutter applications,
generated by tools that were built for other kinds
of applications (for example, those written with Java or C++).
This document provides information on reports that we believe
are incorrect and explains why the concerns are misplaced.

## Common concerns

### Shared objects should use fortified functions

> The shared object does not have any fortified functions.
> Fortified functions provides buffer overflow checks against glibc's commons insecure functions like `strcpy`, `gets` etc.
> Use the compiler option `-D_FORTIFY_SOURCE=2` to fortify functions.

When this refers to compiled Dart code
(such as the `libapp.so` file in Flutter applications),
this advice is misguided because Dart code doesn't
directly invoke libc functions;
all Dart code goes through the Dart standard library.

(In general, MobSF gets false positives here because
it checks for any use of functions with a `_chk` suffix,
but since Dart doesn't use these functions at all,
it doesn't have calls with or without the suffix,
and therefore MobSF treats the code as containing
non-fortified calls.)

### Shared objects should use RELRO

> no RELRO found for `libapp.so` binaries

Dart doesn't use the normal Procedure Linkage Table
(PLT) or Global Offsets Table (GOT) mechanisms at all,
so the Relocation Read-Only (RELRO) technique doesn't
really make much sense for Dart.

Dart's equivalent of GOT is the pool pointer,
which unlike GOT, is located in a randomized location
and is therefore much harder to exploit.

In principle, you can create vulnerable code when using Dart FFI,
but normal use of Dart FFI wouldn't be prone to these issues either,
assuming it's used with C code that itself uses RELRO appropriately.

### Shared objects should use stack canary values

> no canary are found for `libapp.so` binaries

> This shared object does not have a stack canary value added to the stack.
> Stack canaries are used to detect and prevent exploits from overwriting return address.
> Use the option -fstack-protector-all to enable stack canaries.

Dart doesn't generate stack canaries because,
unlike C++, Dart doesn't have stack-allocated arrays
(the primary source of stack smashing in C/C++).

When writing pure Dart (without using `dart:ffi`),
you already have much stronger isolation guarantees
than any C++ mitigation can provide,
simply because pure Dart code is a managed language
where things like buffer overruns don't exist.

In principle, you can create vulnerable code when using Dart FFI,
but normal use of Dart FFI would not be prone to these issues either,
assuming it's used with C code that itself uses stack canary values
appropriately.

### Code should avoid using the `_sscanf`, `_strlen`, and `_fopen` APIs

> The binary may contain the following insecure API(s) `_sscanf` , `_strlen` , `_fopen`.

The tools that report these issues tend to be
overly-simplistic in their scans;
for example, finding custom functions with
these names and assuming they refer to the
standard library functions.
Many of Flutter's third-party dependencies have
functions with similar names that trip these checks.
It's possible that some occurrences are valid concerns,
but it's impossible to tell from the output of these tools
due to the sheer number of false positives.

### Code should use `calloc` (instead of `_malloc`) for memory allocations

> The binary may use `_malloc` function instead of `calloc`.

Memory allocation is a nuanced topic,
where trade-offs have to be made between performance
and resilience to vulnerabilities.
Merely using `malloc` is not automatically indicative
of a security vulnerability.
While we welcome concrete reports (see below)
for cases where using `calloc` would be preferable,
in practice it would be inappropriate to uniformly
replace all `malloc` calls with `calloc`.

### The iOS binary has a Runpath Search Path (`@rpath`) set

> The binary has Runpath Search Path (`@rpath`) set.
> In certain cases an attacker can abuse this feature to run arbitrary executable for code execution and privilege escalation.
> Remove the compiler option `-rpath` to remove `@rpath`.

When the app is being built, Runpath Search Path refers
to the paths the linker searches to find dynamic libraries
(dylibs) used by the app.
By default, iOS apps have this set to
`@executable_path/Frameworks`,
which means the linker should search for dylibs
in the `Frameworks` directory relative to the app
binary inside the app bundle.
The `Flutter.framework` engine,
like most embedded frameworks or dylibs,
is correctly copied into this directory.
When the app runs, it loads the library binary.

Flutter apps use the default iOS build setting
(`LD_RUNPATH_SEARCH_PATHS=@executable_path/Frameworks`).

Vulnerabilities involving `@rpath` don't apply
in mobile settings, as attackers don't have
access to the file system and can't arbitrarily
swap out these frameworks.
Even if an attacker somehow _could_ swap out the
framework with a malicious one,
the app would crash on launch due to codesigning violations.

### CBC with PKCS5/PKCS7 padding vulnerability

We have received vague reports that there is a
"CBC with PKCS5/PKCS7 padding vulnerability"
in some Flutter packages.

As far as we can tell, this is triggered by the HLS
implementation in ExoPlayer
(the `com.google.android.exoplayer2.source.hls.Aes128DataSource` class).
HLS is Apple's streaming format,
which defines the type of encryption that must be used for DRM;
this isn't a vulnerability,
as DRM doesn't protect the user's machine or data
but instead merely provides obfuscation
to limit the user's ability to fully use their software and hardware.

### Apps can read and write to external storage

> App can read/write to External Storage. Any App can read data written to External Storage.

> As with data from any untrusted source, you should perform input validation when handling data from external storage.
> We strongly recommend that you not store executables or class files on external storage prior to dynamic loading.
> If your app does retrieve executable files from external storage,
> the files should be signed and cryptographically verified prior to dynamic loading.

We have received reports that some vulnerability
scanning tools interpret the ability for image
picker plugins to read and write to external storage as a threat.

Reading images from local storage is the purpose of these plugins;
this is not a vulnerability.

### Apps delete data using file.delete()

> When you delete a file using file. delete, only the reference to the file is removed from the file system table.
> The file still exists on disk until other data overwrites it, leaving it vulnerable to recovery.

Some vulnerability scanning tools interpret the deletion of
temporary files after a camera plugin records data from
the device's camera as a security vulnerability.
Because the video is recorded by the user and is stored
on the user's hardware, there is no actual risk.

## Obsolete concerns

This section contains valid messages that might be seen with
older versions of Dart and Flutter, but should no longer
be seen with more recent versions.
If you see these messages with old versions of Dart or Flutter,
upgrade to the latest stable version.
If you see these with the current stable version,
please report them (see the section at the end of this document).

### The stack should have its NX bit set

> The shared object does not have NX bit set.
> NX bit offer protection against exploitation of memory corruption vulnerabilities by marking memory page as non-executable.
> Use option `--noexecstack` or `-z noexecstack` to mark stack as non executable.

(The message from MobSF is misleading; it's looking
for whether the stack is marked as non-executable,
not the shared object.)

In older versions of Dart and Flutter there was a bug
where the ELF generator didn't emit the `gnustack`
segment with the `~X` permission, but this is now fixed.

## Reporting real concerns

While automated vulnerability scanning tools report
false positives such as the examples above,
we can't rule out that there are real issues that
deserve closer attention.
Should you find an issue that you believe is a
legitimate security vulnerability, we would greatly
appreciate if you would report it:

* [Flutter security policy](/security)
* [Dart security policy](https://dart.dev/security)

