JupyterNotebook服务器的安全性

由于对jupyterNotebook服务器的访问意味着对运行任意代码的访问,因此必须限制对Notebook服务器的访问。因此,Notebook4.3引入了基于令牌的身份验证,即 默认情况下 .

注解

如果为Notebook服务器启用密码,则默认情况下不会启用令牌身份验证,并且Notebook服务器的行为与4.3之前的版本保持不变。

启用令牌身份验证后,Notebook使用令牌对请求进行身份验证。此令牌可以通过三种方式登录到Notebook服务器:

  • Authorization 标头,例如:

    Authorization: token abcdef...
    
  • 在URL参数中,例如:

    https://my-notebook/tree/?token=abcdef...
    
  • 在登录表单的密码字段中,如果您没有登录,将显示给您。

在启用令牌身份验证(默认)的情况下启动Notebook服务器时,将生成用于身份验证的令牌。此令牌已记录到终端,以便您可以将URL复制/粘贴到浏览器中::

[I 11:59:16.597 NotebookApp] The Jupyter Notebook is running at:
http://localhost:8888/?token=c8de56fa4deed24899803e93c227592aef6538f93025fe01

如果Notebook服务器将自动打开浏览器(默认,除非 --no-browser 已经通过),一个 额外的 生成用于启动浏览器的令牌。此附加令牌只能使用一次,并用于在浏览器连接后为其设置cookie。当浏览器使用此一次性令牌发出第一个请求后,该令牌将被丢弃,并在浏览器中设置cookie。

在以后的任何时候,您都可以使用 jupyter notebook list ::

$ jupyter notebook list
Currently running servers:
http://localhost:8888/?token=abc... :: /home/you/notebooks
https://0.0.0.0:9999/?token=123... :: /tmp/public
http://localhost:8889/ :: /tmp/has-password

对于启用令牌身份验证的服务器,上面列表中的URL将包含令牌,因此您可以将该URL复制并粘贴到浏览器中以登录。如果服务器没有令牌(例如它有密码或禁用了身份验证),则URL将不包含令牌参数。访问此URL后,浏览器中将设置一个cookie,除非您切换浏览器、清除cookie或在新端口上启动Notebook服务器,否则无需再次使用该令牌。

令牌认证的替代方案

如果生成的令牌不适合您,您可以为Notebook设置密码。 jupyter notebook password 将提示您输入密码,并将哈希密码存储在 jupyter_notebook_config.json .

5.0 新版功能: jupyter notebook password 命令已添加。

通过将令牌和密码设置为空字符串,可以完全禁用身份验证,但这是 不推荐 ,除非在Web应用程序的其他层处理身份验证或访问限制:

c.NotebookApp.token = ''
c.NotebookApp.password = ''

Notebook文档的安全性

随着JupyterNotebook在共享和协作方面越来越受欢迎,恶意用户试图利用Notebook进行恶意攻击的可能性也在增加。IPython2.0引入了一个安全模型,以防止在没有显式用户输入的情况下执行不受信任的代码。

问题

Jupyter的关键是任意代码执行。我们不想限制Notebook的使用范围,这会对Notebook的实用性产生负面影响。

与其他程序不同,JupyterNotebook文件包含输出。与其他文档不同,该输出存在于可以执行代码的上下文中(通过javascript)。

我们需要解决的安全问题是,不应该仅仅因为用户 开的 一个Notebook 他们没有写 . 和其他程序一样,一旦用户决定在Notebook中执行代码,它就被认为是可信的,并且应该被允许做任何事情。

我们的安全模式

  • 不受信任的HTML总是被清除

  • 从不执行不受信任的javascript

  • 标记单元格中的HTML和JavaScript从不受信任

  • 输出 用户生成的是可信的

  • 任何其他HTML或JavaScript(在降价单元格中,由其他人生成的输出)都不受信任

  • 信任的核心问题是“当前用户是否这样做了?”

信任的细节

当执行和保存Notebook时,将根据Notebook内容摘要加上密钥计算签名。它存储在数据库中,只能由当前用户写入。默认情况下,它位于:

~/.local/share/jupyter/nbsignatures.db  # Linux
~/Library/Jupyter/nbsignatures.db       # OS X
%APPDATA%/jupyter/nbsignatures.db       # Windows

每个签名代表一系列由当前用户执行的代码生成的输出,因此是可信的。

当您打开一个Notebook时,服务器会计算它的签名,并检查它是否在数据库中。如果找到匹配项,则加载时将信任Notebook中的HTML和JavaScript输出,否则将不受信任。

交互会话期间生成的任何输出都是可信的。

更新信任

保存Notebook时会更新Notebook的信任。如果Notebook中仍有任何不受信任的输出,则Notebook将不受信任,并且不会存储签名。如果已删除所有不受信任的输出(通过 Clear Output 或者重新执行),那么Notebook将变得可信。

当每个输出更新信任时,这只在单个会话期间进行。新加载的Notebook文件要么受信任,要么不完整。

显性信任

有时,重新执行Notebook以生成受信任的输出不是一个选项,因为依赖项不可用,或者需要很长时间。用户可以通过两种方式明确信任Notebook:

  • 在命令行,使用:

    jupyter trust /path/to/notebook.ipynb
    
  • 加载不受信任的Notebook后, File / Trust Notebook

这两种方法只需加载Notebook,计算新的签名,并将该签名添加到用户的数据库中。

报告安全问题

如果您在Jupyter中发现安全漏洞,或者代码未能正确实现此处描述的模型,或者模型本身出现故障,请将其报告给security@ipython.org。

如果希望加密安全报告,可以使用 this PGP public key .

受影响的用例

由于安全性的变化,在Jupyter1.0中工作的一些用例在2.0中变得不那么方便。我们尽最大努力减少这些烦恼,但安全总是与便利相冲突。

标记单元格中的javascript和css

虽然从未得到官方支持,但在标记单元格中放置隐藏的javascript或CSS样式已成为常见做法,这样它们就不会在页面上可见。因为现在标记单元格被(通过 Google Caja )所有的javascript(包括click事件处理程序等)和css都将被剥离。

我们计划为Notebook主题提供一种机制,但同时,设计Notebook只能通过 custom.css 或HTML输出中的CSS。后者只有在Notebook受信任的情况下才有效,否则输出将像降价一样被清除。

协作

在Notebook上进行协作时,人们可能希望看到同事最近执行的操作产生的输出。由于每个合作者的密钥不同,这将导致每个共享以不受信任的状态开始。有三种基本方法:

  • 收到Notebook后重新运行(不总是可行的)

  • 通过明确信任Notebook jupyter trust 或者Notebook菜单(烦人,但简单)

  • 共享Notebook签名数据库,并在处理项目时使用专用于协作的配置。

要在用户之间共享签名数据库,可以配置:

c.NotebookNotary.data_dir = "/path/to/signature_dir"

指定到sqlite数据库的非默认路径(基本上是Notebook哈希的路径)。我们知道sqlite在nfs上不能很好地工作, working out better ways to do this .