rack-secure-upload 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|