curb 1.3.5 → 1.3.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a502fb4afad21a24a20302b7522b616b08afbbe3d4b5b2a3eeee46d83b53c50d
4
- data.tar.gz: 5e68fd3f3380f2045dfc6d4e8e157ebbb9fc56e4b76601574c92a755665eeef2
3
+ metadata.gz: 11348a158e7da3d3406acd021be1a15f881ce2c607ff04e60b522a3bd92cd828
4
+ data.tar.gz: 0c524ce914df77b109a2aad85289386b2bf54028733fcf4ec5657a84abf511b8
5
5
  SHA512:
6
- metadata.gz: 940f343ad1d926ddcf27b994bca191e131176e766dce3d7f211f9ed5b28917ffb9ebfa5b8f71247ac8ca8a0b916e6565b60fb2ae57a964770b3273d1bd7d5d69
7
- data.tar.gz: 77a44dd831eea50e786d4b4871c2f1702e3bee2c74d0484f7b0812a91d19d4bcdd79c12e20dce7cd8ffcbaf0e06ae77cc6cc7734b7c71fa2feabc636af82b0d8
6
+ metadata.gz: b4ebd6b04943bfc099a6593ede1c70298555ed1a6613958e8628cde43c30b8c7f8b86990d91c7a350481589495fe7d5dc4ad1ac3c313823bb7fb21e483e8910c
7
+ data.tar.gz: 0a78bc41496259eae9989d25e4a47c57a9a9aed6f79b00e77efae691b487a730e71e6cdf8081ae35d33893a84b033219ae24c40cf47effd8e3d1b0ca3591f222
data/README.md CHANGED
@@ -199,6 +199,63 @@ Curl::Multi.download(urls, options) do |curl, file_path|
199
199
  end
