CVE-2022-4064: Improper Neutralization of Special Elements in Output Used by a Downstream Component ('Injection') (CWE-74)
value: A vulnerability was found in Dalli. It has been classified as problematic. Affected is the function self.meta_set of the file lib/dalli/protocol/meta/request_formatter.rb of the component Meta Protocol Handler. The manipulation leads to injection. The exploit has been disclosed to the public and may be used. The name of the patch is 48d594dae55934476fec61789e7a7c3700e0f50d. It is recommended to apply a patch to fix this issue. VDB-214026 is the identifier assigned to this vulnerability.
CWE description: The product constructs all or part of a command, data structure, or record using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify how it is parsed or interpreted when it is sent to a downstream component.
CVSS v3 base score: 3.7
Published: 2022-11-19T19:15Z
Repository: https://github.com/petergoldstein/dalli
Language: Ruby
Files changed: CHANGELOG.md, lib/dalli/protocol/meta.rb, lib/dalli/protocol/meta/request_formatter.rb, test/integration/test_network.rb, test/protocol/meta/test_request_formatter.rb, test/test_rack_session.rb
Commit date: 2022-10-27 17:58:52 -0400
Commit message: Fixes #932 (#933)

Do some input sanitization for the meta protocol. Since this protocol uses raw test, it is possible to execute an injection attack against unsanitized inputs.

This commit explicitly sanitizes the CAS arguments and the ttl passed to flush.

I also added some missing tests for meta_arithmetic and fixed a few lints.
Diff: diff --git a/CHANGELOG.md b/CHANGELOG.md
index 7032cb3..de0887b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,10 +2,12 @@ Dalli Changelog
 =====================
 
 Unreleased
 ==========
 
+- Sanitize CAS inputs to ensure additional commands are not passed to memcached (xhzeem / petergoldstein)
+- Sanitize input to flush command to ensure additional commands are not passed to memcached (xhzeem / petergoldstein)
 - Namespaces passed as procs are now evaluated every time, as opposed to just on initialization (nrw505)
 - Fix missing require of uri in ServerConfigParser (adam12)
 - Fix link to the CHANGELOG.md file in README.md (rud)
 
 3.2.2
diff --git a/lib/dalli/protocol/meta.rb b/lib/dalli/protocol/meta.rb
index 4d6c662..b2e66c3 100644
--- a/lib/dalli/protocol/meta.rb
+++ b/lib/dalli/protocol/meta.rb
@@ -42,10 +42,11 @@ module Dalli
         write(req)
         response_processor.meta_get_with_value(cache_nils: cache_nils?(options))
       end
 
       def touch(key, ttl)
+        ttl = TtlSanitizer.sanitize(ttl)
         encoded_key, base64 = KeyRegularizer.encode(key)
         req = RequestFormatter.meta_get(key: encoded_key, ttl: ttl, value: false, base64: base64)
         write(req)
         response_processor.meta_get_without_value
       end
diff --git a/lib/dalli/protocol/meta/request_formatter.rb b/lib/dalli/protocol/meta/request_formatter.rb
index b36a121..7e485fe 100644
--- a/lib/dalli/protocol/meta/request_formatter.rb
+++ b/lib/dalli/protocol/meta/request_formatter.rb
@@ -29,11 +29,11 @@ module Dalli
         def self.meta_set(key:, value:, bitflags: nil, cas: nil, ttl: nil, mode: :set, base64: false, quiet: false)
           cmd = "ms #{key} #{value.bytesize}"
           cmd << ' c' unless %i[append prepend].include?(mode)
           cmd << ' b' if base64
           cmd << " F#{bitflags}" if bitflags
-          cmd << " C#{cas}" if cas && !cas.zero?
+          cmd << cas_string(cas)
           cmd << " T#{ttl}" if ttl
           cmd << " M#{mode_to_token(mode)}"
           cmd << ' q' if quiet
           cmd << TERMINATOR
           cmd << value
@@ -41,23 +41,24 @@ module Dalli
         end
 
         def self.meta_delete(key:, cas: nil, ttl: nil, base64: false, quiet: false)
           cmd = "md #{key}"
           cmd << ' b' if base64
