rack-secure-upload 0.1.0 → 0.1.1
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 +4 -4
- data/README.md +1 -1
- data/lib/rack/secure_upload/middleware.rb +16 -4
- data/lib/rack/secure_upload/version.rb +1 -1
- data/spec/rack/secure_upload/middleware_spec.rb +46 -16
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b036f4ac41ac68592044502068e7988049f23991
|
4
|
+
data.tar.gz: 840e4c8358d2dbb268f0487076b43de84a4bf32a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 514c477f9022a3df886c57568bb8a737f98a7fd93f71b4c9cf922a7b9d8f2050e32de72795f1abcdf2b22477c9f27c9f794a4dbf00ad6eae6b8bc1ee3ced0d24
|
7
|
+
data.tar.gz: f71b8efc4bfa183ea50b97e48d72f86489464f20fa56a4e49b751a27a2a7b799086a78e826a71731136bc3cb75cd60c46b69a63c05978b03a313a16d809602d1
|
data/README.md
CHANGED
@@ -29,7 +29,7 @@ In `config/application.rb`
|
|
29
29
|
```ruby
|
30
30
|
module MyApp
|
31
31
|
class Application < Rails::Application
|
32
|
-
config.middleware.
|
32
|
+
config.middleware.insert_before ActionDispatch::ParamsParser, Rack::SecureUpload::Middleware, :avast
|
33
33
|
end
|
34
34
|
end
|
35
35
|
```
|
@@ -7,8 +7,9 @@ module Rack
|
|
7
7
|
class Middleware
|
8
8
|
include Utility
|
9
9
|
|
10
|
-
def initialize(app, scanners)
|
10
|
+
def initialize(app, scanners, options = {})
|
11
11
|
@app = app
|
12
|
+
@options = options
|
12
13
|
@scanners = [scanners].flatten.map { |scanner| scanner.is_a?(Symbol) ? Rack::SecureUpload::Scanner.const_get(camelize(scanner.to_s)).new : scanner }
|
13
14
|
@scanners.each do |scanner|
|
14
15
|
scanner.setup
|
@@ -19,9 +20,20 @@ module Rack
|
|
19
20
|
params = Rack::Multipart.parse_multipart(env)
|
20
21
|
|
21
22
|
if params && !params.empty?
|
22
|
-
|
23
|
-
|
24
|
-
|
23
|
+
begin
|
24
|
+
traverse(params) do |value|
|
25
|
+
next unless [Tempfile, File].any?{ |klass| value.is_a?(klass) }
|
26
|
+
scan value.path
|
27
|
+
end
|
28
|
+
rescue InsecureFileError => e
|
29
|
+
fallback = @options[:fallback]
|
30
|
+
if fallback.respond_to?(:call)
|
31
|
+
return fallback.call(env, params, e)
|
32
|
+
elsif fallback.to_s == 'raise'
|
33
|
+
raise
|
34
|
+
else
|
35
|
+
return [406, {'content-type' => 'text/plain; charset=UTF-8'}, ['Insecure File(s) are found!']]
|
36
|
+
end
|
25
37
|
end
|
26
38
|
end
|
27
39
|
|
@@ -1,33 +1,63 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
|
3
3
|
describe Rack::SecureUpload::Middleware do
|
4
|
-
let(:env) { Rack::MockRequest.env_for('/') }
|
4
|
+
let(:env) { Rack::MockRequest.env_for('/', method: :post, params: {foo: file}) }
|
5
5
|
let(:file) { Rack::Multipart::UploadedFile.new(__FILE__) }
|
6
6
|
let(:scanner) { double setup: true, scan: true }
|
7
|
-
|
7
|
+
let(:options) { {} }
|
8
|
+
subject { Rack::SecureUpload::Middleware.new(->env { ":)" }, scanner, options) }
|
8
9
|
|
9
|
-
|
10
|
-
|
10
|
+
it "scans" do
|
11
|
+
expect(scanner).to receive(:scan).once.and_return(true)
|
12
|
+
expect(subject.call(env)).to eq(":)")
|
13
|
+
end
|
14
|
+
it "returns 406" do
|
15
|
+
expect(scanner).to receive(:scan).and_return(false)
|
16
|
+
expect(subject.call(env)).to match_array([406, hash_including, match_array([//])])
|
17
|
+
end
|
18
|
+
|
19
|
+
context "with multiple uploaded files" do
|
20
|
+
let(:env) { Rack::MockRequest.env_for('/', method: :post, params: {foo: file, bar: file, zoo: file}) }
|
11
21
|
|
12
|
-
it "scans" do
|
13
|
-
expect(scanner).to receive(:scan)
|
14
|
-
subject.call(env)
|
22
|
+
it "scans multiple times" do
|
23
|
+
expect(scanner).to receive(:scan).exactly(3).times
|
24
|
+
expect(subject.call(env)).to eq(":)")
|
15
25
|
end
|
26
|
+
end
|
27
|
+
context "without uplaod file" do
|
28
|
+
let(:env) { Rack::MockRequest.env_for('/') }
|
16
29
|
|
17
|
-
|
18
|
-
|
30
|
+
it "does not scan" do
|
31
|
+
expect(scanner).not_to receive(:scan)
|
32
|
+
expect(subject.call(env)).to eq(":)")
|
33
|
+
end
|
34
|
+
end
|
35
|
+
context "fallback option" do
|
36
|
+
context "fallback is a proc" do
|
37
|
+
let(:fallback) { proc {} }
|
38
|
+
let(:options) { {fallback: fallback} }
|
19
39
|
|
20
|
-
it "
|
21
|
-
expect(
|
40
|
+
it "calls fallback" do
|
41
|
+
expect(fallback).to receive(:call)
|
42
|
+
allow(scanner).to receive(:scan).and_return(false)
|
22
43
|
subject.call(env)
|
23
44
|
end
|
24
45
|
end
|
25
|
-
|
46
|
+
context "fallback is raise" do
|
47
|
+
let(:options) { {fallback: :raise} }
|
26
48
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
49
|
+
it "raises an exception" do
|
50
|
+
allow(scanner).to receive(:scan).and_return(false)
|
51
|
+
expect { subject.call(env) }.to raise_error(Rack::SecureUpload::InsecureFileError)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
context "fallback is other value" do
|
55
|
+
let(:options) { {fallback: 'foo'} }
|
56
|
+
|
57
|
+
it "returns 406" do
|
58
|
+
allow(scanner).to receive(:scan).and_return(false)
|
59
|
+
expect(subject.call(env)).to match_array([406, hash_including, match_array([//])])
|
60
|
+
end
|
31
61
|
end
|
32
62
|
end
|
33
63
|
end
|