200
200
  ```
201
201
 
202
+ ## Security considerations
203
+
204
+ `curb` is a libcurl binding and intentionally supports protocols beyond HTTP.
205
+ Do not pass untrusted URLs to `Curl.get`, `Curl::Easy.new`, or related raw
206
+ helpers without application-level validation. For user-supplied URLs, enable the
207
+ process-wide safety policy before making requests:
208
+
209
+ ```ruby
210
+ Curl.safe! do |config|
211
+ config.network_policy = :public # block local/private destination IPs
212
+ config.max_body_bytes = 1_000_000 # cap buffered/callback response bytes
213
+ end
214
+
215
+ curl = Curl.get(user_url) # allows only http/https, including redirects
216
+ ```
217
+
218
+ To allow a different protocol set, configure it explicitly. Redirects default to
219
+ the same protocol list:
220
+
221
+ ```ruby
222
+ Curl.safe! do |config|
223
+ config.protocols = [:http, :ftp]
224
+ config.max_body_bytes = 1_000_000
225
+ end
226
+ ```
227
+
228
+ For local per-handle policy instead of process-wide policy, use
229
+ `easy.safe_http!` and `easy.max_body_bytes = ...` before `perform`.
230
+
231
+ With `network_policy = :public`, curb checks peer addresses when libcurl opens
232
+ the socket and blocks local/private destinations. Proxies, `resolve`,
233
+ `connect_to`, DoH URL overrides, and Unix socket paths are disabled by default
234
+ under this policy unless explicitly allowed in the safety config. Custom DNS
235
+ server overrides are rejected. To use a trusted explicit proxy without
236
+ re-enabling environment proxies, set `allowed_proxy_hosts` and configure
237
+ `easy.proxy_url` on the request.
238
+
239
+ For stricter egress, combine the public network policy with host and CIDR
240
+ allowlists. Host allowlists gate the configured request URL and, when supported
241
+ by libcurl, each followed redirect before the request is sent. CIDR allowlists
242
+ are checked against the resolved peer address at socket-open time:
243
+
244
+ ```ruby
245
+ Curl.safe! do |config|
246
+ config.network_policy = :public
247
+ config.allowed_hosts = ["api.example.com"]
248
+ config.allowed_proxy_hosts = ["proxy.example.com"]
249
+ config.allowed_cidrs = ["93.184.216.0/24", "2606:2800:220::/48"]
250
+ end
251
+ ```
252
+
253
+ By default, responses are buffered into `body` when no `on_body` callback is
254
+ configured. For untrusted or large responses, use `on_body`, `download`, and/or
255
+ `max_body_bytes` so a remote endpoint cannot force unbounded memory growth.
256
+ `max_body_bytes` is enforced for downloads as well as buffered responses and
257
+ custom body callbacks.
258
+
202
259
  ## You will need
203
260
 
204
261
  * A working Ruby installation (`2.0.0+` will work but `2.1+` preferred) (it's possible it still works with 1.8.7 but you'd have to tell me if not...)
data/Rakefile CHANGED
@@ -107,9 +107,10 @@ else
107
107
  end
108
108
 
109
109
  ruby_memcheck_config = { binary_name: 'curb_core' }
110
+ ruby_version = Gem::Version.new(RUBY_VERSION)
110
111
 
111
- if RUBY_ENGINE == 'ruby' && RUBY_VERSION == '4.0.4'
112
- # Ruby 4.0.4 reports fiber/block-handler VM stack accesses under Valgrind.
112
+ if RUBY_ENGINE == 'ruby' && ruby_version >= Gem::Version.new('4.0.4') && ruby_version < Gem::Version.new('4.1.0')
113
+ # Ruby 4.0.4+ reports fiber/block-handler VM stack accesses under Valgrind.
113
114
  # Keep reporting errors that originate in curb_core, but filter Ruby-side noise.
114
115
  ruby_memcheck_config[:filter_all_errors] = true
115
116
  if RubyMemcheck::Configuration.instance_method(:initialize).parameters.any? { |type, name|
@@ -183,7 +184,11 @@ end
183
184
  # RDoc Tasks ---------------------------------------------------------
184
185
  desc "Create the RDOC documentation"
185
186
  task :doc do
186
- ruby "doc.rb #{ENV['DOC_OPTS']}"
187
+ doc_opts = Shellwords.split(ENV.fetch('DOC_OPTS', ''))
188
+ unsupported_opts = doc_opts - ['--cpp']
189
+ fail "Unsupported DOC_OPTS: #{unsupported_opts.join(' ')}" unless unsupported_opts.empty?
190
+
191
+ ruby 'doc.rb', *doc_opts
187
192
  end
188
193
 
189
194
  desc "Publish the RDoc documentation to project web site"
data/doc.rb CHANGED
@@ -1,10 +1,35 @@
1
1
  require 'fileutils'
2
+ require 'open3'
3
+ require 'shellwords'
2
4
  include FileUtils
3
5
 
4
- begin
5
- incflags = File.read('ext/Makefile')[/INCFLAGS\s*=\s*(.*)$/,1]
6
+ def makefile_variables(path)
7
+ variables = {}
8
+
9
+ File.foreach(path) do |line|
10
+ line = line.chomp
11
+ variables[$1] = $2.strip if line =~ /\A([A-Za-z_]\w*)\s*=\s*(.*)\z/
12
+ end
13
+
14
+ variables
15
+ end
16
+
17
+ def expand_make_variables(value, variables, seen = [])
18
+ value.gsub(/\$\(([^)]+)\)/) do
19
+ key = Regexp.last_match(1)
20
+ raise ArgumentError, "unsupported Makefile variable in INCFLAGS: #{key}" unless variables.key?(key)
21
+ raise ArgumentError, "recursive Makefile variable in INCFLAGS: #{key}" if seen.include?(key)
22
+
23
+ expand_make_variables(variables[key], variables, seen + [key])
24
+ end
25
+ end
26
+
27
+ def makefile_incflags
28
+ variables = makefile_variables('ext/Makefile')
29
+ Shellwords.split(expand_make_variables(variables.fetch('INCFLAGS', ''), variables))
6
30
  rescue Errno::ENOENT
7
31
  $stderr.puts("No makefile found; run `rake ext/Makefile' first.")
32
+ []
8
33
  end
9
34
 
10
35
  pp_srcdir = 'ext'
@@ -15,26 +40,41 @@ mkdir(tmpdir)
15
40
  begin
16
41
  if ARGV.include?('--cpp')
17
42
  begin
18
- if `cpp --version` =~ /\(GCC\)/
43
+ cpp_version, status = Open3.capture2e('cpp', '--version')
44
+
45
+ if status.success? && cpp_version =~ /\(GCC\)/
19
46
  # gnu cpp
20
47
  $stderr.puts "Running GNU cpp over source"
48
+ incflags = makefile_incflags
21
49
 
22
- Dir['ext/*.c'].each do |fn|
23
- system("cpp -DRDOC_NEVER_DEFINED -C #{incflags} -o " +
24
- "#{File.join(tmpdir, File.basename(fn))} #{fn}")
50
+ Dir['ext/*.c'].sort.each do |fn|
51
+ out = File.join(tmpdir, File.basename(fn))
52
+ abort "cpp failed for #{fn}" unless system('cpp', '-DRDOC_NEVER_DEFINED', '-C', *incflags, '-o', out, fn)
25
53
  end
26
54
 
27
55
  pp_srcdir = tmpdir
28
56
  else
29
57
  $stderr.puts "Not running cpp (non-GNU)"
30
58
  end
31
- rescue
59
+ rescue Errno::ENOENT
32
60
  # no cpp
33
61
  $stderr.puts "No cpp found"
62
+ rescue ArgumentError => e
63
+ abort e.message
34
64
  end
35
65
  end
36
66
 