-          cmd << " C#{cas}" if cas && !cas.zero?
+          cmd << cas_string(cas)
           cmd << " T#{ttl}" if ttl
           cmd << ' q' if quiet
           cmd + TERMINATOR
         end
 
         def self.meta_arithmetic(key:, delta:, initial:, incr: true, cas: nil, ttl: nil, base64: false, quiet: false)
           cmd = "ma #{key} v"
           cmd << ' b' if base64
           cmd << " D#{delta}" if delta
           cmd << " J#{initial}" if initial
-          cmd << " C#{cas}" if cas && !cas.zero?
-          cmd << " N#{ttl}" if ttl
+          # Always set a TTL if an initial value is specified
+          cmd << " N#{ttl || 0}" if ttl || initial
+          cmd << cas_string(cas)
           cmd << ' q' if quiet
           cmd << " M#{incr ? 'I' : 'D'}"
           cmd + TERMINATOR
         end
         # rubocop:enable Metrics/CyclomaticComplexity
@@ -73,11 +74,11 @@ module Dalli
           "version#{TERMINATOR}"
         end
 
         def self.flush(delay: nil, quiet: false)
           cmd = +'flush_all'
-          cmd << " #{delay}" if delay
+          cmd << " #{parse_to_64_bit_int(delay, 0)}" if delay
           cmd << ' noreply' if quiet
           cmd + TERMINATOR
         end
 
         def self.stats(arg = nil)
@@ -100,9 +101,21 @@ module Dalli
           else
             'S'
           end
         end
         # rubocop:enable Metrics/MethodLength
+
+        def self.cas_string(cas)
+          cas = parse_to_64_bit_int(cas, nil)
+          cas.nil? || cas.zero? ? '' : " C#{cas}"
+        end
+
+        def self.parse_to_64_bit_int(val, default)
+          val.nil? ? nil : Integer(val)
+        rescue ArgumentError
+          # Sanitize to default if it isn't parsable as an integer
+          default
+        end
       end
     end
   end
 end
diff --git a/test/integration/test_network.rb b/test/integration/test_network.rb
index e0ea862..bf20baa 100644
--- a/test/integration/test_network.rb
+++ b/test/integration/test_network.rb
@@ -5,64 +5,64 @@ require_relative '../helper'
 describe 'Network' do
   MemcachedManager.supported_protocols.each do |p|
     describe "using the #{p} protocol" do
       describe 'assuming a bad network' do
         it 'handle no server available' do
+          dc = Dalli::Client.new 'localhost:19333'
           assert_raises Dalli::RingError, message: 'No server available' do
-            dc = Dalli::Client.new 'localhost:19333'
             dc.get 'foo'
           end
         end
 
         describe 'with a fake server' do
           it 'handle connection reset' do
             memcached_mock(->(sock) { sock.close }) do
+              dc = Dalli::Client.new('localhost:19123')
               assert_raises Dalli::RingError, message: 'No server available' do
-                dc = Dalli::Client.new('localhost:19123')
                 dc.get('abc')
               end
             end
           end
 
           it 'handle connection reset with unix socket' do
             socket_path = MemcachedMock::UNIX_SOCKET_PATH
             memcached_mock(->(sock) { sock.close }, :start_unix, socket_path) do
+              dc = Dalli::Client.new(socket_path)
               assert_raises Dalli::RingError, message: 'No server available' do
-                dc = Dalli::Client.new(socket_path)
                 dc.get('abc')
               end
             end
           end
 
           it 'handle malformed response' do
             memcached_mock(->(sock) { sock.write('123') }) do
+              dc = Dalli::Client.new('localhost:19123')
               assert_raises Dalli::RingError, message: 'No server available' do
-                dc = Dalli::Client.new('localhost:19123')
                 dc.get('abc')
               end
             end
           end
 
           it 'handle connect timeouts' do
             memcached_mock(lambda { |sock|
                              sleep(0.6)
                              sock.close
                            }, :delayed_start) do
+              dc = Dalli::Client.new('localhost:19123')
               assert_raises Dalli::RingError, message: 'No server available' do
-                dc = Dalli::Client.new('localhost:19123')
                 dc.get('abc')
               end
             end
           end
 
           it 'handle read timeouts' do
             memcached_mock(lambda { |sock|
                              sleep(0.6)
                              sock.write('giraffe')
                            }) do
+              dc = Dalli::Client.new('localhost:19123')
               assert_raises Dalli::RingError, message: 'No server available' do
