非常教程

Ruby 2.4参考手册

语言 | 3Language

Ruby Security

Ruby 编程语言庞大而复杂,新手和经验丰富的 Rubyists 经常遇到许多安全缺陷。

本文档旨在讨论这些缺陷,并在适用的情况下提供更安全的替代方案。

请查看公共已知CVE的完整列表以及如何正确报告安全漏洞,网址为:www.ruby-lang.org/en/security/ 日文版本位于:www.ruby-lang.org/ja/security /

应通过电子邮件将安全漏洞报告给 security@ruby-lang.org(PGP 公钥),这是一个私人邮件列表。报告的问题将在修复后发布。

$SAFE

Ruby 提供了一种机制来限制 Ruby 代码以$SAFE变量的形式执行哪些操作。

但是,$SAFE不提供执行不可信代码的安全环境。

如果您需要执行不受信任的代码,则应使用操作系统级别的沙盒机制。在Linux上,ptrace或LXC可用于沙盒可能的恶意代码。每个主要操作系统都有其他类似的机制。

Marshal.load

Ruby的Marshal模块提供了用于序列化和反序列化二进制数据格式的 Ruby 对象树的方法。

切勿使用Marshal.load反序列化不可信或用户提供的数据。因为Marshal可以反序列化几乎所有的 Ruby 对象,并且可以完全控制实例变量,所以可以在反序列化之后立即构造一个执行代码的恶意负载。

如果您需要反序列化不可信数据,则应该使用 JSON,因为它只能返回“原始”类型,如字符串,数组,哈希,数字和零。如果你需要反序列化其他类,你应该手动处理。切勿反序列化为用户指定的类。

YAML

YAML 是一种流行的人类可读数据序列化格式,被许多 Ruby 程序用于 Ruby 对象树的配置和数据库持久性。

类似的Marshal,它可以反序列化成任意的 Ruby 类。例如,以下 YAML 数据将ERB在反序列化时创建一个对象:

!ruby/object:ERB
src: puts `uname`

因此,适用于元帅的许多安全考虑事项也适用于 YAML。不要使用 YAML 来反序列化不可信数据。

符号

符号通常被视为简单字符串的语法糖,但它们扮演着非常关键的角色。MRI Ruby 实现在方法,变量和常量名称内部使用符号。其原因是符号只是名称附加的整数,所以它们在哈希表中查找速度更快。

从版本2.2开始,大多数符号可以被垃圾收集; 这些被称为平凡的符号。你创建的大多数符号(例如通过调用to_sym)都是致命的。

