This book is aimed at three (often overlapping) types of people involved with R – users, developers, and administrators.
205 |
The R community is pretty awesome but as a lot of us aren’t trained developers, we can inadvertently do things that are security boo-boos or open us to bad people taking advantage of our systems.
206 |
As a result, we give guidance to R people to help you avoid common issues.
Welcome to our book on security best practices for R people!
200 |
In our Users section, we outline what you need to think about when you’re writing scripts and using R day to day.
201 |
In our Developers section, we outline best practices to developing R packages securely that helps you avoid doing things that allow bad things to happen because of your package.
202 |
In our Administrators section, we outline some best practices for maintaining R to minimise potential security issues.
203 |
The aim of the book is not too make R people security experts, but to give R people some pragmatic, easy-to-follow principles that result in more secure behaviour. We demonstrate the principles with some examples of how to do things and how not to do things. Then, if you’re interested in the details behind why you should do these things we provide explanations.
This work is aimed at three (often overlapping) types of people involved with R – users, developers, and administrators.
93 |
94 |
95 |
1.2 Motivation
96 |
The R community is pretty awesome but as a lot of us aren’t trained developers, we can inadvertently do things that are security boo-boos or open us to bad people taking advantage of our systems. I’m sure we’d like to avoid that!
In R you can work with the file system. R can do anything you can do with files across your network so you need to be careful.
202 |
203 |
3.1.0.1 Principles
204 |
205 |
Interact with files through pre-defined interfaces geared towards the type of file you want to access
206 |
Use relative references
207 |
208 |
209 |
210 |
3.1.0.2 Good examples
211 |
212 |
213 |
3.1.0.3 Bad examples
214 |
215 |
216 |
3.1.0.4 Background
217 |
218 |
219 |
3.1.1 File locations
220 |
221 |
Working directory
222 |
Network files
223 |
224 |
225 |
3.1.1.1 Principles
226 |
227 |
228 |
3.1.1.2 Good examples
229 |
230 |
231 |
3.1.1.3 Bad examples
232 |
233 |
234 |
3.1.1.4 Background
235 |
236 |
237 |
238 |
3.1.2 File permissions
239 |
240 |
Execute permissions
241 |
Groups
242 |
243 |
244 |
245 |
3.1.3 Cleanup
246 |
247 |
The use of on.exit
248 |
The use of unlink
249 |
250 |
251 |
3.1.3.1 Principles
252 |
253 |
254 |
3.1.3.2 Good examples
255 |
256 |
257 |
3.1.3.3 Bad examples
258 |
259 |
260 |
3.1.3.4 Background
261 |
262 |
263 |
264 |
265 |
3.2 Unsafe sourcing
266 |
Don’t source files from internet without checking them!
267 |
You should understand somethting entirely before you execute it and you should verify that a file is the same file you were expecting.
268 |
Using the package notary, you can do this easily:
269 |
library(notary)
270 |
271 |
3.2.0.1 Principles
272 |
273 |
274 |
3.2.0.2 Good examples
275 |
276 |
277 |
3.2.0.3 Bad examples
278 |
279 |
280 |
3.2.0.4 Background
281 |
282 |
283 |
284 |
3.3 Dynamic string creation & SQL injection
285 |
286 |
3.3.0.1 Principles
287 |
288 |
Always cleanse parameters that are input by a user
289 |
290 |
291 |
292 |
3.3.0.2 Good examples
293 |
294 |
3.3.0.2.1 Using DBI
295 |
Here we accept a user’s input to some code that constructs a request to the database in a safe way.
296 |
This uses DBI but you can also use RODBCext if you use RODBC for interfacing with your database package.
297 |
doDBcall <-function(input){
298 | basesql <- "SELECT * FROM iris WHERE species = ?species"
299 | sqltoexecute<-DBI::sqlInterpolate(DBI::ANSI(), basesql, species = input)
300 | # send SQL to the DB with DBI::dbExecute()
301 | return(sqltoexecute)
302 | }
303 |
304 | doDBcall("setosa")
305 |
## <SQL> SELECT * FROM iris WHERE species = 'setosa'
306 |
doDBcall("virginica';DROP TABLE iris;")
307 |
## <SQL> SELECT * FROM iris WHERE species = 'virginica'';DROP TABLE iris;'
308 |
309 |
310 |
3.3.0.2.2 Using shiny
311 |
A common thing you might do is make it easy for someone to analyse some data dynamically, by allowing them to change columns. We use the column names to constrain choices instead of letting people type answers in - this is also a better user experience too!
doDBcall <-function(input){
330 | basesql <- "SELECT * FROM iris WHERE species = '"
331 | sqltoexecute<-paste0(basesql,input,"'")
332 | # send SQL to the DB with DBI::dbExecute()
333 | return(sqltoexecute)
334 | }
335 |
336 | doDBcall("setosa")
337 |
## [1] "SELECT * FROM iris WHERE species = 'setosa'"
338 |
doDBcall("virginica';DROP TABLE iris;")
339 |
## [1] "SELECT * FROM iris WHERE species = 'virginica';DROP TABLE iris;'"
340 |
341 |
342 |
3.3.0.3.2 Using shiny
343 |
344 |
345 |
346 |
3.3.0.4 Background
347 |
SQL Injection aka SQLi is one of the most common security issues in web development, and yet is one of the easiest to avoid.
348 |
SQLi occurs where a user can input text in an unconstrained manner and what they input isn’t sanitised to prevent them ending the statement you were expecting to execute early and adding their own followup statement.
349 |
350 |
351 |
XKCD Exploits of a Mom
352 |
353 |
354 |
355 |
356 |
3.4 Password handling
357 |
358 |
Never store passwords in files that go into source control!
359 |
360 |
361 |
362 |
363 |
3.5 System calls
364 |
You can execute any command-line code from R. This gives you a lot of access to functionality that can be dangerous!
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
246 |
247 |
248 |
249 |
250 |
--------------------------------------------------------------------------------
/docs/search_index.json:
--------------------------------------------------------------------------------
1 | [
2 | ["r-security-practices.html", "1 R security practices 1.1 Who this is for 1.2 Motivation", " 1 R security practices This is a repository of guidance materials to help people improve the security of R usage. The core guidance is available in the book. 1.1 Who this is for This work is aimed at three (often overlapping) types of people involved with R – users, developers, and administrators. 1.2 Motivation The R community is pretty awesome but as a lot of us aren’t trained developers, we can inadvertently do things that are security boo-boos or open us to bad people taking advantage of our systems. I’m sure we’d like to avoid that! "]
3 | ]
4 |
--------------------------------------------------------------------------------
/handouts/01-intro.Rmd:
--------------------------------------------------------------------------------
1 | # Introduction {#intro}
2 |
3 | Welcome to our book on security best practices for R people!
4 |
5 | In our **Users** section, we outline what you need to think about when you're writing scripts and using R day to day.
6 |
7 | In our **Developers** section, we outline best practices to developing R packages securely that helps you avoid doing things that allow bad things to happen because of your package.
8 |
9 | In our **Administrators** section, we outline some best practices for maintaining R to minimise potential security issues.
10 |
11 | The aim of the book is not to make R people security experts, but to give R people some pragmatic, easy-to-follow principles that result in more secure behaviour. We demonstrate the principles with some examples of how to do things and how not to do things. Then, if you're interested in the details behind why you should do these things we provide explanations.
12 |
--------------------------------------------------------------------------------
/handouts/02-users.Rmd:
--------------------------------------------------------------------------------
1 | # R Users
2 |
3 | ## Working with the file system
4 | In R you can work with the file system. R can do anything you can do with files across your network so you need to be careful.
5 |
6 | #### Principles
7 | - Interact with files through pre-defined interfaces geared towards the type of file you want to access
8 | - Use relative references
9 |
10 | #### Good examples
11 | #### Bad examples
12 | #### Background
13 |
14 | ### File locations
15 | - Working directory
16 | - Network files
17 |
18 |
19 | #### Principles
20 | #### Good examples
21 | #### Bad examples
22 | #### Background
23 |
24 | ### File permissions
25 | - Execute permissions
26 | - Groups
27 |
28 | ### Cleanup
29 | - The use of `on.exit`
30 | - The use of `unlink`
31 |
32 |
33 | #### Principles
34 | #### Good examples
35 | #### Bad examples
36 | #### Background
37 |
38 | ## Unsafe sourcing
39 | Don't source files from the internet without checking them!
40 |
41 | You should understand something entirely before you execute it and you should verify that a file is the same file you were expecting.
42 |
43 | Using the package `notary`, you can do this easily:
44 | ```{r}
45 | library(notary)
46 | ```
47 |
48 |
49 | #### Principles
50 | #### Good examples
51 | #### Bad examples
52 | #### Background
53 |
54 | ## Dynamic string creation & SQL injection
55 |
56 |
57 | #### Principles
58 | - Always cleanse parameters that are input by a user
59 |
60 | #### Good examples
61 |
62 | ##### Using DBI
63 | Here we accept a user's input to some code that constructs a request to the database in a safe way.
64 |
65 | This uses DBI but you can also use RODBCext if you use RODBC for interfacing with your database package.
66 |
67 | ```{r}
68 | doDBcall <- function(input){
69 | basesql <- "SELECT * FROM iris WHERE species = ?species"
70 | sqltoexecute<-DBI::sqlInterpolate(DBI::ANSI(), basesql, species = input)
71 | # send SQL to the DB with DBI::dbExecute()
72 | return(sqltoexecute)
73 | }
74 |
75 | doDBcall("setosa")
76 | doDBcall("virginica';DROP TABLE iris;")
77 | ```
78 |
79 | ##### Using shiny
80 | A common thing you might do is make it easy for someone to analyse some data dynamically, by allowing them to change columns. We use the column names to constrain choices instead of letting people type answers in - this is also a better user experience too!
81 |
82 | ```{r eval=FALSE}
83 | library(shiny)
84 | shinyApp(
85 | ui=fluidPage(selectInput("x","X-axis",
86 | choices=colnames(iris)[-5]),
87 | selectInput("y","Y-axis",
88 | choices=colnames(iris)[-5]),
89 | plotOutput("myplot")),
90 | server=function(input, output) {
91 | output$myplot<-renderPlot(plot(iris[,input$x],iris[,input$y]))
92 | }
93 | )
94 | ```
95 |
96 | #### Bad examples
97 | ##### Using DBI
98 | ```{r}
99 | doDBcall <- function(input){
100 | basesql <- "SELECT * FROM iris WHERE species = '"
101 | sqltoexecute<-paste0(basesql,input,"'")
102 | # send SQL to the DB with DBI::dbExecute()
103 | return(sqltoexecute)
104 | }
105 |
106 | doDBcall("setosa")
107 | doDBcall("virginica';DROP TABLE iris;")
108 | ```
109 |
110 | ##### Using shiny
111 |
112 |
113 | #### Background
114 | [SQL Injection](https://www.owasp.org/index.php/SQL_Injection) aka SQLi is one of the most common security issues in web development, and yet is one of the easiest to avoid.
115 |
116 | SQLi occurs where a user can input text in an unconstrained manner and what they input isn't sanitised to prevent them ending the statement you were expecting to execute early and adding their own followup statement.
117 |
118 | 
119 |
120 | ## Password handling
121 | - Never store passwords in files that go into source control!
122 |
123 |
124 |
125 | ## System calls
126 | You can execute any command-line code from R. This gives you a lot of access to functionality that can be dangerous!
127 |
--------------------------------------------------------------------------------
/handouts/03-developers.Rmd:
--------------------------------------------------------------------------------
1 | # Developers
2 |
3 | ## Preventing unsafe arbitrary code execution
4 |
5 | ### Principles
6 | ### Good examples
7 | ### Bad examples
8 | ### Background
9 |
10 | ## Signing your commits
11 |
12 | ### Principles
13 | ### Good examples
14 | ### Bad examples
15 | ### Background
16 |
17 | ## Storing sensitive information
18 |
19 | ### Principles
20 | ### Good examples
21 | ### Bad examples
22 | ### Background
23 |
24 | ## Downloading dependencies
25 |
26 | ### Principles
27 | ### Good examples
28 | ### Bad examples
29 | ### Background
30 |
31 | ## System dependencies
32 |
33 | ### Principles
34 | ### Good examples
35 | ### Bad examples
36 | ### Background
37 |
38 | ## File interactions
39 |
40 | ### Principles
41 | ### Good examples
42 | ### Bad examples
43 | ### Background
44 |
--------------------------------------------------------------------------------
/handouts/04-administrators.Rmd:
--------------------------------------------------------------------------------
1 | # Administrators
2 |
3 | ## Authorative mirrors
4 |
5 | ### Principles
6 | ### Good examples
7 | ### Bad examples
8 | ### Background
9 |
10 | ## Internal CRANs
11 |
12 | ### Principles
13 | ### Good examples
14 | ### Bad examples
15 | ### Background
16 |
17 | ## Validating package installs
18 |
19 | ### Principles
20 | ### Good examples
21 | ### Bad examples
22 | ### Background
23 |
24 | ## Restricting privileges
25 |
26 | ### Principles
27 | ### Good examples
28 | ### Bad examples
29 | ### Background
30 |
--------------------------------------------------------------------------------
/handouts/06-references.Rmd:
--------------------------------------------------------------------------------
1 | `r if (knitr:::is_html_output()) '# References {-}'`
2 |
--------------------------------------------------------------------------------
/handouts/index.Rmd:
--------------------------------------------------------------------------------
1 | ---
2 | title: "R security practices"
3 | author: "Steph Locke"
4 | date: "`r Sys.Date()`"
5 | knit: "bookdown::render_book"
6 | site: bookdown::bookdown_site
7 | output:
8 | bookdown::gitbook: default
9 | bookdown::pdf_book: default
10 | documentclass: book
11 | link-citations: yes
12 | github-repo: ropenscilabs/r-security-practices
13 | description: "A guide for R users about using and developing R securely"
14 | ---
15 |
16 |
17 | # Who this book is for
18 | This book is aimed at three (often overlapping) types of people involved with R -- users, developers, and administrators.
19 |
20 | The R community is pretty awesome but as a lot of us aren't trained developers, we can inadvertently do things that are security boo-boos or open us to bad people taking advantage of our systems.
21 |
22 | As a result, we give guidance to R people to help you avoid common issues.
23 |
--------------------------------------------------------------------------------
/roadmap.md:
--------------------------------------------------------------------------------
1 | # Secutity Roadmap
2 |
3 | ## Signing and validation of R packages (and other things from the internet)
4 |
5 | To be fleshed out and annotated as things become clearer. I am a novice in this area so misunderstandings here will probably be shared by other users.
6 |
7 | * `install.packages` - to get this to support signed releases we would have to have signatures with the package and that is going to require CRAN support. We could support this for non-CRAN repos though (drat repos, etc).
8 | * `install_github` - here we need to be able to verify the signature of a github package. Commits can be signed and then that shows up on the releases. To be able to verify this on installation we need to agree that the developer is someone in our web of trust.
9 | * `source` (and other functions like `readLines`) can happily consume urls. We could validate these
10 | * When building packages, libraries might be downloaded (e.g., Jeroen's collection of windows libraries). These should be signed and the signatures verified during installation (we could survey packages that use `configure` scripts to work out how many packages are potentially affected here.
11 |
12 | ## Best practices for avoiding risky behaviour
13 |
14 | * Avoiding SQL injection
15 | * Being careful with `system`
16 | * etc...
17 |
18 | ## Package threat monitoring
19 |
20 | Packages have access to the system at the level of privilege of the user running it. This means that an R package can do all sorts of nasty things that a user can do, particularly with `system`; see [rpwnd](https://github.com/hrbrmstr/rpwnd) for a non-exhaustive list and proof of concept.
21 |
22 | **Static analysis** This will probably be better for detecting risky behaviour than malicious behaviour. There will be patterns that we could detect in the style of `lintr` or `goodpractice`.
23 |
24 | **Dynamic analysis** Run a package in a sand-boxed environment and watch for things like disk and network access. In particular anything that sends information *out* is a problem, but even some reading from remote system could send all sorts of information. Does the package try to read from the file system at all?
25 |
26 | ## Motivating people
27 |
28 | People don't care about this stuff. Pair things that try to improve security with short motivational videos/gifs that show the extent of the exploit and with a video/gif that shows how a best practice/alternative tooling would prevent it. The shorter and more obvious the better.
29 |
--------------------------------------------------------------------------------
/rsecuritypractices.Rproj:
--------------------------------------------------------------------------------
1 | Version: 1.0
2 |
3 | RestoreWorkspace: No
4 | SaveWorkspace: No
5 | AlwaysSaveHistory: Default
6 |
7 | EnableCodeIndexing: Yes
8 | UseSpacesForTab: Yes
9 | NumSpacesForTab: 2
10 | Encoding: UTF-8
11 |
12 | RnwWeave: knitr
13 | LaTeX: pdfLaTeX
14 |
15 | AutoAppendNewline: Yes
16 | StripTrailingWhitespace: Yes
17 |
18 | BuildType: Package
19 | PackageUseDevtools: Yes
20 | PackageInstallArgs: --no-multiarch --with-keep.source
21 | PackageRoxygenize: rd,collate,namespace
22 |
--------------------------------------------------------------------------------