-                dc = Dalli::Client.new('localhost:19123')
                 dc.get('abc')
               end
             end
           end
         end
diff --git a/test/protocol/meta/test_request_formatter.rb b/test/protocol/meta/test_request_formatter.rb
index 1eef499..755e730 100644
--- a/test/protocol/meta/test_request_formatter.rb
+++ b/test/protocol/meta/test_request_formatter.rb
@@ -75,15 +75,32 @@ describe Dalli::Protocol::Meta::RequestFormatter do
     it 'passes a CAS if one is provided' do
       assert_equal "ms #{key} #{val.bytesize} c F#{bitflags} C#{cas} MS\r\n#{val}\r\n",
                    Dalli::Protocol::Meta::RequestFormatter.meta_set(key: key, value: val, bitflags: bitflags, cas: cas)
     end
 
+    it 'excludes CAS if set to 0' do
+      assert_equal "ms #{key} #{val.bytesize} c F#{bitflags} MS\r\n#{val}\r\n",
+                   Dalli::Protocol::Meta::RequestFormatter.meta_set(key: key, value: val, bitflags: bitflags, cas: 0)
+    end
+
+    it 'excludes non-numeric CAS values' do
+      assert_equal "ms #{key} #{val.bytesize} c F#{bitflags} MS\r\n#{val}\r\n",
+                   Dalli::Protocol::Meta::RequestFormatter.meta_set(key: key, value: val, bitflags: bitflags,
+                                                                    cas: "\nset importantkey 1 1000 8\ninjected")
+    end
+
     it 'sets the quiet mode if configured' do
       assert_equal "ms #{key} #{val.bytesize} c F#{bitflags} MS q\r\n#{val}\r\n",
                    Dalli::Protocol::Meta::RequestFormatter.meta_set(key: key, value: val, bitflags: bitflags,
                                                                     quiet: true)
     end
+
+    it 'sets the base64 mode if configured' do
+      assert_equal "ms #{key} #{val.bytesize} c b F#{bitflags} MS\r\n#{val}\r\n",
+                   Dalli::Protocol::Meta::RequestFormatter.meta_set(key: key, value: val, bitflags: bitflags,
+                                                                    base64: true)
+    end
   end
 
   describe 'meta_delete' do
     let(:key) { SecureRandom.hex(4) }
     let(:cas) { rand(1000..1999) }
@@ -91,19 +108,100 @@ describe Dalli::Protocol::Meta::RequestFormatter do
     it 'returns the default when just passed key' do
       assert_equal "md #{key}\r\n",
                    Dalli::Protocol::Meta::RequestFormatter.meta_delete(key: key)
     end
 
-    it 'returns incorporates CAS when passed cas' do
+    it 'incorporates CAS when passed cas' do
       assert_equal "md #{key} C#{cas}\r\n",
                    Dalli::Protocol::Meta::RequestFormatter.meta_delete(key: key, cas: cas)
     end
 
     it 'sets the q flag when passed quiet' do
       assert_equal "md #{key} q\r\n",
                    Dalli::Protocol::Meta::RequestFormatter.meta_delete(key: key, quiet: true)
     end