37
- system("rdoc --title='Curb - libcurl bindings for ruby' --main=README #{pp_srcdir}/*.c README LICENSE lib/curb.rb")
67
+ main = File.exist?('README.md') ? 'README.md' : 'README'
68
+ sources = Dir[File.join(pp_srcdir, '*.c')].sort
69
+ abort 'rdoc failed' unless system(
70
+ 'rdoc',
71
+ '--title', 'Curb - libcurl bindings for ruby',
72
+ '--main', main,
73
+ *sources,
74
+ main,
75
+ 'LICENSE',
76
+ 'lib/curb.rb'
77
+ )
38
78
  ensure
39
79
  rm_rf(tmpdir)
40
80
  end
data/ext/curb.c CHANGED
@@ -457,6 +457,12 @@ void Init_curb_core() {
457
457
  #endif
458
458
  #ifdef HAVE_CURLOPT_OPENSOCKETDATA
459
459
  CURB_DEFINE(CURLOPT_OPENSOCKETDATA);
460
+ #endif
461
+ #ifdef HAVE_CURLOPT_PREREQFUNCTION
462
+ CURB_DEFINE(CURLOPT_PREREQFUNCTION);
463
+ #endif
464
+ #ifdef HAVE_CURLOPT_PREREQDATA
465
+ CURB_DEFINE(CURLOPT_PREREQDATA);
460
466
  #endif
461
467
  /* CURLOPT_PROGRESSFUNCTION deprecated since 7.32.0, use XFERINFOFUNCTION */
462
468
  #ifdef HAVE_CURLOPT_PROGRESSFUNCTION
@@ -557,6 +563,9 @@ void Init_curb_core() {
557
563
  CURB_DEFINE(CURLOPT_LOCALPORT);
558
564
  #endif
559
565
  CURB_DEFINE(CURLOPT_DNS_CACHE_TIMEOUT);
566
+ #ifdef HAVE_CURLOPT_DNS_SERVERS
567
+ CURB_DEFINE(CURLOPT_DNS_SERVERS);
568
+ #endif
560
569
  /* CURLOPT_DNS_USE_GLOBAL_CACHE deprecated since 7.11.1, does nothing since 7.62.0 */
561
570
  #ifdef HAVE_CURLOPT_DNS_USE_GLOBAL_CACHE
562
571
  CURB_DEFINE(CURLOPT_DNS_USE_GLOBAL_CACHE);
@@ -955,6 +964,9 @@ void Init_curb_core() {
955
964
  #ifdef HAVE_CURLUSESSL_ALL
956
965
  CURB_DEFINE(CURLUSESSL_ALL);
957
966
  #endif
967
+ #ifdef HAVE_CURLOPT_CONNECT_TO
968
+ CURB_DEFINE(CURLOPT_CONNECT_TO);
969
+ #endif
958
970
  #ifdef HAVE_CURLOPT_RESOLVE
959
971
  CURB_DEFINE(CURLOPT_RESOLVE);
960
972
  #endif
@@ -1011,6 +1023,18 @@ void Init_curb_core() {
1011
1023
  #ifdef HAVE_CURLOPT_SSL_VERIFYPEER
1012
1024
  CURB_DEFINE(CURLOPT_SSL_VERIFYPEER);
1013
1025
  #endif
1026
+ #ifdef HAVE_CURLOPT_DOH_URL
1027
+ CURB_DEFINE(CURLOPT_DOH_URL);
1028
+ #endif
1029
+ #ifdef HAVE_CURLOPT_DOH_SSL_VERIFYPEER
1030
+ CURB_DEFINE(CURLOPT_DOH_SSL_VERIFYPEER);
1031
+ #endif
1032
+ #ifdef HAVE_CURLOPT_DOH_SSL_VERIFYHOST
1033
+ CURB_DEFINE(CURLOPT_DOH_SSL_VERIFYHOST);
1034
+ #endif
1035
+ #ifdef HAVE_CURLOPT_DOH_SSL_VERIFYSTATUS
1036
+ CURB_DEFINE(CURLOPT_DOH_SSL_VERIFYSTATUS);
1037
+ #endif
1014
1038
  #ifdef HAVE_CURLOPT_CAINFO
1015
1039
  CURB_DEFINE(CURLOPT_CAINFO);
1016
1040
  #endif
data/ext/curb.h CHANGED
@@ -28,11 +28,11 @@
28
28
  #include "curb_macros.h"
29
29
 
30
30
  // These should be managed from the Rake 'release' task.
31
- #define CURB_VERSION "1.3.5"
32
- #define CURB_VER_NUM 1035
31
+ #define CURB_VERSION "1.3.6"
32
+ #define CURB_VER_NUM 1036
33
33
  #define CURB_VER_MAJ 1
34
34
  #define CURB_VER_MIN 3
35
- #define CURB_VER_MIC 5
35
+ #define CURB_VER_MIC 6
36
36
  #define CURB_VER_PATCH 0
37
37
 
38
38