image_vise 0.1.5 → 0.1.6

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f8355426daabd653dd28ce986a379ce74d04015a
4
- data.tar.gz: c986a6120fec633545eaaaddb57daf751fc3067f
3
+ metadata.gz: 2176fbaf15e4bc2d36a698796bfd934f84100070
4
+ data.tar.gz: 56396a529ce373d32b7a2a27522c8ad82ac65bf9
5
5
  SHA512:
6
- metadata.gz: 3ab6e3c250db5aa9870702b99b15c5bbbf29bc5d5acdd6647c8bdbb639a2b97b212cc6d9d5d3a10c9007a767ec8a53ede4625479415032d5ffe45e66be9efd21
7
- data.tar.gz: b2db49f8c1655d6ff9064749098b856eb4616430e91644309c95fbe32d402e630c6eb224f430a79f9f9b46a4998d80f6f11737524b73cc8524c4aaaa777072f6
6
+ metadata.gz: cb597e00191e3f4428c35f295041ba0b93181f7fb309f3bb2790d93641d1487a3d9f374acc260a20b93b3acc2987decbf0960266cd2518d2b006243e7dc46e4b
7
+ data.tar.gz: ac54cb79ad6d908e27fb2b0e26dd538a84db39fea929bdf72928587dcc4378764ed4a02fac458e6e0ef28fbb0ca6e3264cecfd740e4bd1d37b0744ba83675d76
data/SECURITY.md CHANGED
@@ -4,10 +4,19 @@ This lists out the implementation details of security-sensitive parts of ImageVi
4
4
 
5
5
  ## Protection of the URLs
6
6
 
7
- URLs are passed as Base64-encoded JSON. The JSON payload is signed using HMAC with SHA256. This should be
8
- sufficient to prevent too much probing. If this is a critical issue you need to put throttling in front of the application.
7
+ URLs are passed as Base64-encoded JSON. The HMAC signature is computed over the Base-64 encoded string,
8
+ so altering the string (with the intention to bust the cache) will invalidate the signature.
9
+
9
10
  For checking HMAC values `Rack::Utils.secure_compare` constant-time comparison is used.
10
11
 
12
+ ## Throttling still recommended
13
+
14
+ Throttling between the caching CDN/proxy is recommended.
15
+
16
+ ## Cache bypass protection for fuzzed paths
17
+
18
+ ImageVise accepts exactly 2 path components, and will return early if there are more
19
+
11
20
  ## Cache bypass protection for randomized query string params
12
21
 
13
22
  ImageVise defaults to using paths. If you have a way to forbid query strings on the fronting CDN
@@ -22,7 +31,7 @@ CDN cache because the query string params contain extra data.
22
31
 
23
32
  ## Protection for remote URLs from HTTP(s) origins
24
33
 
25
- Only URLs referring to permitted hosts are going to be permitted for fetching. If there are no host added,
34
+ Only URLs referring to permitted hosts are going to be permitted for fetching. If there are no hosts added,
26
35
  any remote URL is going to cause an exception. No special verification for whether the upstream must be HTTP
27
36
  or HTTPS is performed at this time.
28
37
 
@@ -33,6 +42,10 @@ The matching takes links (hard and soft) into account, and uses Ruby's `File.fnm
33
42
  is always expanded first using `File.expand_path`. The data is not read into ImageMagick from the original location,
34
43
  but gets copied into a tempfile first.
35
44
 
45
+ The path in to the file gets encoded in the image processing request and may be examined by the user, that will
46
+ disclose where the source image is stored on the server's filesystem. This might be an issue - if it is,
47
+ a customised version with a custom URL scheme should be used for the source URL.
48
+
36
49
  ## ImageMagick memory constraints
37
50
 
38
51
  ImageVise does not set RMagick limits by itself. You should
data/image_vise.gemspec CHANGED
@@ -2,16 +2,16 @@
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
3
  # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
- # stub: image_vise 0.1.5 ruby lib
5
+ # stub: image_vise 0.1.6 ruby lib
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "image_vise"
9
- s.version = "0.1.5"
9
+ s.version = "0.1.6"
10
10
 
11
11
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
12
12
  s.require_paths = ["lib"]
13
13
  s.authors = ["Julik Tarkhanov"]
14
- s.date = "2016-11-21"
14
+ s.date = "2016-12-07"
15
15
  s.description = "Image processing via URLs"
16
16
  s.email = "me@julik.nl"
17
17
  s.extra_rdoc_files = [
@@ -67,7 +67,8 @@ Gem::Specification.new do |s|
67
67
  "spec/waterside_magic_hour.jpg",
68
68
  "spec/waterside_magic_hour.psd",
69
69
  "spec/waterside_magic_hour_adobergb.jpg",
70
- "spec/waterside_magic_hour_gray.tif"
70
+ "spec/waterside_magic_hour_gray.tif",
71
+ "spec/waterside_magic_hour_transp.png"
71
72
  ]