+
+    it 'excludes CAS when set to 0' do
+      assert_equal "md #{key}\r\n",
+                   Dalli::Protocol::Meta::RequestFormatter.meta_delete(key: key, cas: 0)
+    end
+
+    it 'excludes non-numeric CAS values' do
+      assert_equal "md #{key}\r\n",
+                   Dalli::Protocol::Meta::RequestFormatter.meta_delete(key: key,
+                                                                       cas: "\nset importantkey 1 1000 8\ninjected")
+    end
+
+    it 'sets the base64 mode if configured' do
+      assert_equal "md #{key} b\r\n",
+                   Dalli::Protocol::Meta::RequestFormatter.meta_delete(key: key, base64: true)
+    end
+  end
+
+  describe 'meta_arithmetic' do
+    let(:key) { SecureRandom.hex(4) }
+    let(:delta) { rand(500..999) }
+    let(:initial) { rand(500..999) }
+    let(:cas) { rand(500..999) }
+    let(:ttl) { rand(500..999) }
+
+    it 'returns the expected string with the default N flag when passed non-nil key, delta, and initial' do
+      assert_equal "ma #{key} v D#{delta} J#{initial} N0 MI\r\n",
+                   Dalli::Protocol::Meta::RequestFormatter.meta_arithmetic(key: key, delta: delta, initial: initial)
+    end
+
+    it 'excludes the J and N flags when initial is nil and ttl is not set' do
+      assert_equal "ma #{key} v D#{delta} MI\r\n",
+                   Dalli::Protocol::Meta::RequestFormatter.meta_arithmetic(key: key, delta: delta, initial: nil)
+    end
+
+    it 'omits the D flag is delta is nil' do
+      assert_equal "ma #{key} v J#{initial} N0 MI\r\n",
+                   Dalli::Protocol::Meta::RequestFormatter.meta_arithmetic(key: key, delta: nil, initial: initial)
+    end
+
+    it 'uses ttl for the N flag when ttl passed explicitly along with an initial value' do
+      assert_equal "ma #{key} v D#{delta} J#{initial} N#{ttl} MI\r\n",
+                   Dalli::Protocol::Meta::RequestFormatter.meta_arithmetic(key: key, delta: delta, initial: initial,
+                                                                           ttl: ttl)
+    end
+
+    it 'incorporates CAS when passed cas' do
+      assert_equal "ma #{key} v D#{delta} J#{initial} N0 C#{cas} MI\r\n",
+                   Dalli::Protocol::Meta::RequestFormatter.meta_arithmetic(key: key, delta: delta, initial: initial,
+                                                                           cas: cas)
+    end
+
+    it 'excludes CAS when CAS is set to 0' do
+      assert_equal "ma #{key} v D#{delta} J#{initial} N0 MI\r\n",
+                   Dalli::Protocol::Meta::RequestFormatter.meta_arithmetic(key: key, delta: delta, initial: initial,
+                                                                           cas: 0)
+    end
+
+    it 'includes the N flag when ttl passed explicitly with a nil initial value' do
+      assert_equal "ma #{key} v D#{delta} N#{ttl} MI\r\n",
+                   Dalli::Protocol::Meta::RequestFormatter.meta_arithmetic(key: key, delta: delta, initial: nil,
+                                                                           ttl: ttl)
+    end
+
+    it 'swaps from MI to MD when the incr value is explicitly false' do
+      assert_equal "ma #{key} v D#{delta} J#{initial} N0 MD\r\n",
+                   Dalli::Protocol::Meta::RequestFormatter.meta_arithmetic(key: key, delta: delta, initial: initial,
+                                                                           incr: false)
+    end
+
+    it 'includes the quiet flag when specified' do
+      assert_equal "ma #{key} v D#{delta} J#{initial} N0 q MI\r\n",
+                   Dalli::Protocol::Meta::RequestFormatter.meta_arithmetic(key: key, delta: delta, initial: initial,
+                                                                           quiet: true)
+    end
+
+    it 'sets the base64 mode if configured' do
+      assert_equal "ma #{key} v b D#{delta} J#{initial} N0 MI\r\n",
+                   Dalli::Protocol::Meta::RequestFormatter.meta_arithmetic(key: key, delta: delta, initial: initial,
+                                                                           base64: true)
+    end
   end
 
   describe 'meta_noop' do
     it 'returns the expected string' do
       assert_equal "mn\r\n", Dalli::Protocol::Meta::RequestFormatter.meta_noop
@@ -128,10 +226,15 @@ describe Dalli::Protocol::Meta::RequestFormatter do
     it 'returns the expected string with a delay argument' do
       delay = rand(1000..1999)
       assert_equal "flush_all #{delay}\r\n", Dalli::Protocol::Meta::RequestFormatter.flush(delay: delay)
     end
 
+    it 'santizes the delay argument' do
+      delay = "\nset importantkey 1 1000 8\ninjected"
+      assert_equal "flush_all 0\r\n", Dalli::Protocol::Meta::RequestFormatter.flush(delay: delay)
+    end
+
     it 'adds noreply with a delay and quiet argument' do
       delay = rand(1000..1999)
       assert_equal "flush_all #{delay} noreply\r\n",
                    Dalli::Protocol::Meta::RequestFormatter.flush(delay: delay, quiet: true)
     end