另一方面,不朽的符号永远不会被垃圾收集。修改代码时会创建它们:

  • 定义一个方法(例如define_method),
  • 设置一个实例变量(例如with instance_variable_set),
  • 创建一个变量或常量(例如与const_set

尚未更新且仍在呼叫的 C 扩展SYM2ID将创建不朽的符号。2.2.0中的错误:send+ __ send __ +也创建了不朽的符号,并且调用具有关键字参数的方法也可以创建一些。

不要从用户输入中创建不朽的符号。否则,这将允许用户通过使用唯一字符串填充对应用程序的拒绝服务攻击,这会导致内存无限增长,直到 Ruby 进程死亡或导致系统减速停止。

虽然它可能不是一个好主意,与用户输入,曾经是脆弱的,如方法调用这些to_symrespond_to?methodinstance_variable_getconst_get,等不再是一个威胁。

常用表达

与其他语言相比,Ruby 的正则表达式语法有一些细微差别。在R uby中,^$锚不是指字符串,而开始和结束的开始和结束

这意味着如果您使用正则表达式/^[a-z]+$/来将字符串限制为仅字母,攻击者可以通过传递包含字母,换行符和任意字符串的字符串来绕过此检查。

如果你想匹配 Ruby 中整个字符串的开头和结尾,使用锚\A\z

eval

切勿将不可信或用户控制的输入传递给eval

除非你实现像 REPL irb或者pryeval是几乎可以肯定不是你想要的。不要试图在传递给用户输入之前过滤用户输入eval- 这种方法充满了危险,并且很可能会将您的应用程序打开到严重的远程代码执行漏洞。

send

Ruby 中的“全局函数”(putsexit等)实际上是私有的实例方法Object。这意味着send即使调用send具有明确的接收者,也可以调用这些方法。

例如,以下代码片段将 “Hello world” 写入终端:

1.send(:puts, "Hello world")

您不应该send使用用户提供的输入作为第一个参数。这样做可能会导致拒绝服务漏洞:

foo.send(params[:bar]) # params[:bar] is "exit!"

如果攻击者可以控制前两个参数send,则可以执行远程代码:

# params is { :a => "eval", :b => "...ruby code to be executed..." }
foo.send(params[:a], params[:b])

根据用户输入调度方法调用时,请仔细验证方法名称。如果可能的话,请根据安全方法名称的白名单进行检查。

请注意,使用public_send也是危险的,因为send它本身是公开的:

1.public_send("send", "eval", "...ruby code to be executed...")

DRb

由于 DRb 允许远程客户端调用任意方法,因此不适合暴露给不受信任的客户端。

使用 DRb 时,尽量避免将其暴露在网络上。如果这不可行并且您需要将 DRb 公开给世界,则必须使用相应的安全策略进行配置DRb::ACL

Ruby 2.4

Ruby 是一种面向对象、命令式、函数式、动态的通用编程语言,是世界上最优美而巧妙的语言。

主页 https://www.ruby-lang.org/
源码 https://github.com/ruby/ruby
版本 2.4
发布版本 2.4.1

Ruby 2.4目录

1.缩略 | Abbrev
2.ARGF
3.数组 | Array
4.Base64
5.基本对象 | BasicObject
6.基准测试 | Benchmark
7.BigDecimal
8.绑定 | Binding
9.CGI
10.类 | Class
11.比较 | Comparable
12.负责 | Complex
13.计算续体 | Continuation
14.覆盖 | Coverage
15.CSV
16.日期 | Date
17.日期时间 | DateTime
18.DBM
19.代理 | Delegator
20.摘要 | Digest
21.Dir
22.DRb
23.编码 | Encoding
24.枚举 | Enumerable
25.枚举 | Enumerator
26.ENV
27.ERB
28.错误 | Errors
29.Etc
30.期望值 | Exception
31.错误类 | FalseClass
32.Fiber
33.Fiddle
34.文件 | File
35.文件实用程序 | FileUtils
36.查找 | Find
37.浮点 | Float
38.Forwardable
39.GC
40.GDBM
41.GetoptLong
42.Hash
43.Integer
44.IO
45.IPAddr
46.JSON
47.Kernel
48.语言 | 3Language
49.记录 | Logger
50.编排 | Marshal
51.MatchData
52.数学 | Math
53.矩阵 | Matrix
54.方法 | Method
55.模型 | Module
56.监控 | Monitor
57. 互斥 | Mutex
58.Net
59.Net::FTP
60.Net::HTTP
61.Net::IMAP
62.Net::SMTP
63.NilClass
64.数字 | Numeric
65.对象 | Object
66.ObjectSpace
67.Observable
68.Open3
69.OpenSSL
70.OpenStruct
71.OpenURI
72.OptionParser
73.路径名 | Pathname
74.完整输出 | PrettyPrint
75.Prime
76.Proc
77.过程 | Process
78.PStore
79.PTY
80.队列 | Queue
81.随机 | Random
82.范围 | Range
83.合理的 | Rational
84.Readline
85.Regexp
86.Resolv
87.Ripper
88.RubyVM
89.Scanf
90.SDBM
91.SecureRandom
92.Set
93.Shell
94.信号 | Signal
95.Singleton
96.套接字 | Socket
97.字符串 | String
98.StringIO
99.StringScanner
100.结构 | Struct