72
73
  s.homepage = "https://github.com/WeTransfer/image_vise"
73
74
  s.licenses = ["MIT"]
@@ -12,9 +12,44 @@ class ImageVise::EllipseStencil
12
12
  private_constant :C_black
13
13
 
14
14
  def apply!(magick_image)
15
- # http://stackoverflow.com/a/13329959/153886
16
15
  width, height = magick_image.columns, magick_image.rows
17
16
 
17
+ # This is a bit involved. We need to do a manual composite. Here is what it entails.
18
+ #
19
+ # Given a premultiplied RGB image B, and a grayscale mask A, we need to do the following
20
+ # operation:
21
+ #
22
+ # BrBgBb / Ba * (Ba * A)
23
+ #
24
+ # Since ImageMagick works with unpremultiplied alphas, it is doable - but special care
25
+ # must be taken not to overmult or overdivide.
26
+ #
27
+ # To begin,generate a black and white image for the stencil
28
+ circle_img = Magick::Image.new(width, height)
29
+ draw_circle(circle_img, width, height)
30
+ mask = circle_img.negate
31
+
32
+ # At this stage the mask contains a B/W image of the circle, black outside, white inside.
33
+ # Retain the alpha of the original in a separate image
34
+ only_alpha = magick_image.copy
35
+ only_alpha.alpha(Magick::ExtractAlphaChannel)
36
+ mask.composite!(only_alpha, Magick::CenterGravity, Magick::MultiplyCompositeOp)
37
+
38
+ # With this composite op, enabling alpha on the destination image is
39
+ # not required - it will be enabled automatically.
40
+ # The CopyOpacityCompositeOp implies that we copy the grayscale version
41
+ # of the RGB channels as the alpha channel, so for some weird reason we need
42
+ # to disable the alpha on our mask image
43
+ mask.alpha(Magick::DeactivateAlphaChannel)
44
+ # And perform the operation (set gray(RGB) of mask as the A of magick_image)
45
+ magick_image.composite!(mask, Magick::CenterGravity, Magick::CopyOpacityCompositeOp)
46
+ ensure
47
+ [mask, only_alpha, circle_img].each do |maybe_image|
48
+ ImageVise.destroy(maybe_image)
49
+ end
50
+ end
51
+
52
+ def draw_circle(into_image, width, height)
18
53
  center_x = (width / 2.0)
19
54
  center_y = (height / 2.0)
20
55
  # Make sure all the edges are anti-aliased
@@ -24,19 +59,9 @@ class ImageVise::EllipseStencil
24
59
  gc = Magick::Draw.new
25
60
  gc.fill C_black
26
61
  gc.ellipse(center_x, center_y, radius_width, radius_height, deg_start=0, deg_end=360)
27
-
28
- circle_img = Magick::Image.new(width, height)
29
- gc.draw(circle_img)
30
-
31
- mask = circle_img.negate
32
- mask.matte = false
33
-
34
- magick_image.matte = true
35
- magick_image.composite!(mask, Magick::CenterGravity, Magick::CopyOpacityCompositeOp)
62
+ gc.draw(into_image)
36
63
  ensure
37
- [mask, gc, circle_img].each do |maybe_image|
38
- ImageVise.destroy(maybe_image)
39
- end
64
+ ImageVise.destroy(gc)
40
65
  end
41
66
 
42
67
  ImageVise.add_operator 'ellipse_stencil', self
data/lib/image_vise.rb CHANGED
@@ -8,7 +8,7 @@ require 'base64'
8
8
  require 'rack'
9
9
 
10
10
  class ImageVise
11
- VERSION = '0.1.5'
11
+ VERSION = '0.1.6'
12
12
  S_MUTEX = Mutex.new
13
13
  private_constant :S_MUTEX
14
14
 
@@ -7,4 +7,13 @@ describe ImageVise::EllipseStencil do
7
7
  stencil.apply!(image)
8
8
  examine_image(image, "circle-stencil")
9
9
  end
10
- end
10
+
11
+ it 'applies the circle stencil to a png with transparency' do
12
+ png_transparent_path = File.expand_path(__dir__ + '/../waterside_magic_hour_transp.png')
13
+ image = Magick::Image.read(png_transparent_path)[0]
14
+ stencil = described_class.new
15
+ stencil.apply!(image)
16
+ examine_image(image, "circle-stencil-transparent-bg")
17
+ end
18
+
19
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: image_vise
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.5
4
+ version: 0.1.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Julik Tarkhanov
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-11-21 00:00:00.000000000 Z
11
+ date: 2016-12-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: patron
@@ -311,6 +311,7 @@ files:
311
311
  - spec/waterside_magic_hour.psd
312
312
  - spec/waterside_magic_hour_adobergb.jpg
313
313
  - spec/waterside_magic_hour_gray.tif
314
+ - spec/waterside_magic_hour_transp.png
314
315
  homepage: https://github.com/WeTransfer/image_vise
315
316
  licenses:
316
317
  - MIT