diff --git a/test/test_rack_session.rb b/test/test_rack_session.rb
index e56a098..9386034 100644
--- a/test/test_rack_session.rb
+++ b/test/test_rack_session.rb
@@ -52,19 +52,19 @@ describe Rack::Session::Dalli do
                    end)
   end
   let(:incrementor) { Rack::Lint.new(incrementor_proc) }
 
   it 'faults on no connection' do
+    rsd = Rack::Session::Dalli.new(incrementor, memcache_server: 'nosuchserver')
     assert_raises Dalli::RingError do
-      rsd = Rack::Session::Dalli.new(incrementor, memcache_server: 'nosuchserver')
       rsd.data.with { |c| c.set('ping', '') }
     end
   end
 
   it 'connects to existing server' do
+    rsd = Rack::Session::Dalli.new(incrementor, namespace: 'test:rack:session')
     assert_silent do
-      rsd = Rack::Session::Dalli.new(incrementor, namespace: 'test:rack:session')
       rsd.data.with { |c| c.set('ping', '') }
     end
   end
 
   it 'passes options to MemCache' do

Vulnerable code:           cmd << " C#{cas}" if cas && !cas.zero?
          cmd << " C#{cas}" if cas && !cas.zero?
          cmd << " C#{cas}" if cas && !cas.zero?
          cmd << " N#{ttl}" if ttl
          cmd << " #{delay}" if delay
            dc = Dalli::Client.new 'localhost:19333'
                dc = Dalli::Client.new('localhost:19123')
                dc = Dalli::Client.new(socket_path)
                dc = Dalli::Client.new('localhost:19123')
                dc = Dalli::Client.new('localhost:19123')
                dc = Dalli::Client.new('localhost:19123')
    it 'returns incorporates CAS when passed cas' do
      rsd = Rack::Session::Dalli.new(incrementor, memcache_server: 'nosuchserver')
      rsd = Rack::Session::Dalli.new(incrementor, namespace: 'test:rack:session')
