jekyll-content-security-policy-generator 1.0.0 → 1.6.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +6 -0
- data/LICENSE +21 -0
- data/Makefile +36 -0
- data/README.md +37 -0
- data/jekyll-content-security-policy-generator.gemspec +21 -0
- data/lib/jekyll-content-security-policy-generator.rb +5 -0
- data/lib/jekyll-content-security-policy-generator/hook.rb +268 -0
- data/lib/jekyll-content-security-policy-generator/version.rb +3 -0
- metadata +34 -25
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 666962f27c797d8df3b4d88d7de3cfabea8c3e5750fed324fe29682ff28ac980
|
4
|
+
data.tar.gz: 842ca42c7328fe877dcc67f087917176de8ca34fd84e3c7371ce2d0b117aa3c6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f0ccb7182e536d153ffc41fb6103ad2857631d3c9f47e2ff2ae3ecde0a3b7eb4790e17b160f59ec341b608cef48db63bccde40e4a135602de178c4631b67d303
|
7
|
+
data.tar.gz: 7dac28f93a0f8757a9d78d0c37a7e7d41b1902651020965ceca6092b6efea5d1f84f028c59b21b3e88668427db097e186c862b66faf6a610b169b5aed35c5fa9
|
data/.gitignore
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2021 strongscot <mail@strongscot.com> (https://strongscot.com
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/Makefile
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
CWD := $(shell pwd)
|
2
|
+
|
3
|
+
.PHONY: all
|
4
|
+
all: build
|
5
|
+
|
6
|
+
.PHONY: start
|
7
|
+
start:
|
8
|
+
@bundle exec jekyll serve --verbose
|
9
|
+
|
10
|
+
.PHONY: build
|
11
|
+
build: clean
|
12
|
+
@gem build *.gemspec
|
13
|
+
@echo ::: BUILD :::
|
14
|
+
|
15
|
+
.PHONY: install
|
16
|
+
install: deps
|
17
|
+
-@rm -f Gemfile.lock &>/dev/null || true
|
18
|
+
@bundle install
|
19
|
+
@echo ::: INSTALL :::
|
20
|
+
|
21
|
+
.PHONY: push
|
22
|
+
push: build
|
23
|
+
@gem push *.gem
|
24
|
+
@echo ::: PUSH :::
|
25
|
+
|
26
|
+
.PHONY: clean
|
27
|
+
clean:
|
28
|
+
-@rm -rf *.gem &>/dev/null || true
|
29
|
+
@echo ::: CLEAN :::
|
30
|
+
|
31
|
+
.PHONY: deps
|
32
|
+
deps: bundle
|
33
|
+
@echo ::: DEPS :::
|
34
|
+
.PHONY: bundle
|
35
|
+
bundle:
|
36
|
+
@if ! o=$$(which bundle); then gem install bundle jekyll; fi
|
data/README.md
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
# jekyll-content-security-policy-generator Plugin
|
2
|
+
|
3
|
+
This Jekyll plugin automatically builds an HTML content-security-policy for a Jekyll site. The plugin
|
4
|
+
will scan ```.html``` files generated by Jekyll and attempt to locate images, styles, scripts, frames etc and build a
|
5
|
+
content security policy HTML meta tag. The script will also generate SHA256 hashes for inline scripts and styles. If
|
6
|
+
the script finds elements with style attributes ```<div style="color: red"></div>```, the script will extract the style
|
7
|
+
information and build a style element to which will also pass through the content security policy generation.
|
8
|
+
|
9
|
+
## Goal
|
10
|
+
|
11
|
+
To speed up development of Jekyll based sites whilst also helping to generate secure HTMl files protected from XSS.
|
12
|
+
|
13
|
+
## Features
|
14
|
+
|
15
|
+
* Scans for ```.html``` files generated by Jekyll.
|
16
|
+
* Finds inline scripts such as ```<script>alert("Hello World!");</script>``` and generates an SHA256 hash.
|
17
|
+
* Finds inline styles such as ```<style>.hello { color: "red"; }</style>``` and generates an SHA256 hash.
|
18
|
+
* Creates or reuses an HTTP meta tag for the content security policy.
|
19
|
+
* Finds all images, styles, scripts and frames with external URLs and builds CSP.
|
20
|
+
* Converts style attributes into ```<style>``` elements.
|
21
|
+
|
22
|
+
## Installation
|
23
|
+
|
24
|
+
Install the gem:
|
25
|
+
|
26
|
+
```gem install jekyll-content-security-policy-generator```
|
27
|
+
|
28
|
+
Then add this to your _config.yml:
|
29
|
+
|
30
|
+
```
|
31
|
+
plugins:
|
32
|
+
- jekyll-content-security-policy-generator
|
33
|
+
```
|
34
|
+
|
35
|
+
## Support
|
36
|
+
|
37
|
+
https://strongscot.com
|
@@ -0,0 +1,21 @@
|
|
1
|
+
lib = File.expand_path("../lib", __FILE__)
|
2
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
|
+
require "jekyll-content-security-policy-generator/version"
|
4
|
+
Gem::Specification.new do |spec|
|
5
|
+
spec.name = "jekyll-content-security-policy-generator"
|
6
|
+
spec.summary = "Helps generate a content security policy."
|
7
|
+
spec.description = "Helps generate a content security policy. Locates inline scripts, images, frames etc."
|
8
|
+
spec.version = JekyllContentSecurityPolicyGenerator::VERSION
|
9
|
+
spec.authors = ["strongscot"]
|
10
|
+
spec.email = ["mail@strongscot.com"]
|
11
|
+
spec.homepage = "https://github.com/strongscot/jekyll-content-security-policy-generator"
|
12
|
+
spec.licenses = ["MIT"]
|
13
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r!^(test|spec|features)/!) }
|
14
|
+
spec.require_paths = ["lib"]
|
15
|
+
spec.add_dependency "jekyll"
|
16
|
+
spec.add_dependency "digest"
|
17
|
+
spec.add_dependency "nokogiri", ">= 1.11"
|
18
|
+
spec.add_development_dependency "rake"
|
19
|
+
spec.add_development_dependency "rspec"
|
20
|
+
spec.add_development_dependency "rubocop"
|
21
|
+
end
|
@@ -0,0 +1,268 @@
|
|
1
|
+
require 'jekyll'
|
2
|
+
require 'nokogiri'
|
3
|
+
require 'digest'
|
4
|
+
require 'open-uri'
|
5
|
+
|
6
|
+
##
|
7
|
+
# Provides the ability to generate a content security policy for inline scripts and styles.
|
8
|
+
# Will reuse an existing CSP or generate a new one and insert in HEAD.
|
9
|
+
module Jekyll
|
10
|
+
|
11
|
+
module JekyllContentSecurityPolicyGenerator
|
12
|
+
|
13
|
+
##
|
14
|
+
# Provides the ability to generate a content security policy for inline scripts and styles.
|
15
|
+
# Will reuse an existing CSP or generate a new one and insert in HEAD.
|
16
|
+
class ContentSecurityPolicyGenerator
|
17
|
+
def initialize(document_html)
|
18
|
+
@document_html = document_html
|
19
|
+
@nokogiri = Nokogiri::HTML(document_html)
|
20
|
+
|
21
|
+
@csp_frame_src = ['\'self\'']
|
22
|
+
@csp_image_src = ['\'self\'']
|
23
|
+
@csp_style_src = ['\'self\'']
|
24
|
+
@csp_script_src = ['\'self\'']
|
25
|
+
@csp_unknown = []
|
26
|
+
end
|
27
|
+
|
28
|
+
##
|
29
|
+
# Creates an HTML content security policy meta tag.
|
30
|
+
def generate_convert_security_policy_meta_tag
|
31
|
+
meta_content = ""
|
32
|
+
|
33
|
+
if @csp_frame_src.length > 0
|
34
|
+
meta_content += "frame-src " + @csp_frame_src.join(' ') + '; '
|
35
|
+
end
|
36
|
+
|
37
|
+
if @csp_image_src.length > 0
|
38
|
+
meta_content += "img-src " + @csp_image_src.join(' ') + '; '
|
39
|
+
end
|
40
|
+
|
41
|
+
if @csp_style_src.length > 0
|
42
|
+
meta_content += "style-src " + @csp_style_src.join(' ') + '; '
|
43
|
+
end
|
44
|
+
|
45
|
+
if @csp_script_src.length > 0
|
46
|
+
meta_content += "script-src " + @csp_script_src.join(' ') + '; '
|
47
|
+
end
|
48
|
+
|
49
|
+
if @csp_unknown.length > 0
|
50
|
+
@csp_unknown.each do |find|
|
51
|
+
find_name = find[0]
|
52
|
+
find = find.drop(1)
|
53
|
+
meta_content += find_name + " " + find.join(' ') + '; '
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
if @nokogiri.at("head")
|
58
|
+
Jekyll.logger.info "Generated content security policy, inserted in HEAD."
|
59
|
+
@nokogiri.at("head") << "<meta http-equiv=\"Content-Security-Policy\" content=\"" + meta_content + "\">"
|
60
|
+
elsif @nokogiri.at("body")
|
61
|
+
Jekyll.logger.info "Generated content security policy, inserted in BODY."
|
62
|
+
@nokogiri.at("body") << "<meta http-equiv=\"Content-Security-Policy\" content=\"" + meta_content + "\">"
|
63
|
+
else
|
64
|
+
Jekyll.logger.error "Generated content security policy but found no-where to insert it."
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
68
|
+
|
69
|
+
##
|
70
|
+
# Parse an existing content security policy meta tag
|
71
|
+
def parse_existing_meta_element()
|
72
|
+
csp = @nokogiri.at('meta[http-equiv="Content-Security-Policy"]')
|
73
|
+
|
74
|
+
if csp
|
75
|
+
content = csp.attr('content')
|
76
|
+
content = content.strip! || content
|
77
|
+
policies = content.split(';')
|
78
|
+
|
79
|
+
policies.each do |policy|
|
80
|
+
policy = policy.strip! || policy
|
81
|
+
|
82
|
+
if policy.include? ' '
|
83
|
+
policy_parts = policy.split(' ')
|
84
|
+
|
85
|
+
if policy_parts[0] == 'script-src'
|
86
|
+
@csp_script_src.concat(policy_parts.drop(1))
|
87
|
+
@csp_script_src = @csp_script_src.uniq
|
88
|
+
elsif policy_parts[0] == 'style-src'
|
89
|
+
@csp_style_src.concat(policy_parts.drop(1))
|
90
|
+
@csp_style_src = @csp_style_src.uniq
|
91
|
+
elsif policy_parts[0] == 'image-src'
|
92
|
+
@csp_image_src.concat(policy_parts.drop(1))
|
93
|
+
@csp_image_src = @csp_image_src.uniq
|
94
|
+
elsif policy_parts[0] == 'frame-src'
|
95
|
+
@csp_frame_src.concat(policy_parts.drop(1))
|
96
|
+
@csp_frame_src = @csp_frame_src.uniq
|
97
|
+
else
|
98
|
+
@csp_unknown.concat([policy_parts])
|
99
|
+
end
|
100
|
+
|
101
|
+
else
|
102
|
+
Jekyll.logger.warn "Incorrect existing content security policy meta tag found, skipping."
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
##
|
109
|
+
# This function converts elements with style="color:red" attributes into inline styles
|
110
|
+
def convert_all_inline_styles_attributes
|
111
|
+
@nokogiri.css('*').each do |find|
|
112
|
+
find_src = find.attr('style')
|
113
|
+
|
114
|
+
if find_src
|
115
|
+
if find.attr('id')
|
116
|
+
element_id = find.attr('id')
|
117
|
+
else
|
118
|
+
element_id = Digest::MD5.hexdigest find_src + "#{Random.rand(11)}"
|
119
|
+
find["id"] = element_id
|
120
|
+
end
|
121
|
+
|
122
|
+
new_element = "<style>#" + element_id + " { " + find_src + " } </style>"
|
123
|
+
find.remove_attribute("style")
|
124
|
+
|
125
|
+
if @nokogiri.at('head')
|
126
|
+
@nokogiri.at('head') << new_element
|
127
|
+
Jekyll.logger.info'Converting style attribute to inline style, inserted into HEAD.'
|
128
|
+
else
|
129
|
+
if @nokogiri.at('body')
|
130
|
+
@nokogiri.at('body') << new_element
|
131
|
+
Jekyll.logger.info'Converting style attribute to inline style, inserted into BODY.'
|
132
|
+
else
|
133
|
+
Jekyll.logger.warn'Unable to convert style attribute to inline style, no HEAD or BODY found.'
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
##
|
141
|
+
# Find all images
|
142
|
+
def find_images
|
143
|
+
@nokogiri.css('img').each do |find|
|
144
|
+
find_src = find.attr('src')
|
145
|
+
|
146
|
+
if find_src.start_with?('http', 'https')
|
147
|
+
@csp_image_src.push find_src.match(/(.*\/)+(.*$)/)[1]
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
##
|
153
|
+
# Find all scripts
|
154
|
+
def find_scripts
|
155
|
+
@nokogiri.css('script').each do |find|
|
156
|
+
if find.attr('src')
|
157
|
+
find_src = find.attr('src')
|
158
|
+
|
159
|
+
if find_src.start_with?('http', 'https')
|
160
|
+
@csp_script_src.push find_src.match(/(.*\/)+(.*$)/)[1]
|
161
|
+
end
|
162
|
+
|
163
|
+
else
|
164
|
+
@csp_script_src.push self.generate_sha256_content_hash find.content
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
##
|
170
|
+
# Find all stylesheets
|
171
|
+
def find_styles
|
172
|
+
@nokogiri.css('style').each do |find|
|
173
|
+
if find.attr('src')
|
174
|
+
find_src = find.attr('src')
|
175
|
+
|
176
|
+
if find_src.start_with?('http', 'https')
|
177
|
+
@csp_style_src.push find_src.match(/(.*\/)+(.*$)/)[1]
|
178
|
+
end
|
179
|
+
|
180
|
+
else
|
181
|
+
@csp_style_src.push self.generate_sha256_content_hash find.content
|
182
|
+
end
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
##
|
187
|
+
# Find all iframes
|
188
|
+
def find_iframes
|
189
|
+
@nokogiri.css('iframe').each do |find|
|
190
|
+
find_src = find.attr('src')
|
191
|
+
|
192
|
+
if find_src.start_with?('http', 'https')
|
193
|
+
@csp_frame_src.push find_src.match(/(.*\/)+(.*$)/)[1]
|
194
|
+
end
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
##
|
199
|
+
# Generate a content hash
|
200
|
+
def generate_sha256_content_hash(content)
|
201
|
+
hash = Digest::SHA2.base64digest content
|
202
|
+
"'sha256-#{hash}'"
|
203
|
+
end
|
204
|
+
|
205
|
+
##
|
206
|
+
# Builds an HTML meta tag based on the found inline scripts and style hashes
|
207
|
+
def run
|
208
|
+
self.parse_existing_meta_element
|
209
|
+
|
210
|
+
self.convert_all_inline_styles_attributes
|
211
|
+
|
212
|
+
# Find elements in document
|
213
|
+
self.find_images
|
214
|
+
self.find_styles
|
215
|
+
self.find_scripts
|
216
|
+
self.find_iframes
|
217
|
+
|
218
|
+
self.generate_convert_security_policy_meta_tag
|
219
|
+
|
220
|
+
@nokogiri.to_html
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
224
|
+
##
|
225
|
+
# Write the file contents back.
|
226
|
+
def write_file_contents(dest, content)
|
227
|
+
FileUtils.mkdir_p(File.dirname(dest))
|
228
|
+
File.open(dest, 'w') do |f|
|
229
|
+
f.write(content)
|
230
|
+
end
|
231
|
+
end
|
232
|
+
|
233
|
+
##
|
234
|
+
# Write document contents
|
235
|
+
def write(dest)
|
236
|
+
dest_path = destination(dest)
|
237
|
+
if File.extname(dest_path) == ".html"
|
238
|
+
content_security_policy_generator = ContentSecurityPolicyGenerator.new output
|
239
|
+
output = content_security_policy_generator.run
|
240
|
+
end
|
241
|
+
|
242
|
+
write_file_contents(dest_path, output)
|
243
|
+
end
|
244
|
+
|
245
|
+
end
|
246
|
+
|
247
|
+
class Document
|
248
|
+
include JekyllContentSecurityPolicyGenerator
|
249
|
+
|
250
|
+
##
|
251
|
+
# Write document contents
|
252
|
+
def write(dest)
|
253
|
+
super dest
|
254
|
+
trigger_hooks(:post_write)
|
255
|
+
end
|
256
|
+
end
|
257
|
+
|
258
|
+
class Page
|
259
|
+
include JekyllContentSecurityPolicyGenerator
|
260
|
+
|
261
|
+
##
|
262
|
+
# Write page contents
|
263
|
+
def write(dest)
|
264
|
+
super dest
|
265
|
+
Jekyll::Hooks.trigger hook_owner, :post_write, self
|
266
|
+
end
|
267
|
+
end
|
268
|
+
end
|
metadata
CHANGED
@@ -1,31 +1,31 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jekyll-content-security-policy-generator
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.6.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- strongscot
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-04-
|
11
|
+
date: 2021-04-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: jekyll
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
17
|
+
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
19
|
+
version: '0'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - "
|
24
|
+
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
26
|
+
version: '0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
28
|
+
name: digest
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - ">="
|
@@ -39,68 +39,77 @@ dependencies:
|
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
42
|
+
name: nokogiri
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - ">="
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: '
|
47
|
+
version: '1.11'
|
48
48
|
type: :runtime
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: '
|
54
|
+
version: '1.11'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: rake
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- - "
|
59
|
+
- - ">="
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: '
|
61
|
+
version: '0'
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
|
-
- - "
|
66
|
+
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version: '
|
68
|
+
version: '0'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: rspec
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
|
-
- - "
|
73
|
+
- - ">="
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version: '
|
75
|
+
version: '0'
|
76
76
|
type: :development
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
|
-
- - "
|
80
|
+
- - ">="
|
81
81
|
- !ruby/object:Gem::Version
|
82
|
-
version: '
|
82
|
+
version: '0'
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
84
|
name: rubocop
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
|
-
- - "
|
87
|
+
- - ">="
|
88
88
|
- !ruby/object:Gem::Version
|
89
|
-
version: '0
|
89
|
+
version: '0'
|
90
90
|
type: :development
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
|
-
- - "
|
94
|
+
- - ">="
|
95
95
|
- !ruby/object:Gem::Version
|
96
|
-
version: '0
|
97
|
-
description: Helps generate a content security policy
|
96
|
+
version: '0'
|
97
|
+
description: Helps generate a content security policy. Locates inline scripts, images,
|
98
|
+
frames etc.
|
98
99
|
email:
|
99
100
|
- mail@strongscot.com
|
100
101
|
executables: []
|
101
102
|
extensions: []
|
102
103
|
extra_rdoc_files: []
|
103
|
-
files:
|
104
|
+
files:
|
105
|
+
- ".gitignore"
|
106
|
+
- LICENSE
|
107
|
+
- Makefile
|
108
|
+
- README.md
|
109
|
+
- jekyll-content-security-policy-generator.gemspec
|
110
|
+
- lib/jekyll-content-security-policy-generator.rb
|
111
|
+
- lib/jekyll-content-security-policy-generator/hook.rb
|
112
|
+
- lib/jekyll-content-security-policy-generator/version.rb
|
104
113
|
homepage: https://github.com/strongscot/jekyll-content-security-policy-generator
|
105
114
|
licenses:
|
106
115
|
- MIT
|
@@ -123,5 +132,5 @@ requirements: []
|
|
123
132
|
rubygems_version: 3.0.3
|
124
133
|
signing_key:
|
125
134
|
specification_version: 4
|
126
|
-
summary: Helps generate a content security policy
|
135
|
+
summary: Helps generate a content security policy.
|
127
136
|
test_files: []
|