Проблемы XSS при использовании OpenCPU и knitr для печати предоставленных пользователем данных

Я использую openCPU и knitr для создания пользовательских отзывов после опросов. С этой целью я в основном позволил разработчикам опросов указывать файлы rmd. В этом случае разработчикам опроса можно доверять, а участникам опроса - нет.

Я сейчас думаю о XSS. Это не большое беспокойство, поскольку отзывы пользователей, как правило, будут отображаться только пользователю, который ввел данные на дисплей, но, конечно, такие символы, как "<", будут использоваться по незлонамеренным причинам, и я хотел бы подумать об этом заранее и исследуйте некоторые испытания и трудности свободного смешивания R с веб-приложениями.

Knitr и R вообще не были сделаны с ненадежными пользователями и XSS в моем уме. OpenCPU устраняет многие проблемы с безопасностью, используя AppArmored-R в качестве API, но мне интересно, можно ли доказать такой подход с максимальной гибкостью, как мой.

Возможные точки, в которых можно разделить доверенную и ненадежную разметку:

  1. Перед вязанием, т.е. я передаю сбежавшие пользовательские данные в rmd-файл. Недостаток: забывший разработчик опроса может удалить его случайно или из-за того, что он раздражает в некотором контексте.
  2. Во время вязания. Я думаю, это было бы идеально, но я не знаю, возможно ли это, особенно если разработчик опроса потенциально может изменить настройки чанка.
  3. После вязания. Я думаю, что невозможно разграничить доверенную и ненадежную разметку пост-hoc.

Некоторый код для вставки в приложение knitr OpenCPU:

```{r}
good_userdata = 'I like brackets [].'
bad_userdata = 'some text should not be 
[linked](javascript:location.href=\'http://example.com?secrets\';), <s>struck</s> or __bold__'

escape_html = highr:::escape_html
escape_md <- function(x){
  x <- gsub('\\[', '\\\\[', x);
  x <- gsub('_', '\\\\_', x);
  x
} 
good_userdata_escaped = escape_md(escape_html(good_userdata))
bad_userdata_escaped = escape_md(escape_html(bad_userdata))
```

## let's say survey devs wants to print text like this
```{r}
cat(good_userdata_escaped)
cat(bad_userdata_escaped) # doesn't know about text like this
```

## gets annoyed, does
```{r}
good_userdata_escaped <- gsub('\\\\', '', good_userdata_escaped);
bad_userdata_escaped <- gsub('\\\\', '', bad_userdata_escaped);
```

##
so that this looks nice
```{r}
cat(good_userdata_escaped)
```

## later renders the same text inline, so that is evaluated as markdown

`r good_userdata_escaped # doesn't look dangerous`

`r bad_userdata_escaped`

Редактировать 2

Извините, я предоставил только некоторые теги HTML, думая, что возможные атаки XSS очевидны. Мишель Фортин имел несколько примеров на своей странице.

1 ответ

Я не уверен на 100%, что понимаю вашу озабоченность. Если вы беспокоитесь о XSS, вы беспокоитесь о пользователях, включающих тег javascript или около того в уценке, верно?

```{r}
userdata = '<script>alert("I am evil")</script>'
```

```{r,results='asis'}
cat(userdata)
```

Вы можете предотвратить это, экранируя символы HTML. Я думаю, что есть раздел об этом в определении уценки. Таким образом, вам нужно было бы избежать любого пользовательского ввода, либо при вставке его в вашу БД, либо при его извлечении:

escape <- function(x){
  x <- gsub("<", "&lt;", x);
  x <- gsub(">", "&gt;", x);
  x <- gsub("&", "&amp;", x);
  x
} 

Попробуйте запустить следующее:

```{r output}
escape <- function(x){
  x <- gsub("&", "&amp;", x);
  x <- gsub("<", "&lt;", x);
  x <- gsub(">", "&gt;", x);
  x
} 
```

```{r}
userdata = escape('<script>alert("I am evil")</script>')
```

```{r,results='asis'}
cat(userdata)
```

Это должно заботиться о любом внедрении кода. Я не совсем уверен, как __bold__ Пример вызывает озабоченность, поскольку на самом деле это не может быть использовано для атаки XSS, так как нет сценариев. Но если вы хотите, чтобы пользователи тоже не связывались с макетом, вам следует избегать всех символов уценки, я полагаю.

Другие вопросы по тегам