1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179
|
# frozen_string_literal: true
require "spec_helper"
module SecureHeaders
describe Cookie do
let(:raw_cookie) { "_session=thisisatest" }
it "does not tamper with cookies when using OPT_OUT is used" do
cookie = Cookie.new(raw_cookie, OPT_OUT)
expect(cookie.to_s).to eq(raw_cookie)
end
it "applies httponly, secure, and samesite by default" do
cookie = Cookie.new(raw_cookie, nil)
expect(cookie.to_s).to eq("_session=thisisatest; secure; HttpOnly; SameSite=Lax")
end
it "preserves existing attributes" do
cookie = Cookie.new("_session=thisisatest; secure", secure: true, httponly: OPT_OUT, samesite: OPT_OUT)
expect(cookie.to_s).to eq("_session=thisisatest; secure")
end
it "prevents duplicate flagging of attributes" do
cookie = Cookie.new("_session=thisisatest; secure", secure: true, httponly: OPT_OUT)
expect(cookie.to_s.scan(/secure/i).count).to eq(1)
end
context "Secure cookies" do
context "when configured with a boolean" do
it "flags cookies as Secure" do
cookie = Cookie.new(raw_cookie, secure: true, httponly: OPT_OUT, samesite: OPT_OUT)
expect(cookie.to_s).to eq("_session=thisisatest; secure")
end
end
context "when configured with a Hash" do
it "flags cookies as Secure when whitelisted" do
cookie = Cookie.new(raw_cookie, secure: { only: ["_session"]}, httponly: OPT_OUT, samesite: OPT_OUT)
expect(cookie.to_s).to eq("_session=thisisatest; secure")
end
it "does not flag cookies as Secure when excluded" do
cookie = Cookie.new(raw_cookie, secure: { except: ["_session"] }, httponly: OPT_OUT, samesite: OPT_OUT)
expect(cookie.to_s).to eq("_session=thisisatest")
end
end
end
context "HttpOnly cookies" do
context "when configured with a boolean" do
it "flags cookies as HttpOnly" do
cookie = Cookie.new(raw_cookie, httponly: true, secure: OPT_OUT, samesite: OPT_OUT)
expect(cookie.to_s).to eq("_session=thisisatest; HttpOnly")
end
end
context "when configured with a Hash" do
it "flags cookies as HttpOnly when whitelisted" do
cookie = Cookie.new(raw_cookie, httponly: { only: ["_session"]}, secure: OPT_OUT, samesite: OPT_OUT)
expect(cookie.to_s).to eq("_session=thisisatest; HttpOnly")
end
it "does not flag cookies as HttpOnly when excluded" do
cookie = Cookie.new(raw_cookie, httponly: { except: ["_session"] }, secure: OPT_OUT, samesite: OPT_OUT)
expect(cookie.to_s).to eq("_session=thisisatest")
end
end
end
context "SameSite cookies" do
%w(None Lax Strict).each do |flag|
it "flags SameSite=#{flag}" do
cookie = Cookie.new(raw_cookie, samesite: { flag.downcase.to_sym => { only: ["_session"] } }, secure: OPT_OUT, httponly: OPT_OUT)
expect(cookie.to_s).to eq("_session=thisisatest; SameSite=#{flag}")
end
it "flags SameSite=#{flag} when configured with a boolean" do
cookie = Cookie.new(raw_cookie, samesite: { flag.downcase.to_sym => true}, secure: OPT_OUT, httponly: OPT_OUT)
expect(cookie.to_s).to eq("_session=thisisatest; SameSite=#{flag}")
end
it "does not flag cookies as SameSite=#{flag} when excluded" do
cookie = Cookie.new(raw_cookie, samesite: { flag.downcase.to_sym => { except: ["_session"] } }, secure: OPT_OUT, httponly: OPT_OUT)
expect(cookie.to_s).to eq("_session=thisisatest")
end
end
it "flags SameSite=Strict when configured with a boolean" do
cookie = Cookie.new(raw_cookie, {samesite: { strict: true}, secure: OPT_OUT, httponly: OPT_OUT})
expect(cookie.to_s).to eq("_session=thisisatest; SameSite=Strict")
end
it "flags properly when both lax and strict are configured" do
raw_cookie = "_session=thisisatest"
cookie = Cookie.new(raw_cookie, samesite: { strict: { only: ["_session"] }, lax: { only: ["_additional_session"] } }, secure: OPT_OUT, httponly: OPT_OUT)
expect(cookie.to_s).to eq("_session=thisisatest; SameSite=Strict")
end
it "ignores configuration if the cookie is already flagged" do
raw_cookie = "_session=thisisatest; SameSite=Strict"
cookie = Cookie.new(raw_cookie, samesite: { lax: true }, secure: OPT_OUT, httponly: OPT_OUT)
expect(cookie.to_s).to eq(raw_cookie)
end
it "samesite: true sets all cookies to samesite=lax" do
raw_cookie = "_session=thisisatest"
cookie = Cookie.new(raw_cookie, samesite: true, secure: OPT_OUT, httponly: OPT_OUT)
expect(cookie.to_s).to eq("_session=thisisatest; SameSite=Lax")
end
end
end
context "with an invalid configuration" do
it "raises an exception when not configured with a Hash" do
expect do
Cookie.validate_config!("configuration")
end.to raise_error(CookiesConfigError)
end
it "raises an exception when configured without a boolean(true or OPT_OUT)/Hash" do
expect do
Cookie.validate_config!(secure: "true")
end.to raise_error(CookiesConfigError)
end
it "raises an exception when configured with false" do
expect do
Cookie.validate_config!(secure: false)
end.to raise_error(CookiesConfigError)
end
it "raises an exception when both only and except filters are provided" do
expect do
Cookie.validate_config!(secure: { only: [], except: [] })
end.to raise_error(CookiesConfigError)
end
it "raises an exception when SameSite is not configured with a Hash" do
expect do
Cookie.validate_config!(samesite: true)
end.to raise_error(CookiesConfigError)
end
cookie_options = %i(none lax strict)
cookie_options.each do |flag|
(cookie_options - [flag]).each do |other_flag|
it "raises an exception when SameSite #{flag} and #{other_flag} enforcement modes are configured with booleans" do
expect do
Cookie.validate_config!(samesite: { flag => true, other_flag => true})
end.to raise_error(CookiesConfigError)
end
end
end
it "raises an exception when SameSite lax and strict enforcement modes are configured with booleans" do
expect do
Cookie.validate_config!(samesite: { lax: true, strict: { only: ["_anything"] } })
end.to raise_error(CookiesConfigError)
end
it "raises an exception when both only and except filters are provided to SameSite configurations" do
expect do
Cookie.validate_config!(samesite: { lax: { only: ["_anything"], except: ["_anythingelse"] } })
end.to raise_error(CookiesConfigError)
end
it "raises an exception when both lax and strict only filters are provided to SameSite configurations" do
expect do
Cookie.validate_config!(samesite: { lax: { only: ["_anything"] }, strict: { only: ["_anything"] } })
end.to raise_error(CookiesConfigError)
end
it "raises an exception when both lax and strict only filters are provided to SameSite configurations" do
expect do
Cookie.validate_config!(samesite: { lax: { except: ["_anything"] }, strict: { except: ["_anything"] } })
end.to raise_error(CookiesConfigError)
end
end
end
|