🛡: check potential vulnerabilities in other R packages
Switch branches/tags
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
R
docs
inst/rstudio
man
tests
.Rbuildignore
.gitignore
.travis.yml
DESCRIPTION
LICENSE
LICENSE.md
NAMESPACE
NEWS.md
README.Rmd
README.md
_pkgdown.yml
codecov.yml
codemeta.json
defender.Rproj

README.md

rOpenSci Unconf 18 Project : defender

Authors:

  • Ildiko Czeller
  • Karthik Ram
  • Bob Rudis
  • Kara Woo

defender

Travis build status Coverage status Lifecycle Status

The goal of defender is to do static code analysis on other R packages to check for potential security risks and best practices. It provides checks on multiple levels:

  1. static code analysis without installing the package
  2. more thorough but potentially dangerous checks with installation / in Docker container

The checks do not tell you whether something is harmful but rather they flag code that you should double-check before running / loading the package.

Installation

You can install defender from github with:

# install.packages("devtools")
devtools::install_github("ropenscilabs/defender")

Example

System calls in R scripts

You can check for system calls in any directory locally available:

defender::summarize_system_calls("../testevil")
#>                path line_number                     call
#> 1   inst/root_sys.R           1            system2("ls")
#> 2   inst/root_sys.R           4             system("ls")
#> 3      R/exported.R           7            system2("ls")
#> 4      R/internal.R           4             system("ls")
#> 5      R/internal.R           8         system("ls -la")
#> 6      R/processx.R           3      processx::run("ls")
#> 7           R/sys.R           8 sys::exec_internal("ls")
#> 8 R/system_hidden.R           2            system2("lm")
#>        function_name
#> 1            system2
#> 2             system
#> 3            system2
#> 4             system
#> 5             system
#> 6      processx::run
#> 7 sys::exec_internal
#> 8            system2

You can also include additional elements to flag as dangerous:

sc <- defender::system_calls("poll")
defender::summarize_system_calls("../testevil", calls_to_flag = sc)
#>                path line_number                     call
#> 1   inst/root_sys.R           1            system2("ls")
#> 2   inst/root_sys.R           4             system("ls")
#> 3      R/exported.R           7            system2("ls")
#> 4      R/internal.R           4             system("ls")
#> 5      R/internal.R           8         system("ls -la")
#> 6      R/processx.R           9               poll("ls")
#> 7      R/processx.R           3      processx::run("ls")
#> 8           R/sys.R           8 sys::exec_internal("ls")
#> 9 R/system_hidden.R           2            system2("lm")
#>        function_name
#> 1            system2
#> 2             system
#> 3            system2
#> 4             system
#> 5             system
#> 6               poll
#> 7      processx::run
#> 8 sys::exec_internal
#> 9            system2

System-related imports in NAMESPACE

You can check the NAMESPACE file in a package for dangerous imports:

defender::check_namespace("../testevil")
#>       type        import  package
#> 1  package           sys      sys
#> 2  package      processx processx
#> 3 function processx::run processx

You can also include additional elements to flag as dangerous:

di <- defender::dangerous_imports("processx::poll")
defender::check_namespace("../testevil", imports_to_flag = di)
#>       type         import  package
#> 1  package            sys      sys
#> 2  package       processx processx
#> 3 function processx::poll processx
#> 4 function  processx::run processx

Collaborators

  • Ildi Czeller @czeildi
  • Karthik Ram @karthik
  • Bob Rudis @hrbrmstr
  • Kara Woo @karawoo