Fixed code: - Sanitize CAS inputs to ensure additional commands are not passed to memcached (xhzeem / petergoldstein)
- Sanitize input to flush command to ensure additional commands are not passed to memcached (xhzeem / petergoldstein)
        ttl = TtlSanitizer.sanitize(ttl)
          cmd << cas_string(cas)
          cmd << cas_string(cas)
          # Always set a TTL if an initial value is specified
          cmd << " N#{ttl || 0}" if ttl || initial
          cmd << cas_string(cas)
          cmd << " #{parse_to_64_bit_int(delay, 0)}" if delay

        def self.cas_string(cas)
          cas = parse_to_64_bit_int(cas, nil)
          cas.nil? || cas.zero? ? '' : " C#{cas}"
        end

        def self.parse_to_64_bit_int(val, default)
          val.nil? ? nil : Integer(val)
        rescue ArgumentError
          # Sanitize to default if it isn't parsable as an integer
          default
        end
          dc = Dalli::Client.new 'localhost:19333'
              dc = Dalli::Client.new('localhost:19123')
              dc = Dalli::Client.new(socket_path)
              dc = Dalli::Client.new('localhost:19123')
              dc = Dalli::Client.new('localhost:19123')
              dc = Dalli::Client.new('localhost:19123')
    it 'excludes CAS if set to 0' do
      assert_equal "ms #{key} #{val.bytesize} c F#{bitflags} MS\r\n#{val}\r\n",
                   Dalli::Protocol::Meta::RequestFormatter.meta_set(key: key, value: val, bitflags: bitflags, cas: 0)
    end

    it 'excludes non-numeric CAS values' do
      assert_equal "ms #{key} #{val.bytesize} c F#{bitflags} MS\r\n#{val}\r\n",
                   Dalli::Protocol::Meta::RequestFormatter.meta_set(key: key, value: val, bitflags: bitflags,
                                                                    cas: "\nset importantkey 1 1000 8\ninjected")
    end


    it 'sets the base64 mode if configured' do
      assert_equal "ms #{key} #{val.bytesize} c b F#{bitflags} MS\r\n#{val}\r\n",
                   Dalli::Protocol::Meta::RequestFormatter.meta_set(key: key, value: val, bitflags: bitflags,
                                                                    base64: true)
    end
    it 'incorporates CAS when passed cas' do

    it 'excludes CAS when set to 0' do
      assert_equal "md #{key}\r\n",
                   Dalli::Protocol::Meta::RequestFormatter.meta_delete(key: key, cas: 0)
    end

    it 'excludes non-numeric CAS values' do
      assert_equal "md #{key}\r\n",
                   Dalli::Protocol::Meta::RequestFormatter.meta_delete(key: key,
                                                                       cas: "\nset importantkey 1 1000 8\ninjected")
    end

    it 'sets the base64 mode if configured' do
      assert_equal "md #{key} b\r\n",
                   Dalli::Protocol::Meta::RequestFormatter.meta_delete(key: key, base64: true)
    end
  end

  describe 'meta_arithmetic' do
    let(:key) { SecureRandom.hex(4) }
    let(:delta) { rand(500..999) }
    let(:initial) { rand(500..999) }
    let(:cas) { rand(500..999) }
    let(:ttl) { rand(500..999) }

    it 'returns the expected string with the default N flag when passed non-nil key, delta, and initial' do
      assert_equal "ma #{key} v D#{delta} J#{initial} N0 MI\r\n",
                   Dalli::Protocol::Meta::RequestFormatter.meta_arithmetic(key: key, delta: delta, initial: initial)
    end

    it 'excludes the J and N flags when initial is nil and ttl is not set' do
      assert_equal "ma #{key} v D#{delta} MI\r\n",
                   Dalli::Protocol::Meta::RequestFormatter.meta_arithmetic(key: key, delta: delta, initial: nil)
    end

    it 'omits the D flag is delta is nil' do
      assert_equal "ma #{key} v J#{initial} N0 MI\r\n",
                   Dalli::Protocol::Meta::RequestFormatter.meta_arithmetic(key: key, delta: nil, initial: initial)
    end

    it 'uses ttl for the N flag when ttl passed explicitly along with an initial value' do
      assert_equal "ma #{key} v D#{delta} J#{initial} N#{ttl} MI\r\n",
                   Dalli::Protocol::Meta::RequestFormatter.meta_arithmetic(key: key, delta: delta, initial: initial,
                                                                           ttl: ttl)
    end

    it 'incorporates CAS when passed cas' do
      assert_equal "ma #{key} v D#{delta} J#{initial} N0 C#{cas} MI\r\n",
                   Dalli::Protocol::Meta::RequestFormatter.meta_arithmetic(key: key, delta: delta, initial: initial,
                                                                           cas: cas)
    end

    it 'excludes CAS when CAS is set to 0' do
      assert_equal "ma #{key} v D#{delta} J#{initial} N0 MI\r\n",
                   Dalli::Protocol::Meta::RequestFormatter.meta_arithmetic(key: key, delta: delta, initial: initial,
                                                                           cas: 0)
    end

    it 'includes the N flag when ttl passed explicitly with a nil initial value' do
      assert_equal "ma #{key} v D#{delta} N#{ttl} MI\r\n",
                   Dalli::Protocol::Meta::RequestFormatter.meta_arithmetic(key: key, delta: delta, initial: nil,
                                                                           ttl: ttl)
    end

    it 'swaps from MI to MD when the incr value is explicitly false' do
      assert_equal "ma #{key} v D#{delta} J#{initial} N0 MD\r\n",
                   Dalli::Protocol::Meta::RequestFormatter.meta_arithmetic(key: key, delta: delta, initial: initial,
                                                                           incr: false)
    end

    it 'includes the quiet flag when specified' do
      assert_equal "ma #{key} v D#{delta} J#{initial} N0 q MI\r\n",
                   Dalli::Protocol::Meta::RequestFormatter.meta_arithmetic(key: key, delta: delta, initial: initial,
                                                                           quiet: true)
    end

    it 'sets the base64 mode if configured' do
      assert_equal "ma #{key} v b D#{delta} J#{initial} N0 MI\r\n",
                   Dalli::Protocol::Meta::RequestFormatter.meta_arithmetic(key: key, delta: delta, initial: initial,
                                                                           base64: true)
    end
    it 'santizes the delay argument' do
      delay = "\nset importantkey 1 1000 8\ninjected"
      assert_equal "flush_all 0\r\n", Dalli::Protocol::Meta::RequestFormatter.flush(delay: delay)
    end

    rsd = Rack::Session::Dalli.new(incrementor, memcache_server: 'nosuchserver')
    rsd = Rack::Session::Dalli.new(incrementor, namespace: 'test:rack:session')