jekyll_flexible_include 2.0.8 → 2.0.11
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/CHANGELOG.md +9 -0
- data/README.md +4 -1
- data/lib/flexible_include/version.rb +1 -1
- data/lib/flexible_include.rb +38 -13
- data/lib/jekyll_tag_helper.rb +5 -1
- data/spec/glob_spec.rb +20 -0
- data/spec/spec_helper.rb +16 -0
- data/spec/status_persistence.txt +3 -0
- metadata +9 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f3c2d80bab20b338d7635734938862e2ed99af858dc8f4967e7f0995fc0e5304
|
4
|
+
data.tar.gz: 3683ddcebf92f60dd12955e34eb64a910e8d51a16e46fa2b8c40fafb5b33b682
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 694653b9d9104793c425af90a2f93be38ee822c399bc60b1ce1bb012f70ea8af0268a8d4679353a4aab1f0dcd143b8738f58c74e094dc973b27081ac46690abd
|
7
|
+
data.tar.gz: 38b218be26c2bef642f13bf313150ef92676d214d5ade4b8333d936e47883f5b2a8b941b4a67f58427794706b68e976cd04847a1efba286dabe3d25eb914b3a9
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,12 @@
|
|
1
|
+
## 2.0.11 / 2022-04-15
|
2
|
+
* Added & => & to the escaped characters
|
3
|
+
|
4
|
+
## 2.0.10 / 2022-04-15
|
5
|
+
* Fixed nil pointer
|
6
|
+
|
7
|
+
## 2.0.9 / 2022-04-15
|
8
|
+
* Changed how path matching was implemented.
|
9
|
+
|
1
10
|
## 2.0.8 / 2022-04-14
|
2
11
|
* Added the ability to restrict arbitrary command execution, and specify the allowable directories to read from.
|
3
12
|
|
data/README.md
CHANGED
@@ -60,7 +60,7 @@ For example, the following restricts access to only the files within:
|
|
60
60
|
2. The directory tree rooted at `/var/files`.
|
61
61
|
3. The directory tree rooted at the expanded value of the `$work` environment variable.
|
62
62
|
```shell
|
63
|
-
export FLEXIBLE_INCLUDE_PATHS='
|
63
|
+
export FLEXIBLE_INCLUDE_PATHS='~/.*:$sites/.*:$work/.*'
|
64
64
|
```
|
65
65
|
Note that the above matches dot (hidden) files as well as regular files.
|
66
66
|
To just match visible files:
|
@@ -68,6 +68,9 @@ To just match visible files:
|
|
68
68
|
export FLEXIBLE_INCLUDE_PATHS='~/my_dir/**/*:/var/files/**/*:$work/**/*'
|
69
69
|
```
|
70
70
|
|
71
|
+
#### Note
|
72
|
+
The specified directories are traversed when the plugin starts, and the filenames are stored in memory. Directories with lots of files might take a noticable amount to time to enumerate the files.
|
73
|
+
|
71
74
|
|
72
75
|
### Restricting Arbitrary Processes
|
73
76
|
By default, `flexible_include` can execute any command. You can disable that by setting the environment variable `DISABLE_FLEXIBLE_INCLUDE` to any non-empty value.
|
data/lib/flexible_include.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "benchmark"
|
3
4
|
require "jekyll"
|
4
5
|
require "jekyll_plugin_logger"
|
5
6
|
require "securerandom"
|
@@ -13,6 +14,36 @@ end
|
|
13
14
|
class FlexibleInclude < Liquid::Tag
|
14
15
|
FlexibleIncludeError = Class.new(Liquid::Error)
|
15
16
|
|
17
|
+
@read_regexes = nil
|
18
|
+
|
19
|
+
def self.normalize_path(path)
|
20
|
+
JekyllTagHelper.expand_env(path)
|
21
|
+
.gsub("~", Dir.home)
|
22
|
+
end
|
23
|
+
|
24
|
+
# If FLEXIBLE_INCLUDE_PATHS='~/lib/.*:.*:$WORK/.*'
|
25
|
+
# Then @read_regexes will be set to regexes of ["/home/my_user_id/lib/.*", "/pwd/.*", "/work/envar/path/.*"]
|
26
|
+
def self.security_check
|
27
|
+
@execution_denied = ENV['DISABLE_FLEXIBLE_INCLUDE']
|
28
|
+
|
29
|
+
unless @read_regexes
|
30
|
+
flexible_include_paths = ENV['FLEXIBLE_INCLUDE_PATHS']
|
31
|
+
read_paths = normalize_path(flexible_include_paths) if flexible_include_paths
|
32
|
+
if read_paths
|
33
|
+
@read_regexes = read_paths.split(":").map do |path|
|
34
|
+
abs_path = path.start_with?('/') ? path : (Pathname.new(Dir.pwd) + path).to_s
|
35
|
+
Regexp.new(abs_path)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.access_allowed(path)
|
42
|
+
return true unless @read_regexes
|
43
|
+
|
44
|
+
@read_regexes.find { |regex| regex.match(normalize_path(path)) }
|
45
|
+
end
|
46
|
+
|
16
47
|
# @param tag_name [String] the name of the tag, which we already know.
|
17
48
|
# @param markup [String] the arguments from the tag, as a single string.
|
18
49
|
# @param parse_context [Liquid::ParseContext] hash that stores Liquid options.
|
@@ -25,12 +56,7 @@ class FlexibleInclude < Liquid::Tag
|
|
25
56
|
@logger = PluginMetaLogger.instance.new_logger(self, PluginMetaLogger.instance.config)
|
26
57
|
@helper = JekyllTagHelper.new(tag_name, markup, @logger)
|
27
58
|
|
28
|
-
|
29
|
-
|
30
|
-
# If FLEXIBLE_INCLUDE_PATHS='~/lib/**/*:*/**/*'
|
31
|
-
# Then @read_paths will be set to ["~/lib/**/*", "*/**/*"]
|
32
|
-
@read_paths = ENV['FLEXIBLE_INCLUDE_PATHS']
|
33
|
-
@read_paths = @read_paths.split(":").map { |x| JekyllTagHelper.expand_env x } if @read_paths
|
59
|
+
self.class.security_check
|
34
60
|
end
|
35
61
|
|
36
62
|
# @param liquid_context [Liquid::Context]
|
@@ -43,6 +69,7 @@ class FlexibleInclude < Liquid::Tag
|
|
43
69
|
@label_specified = @label
|
44
70
|
@copy_button = @helper.parameter_specified? "copyButton"
|
45
71
|
@pre = @copy_button || @dark || @download || @label_specified || @helper.parameter_specified?("pre") # Download or label implies pre
|
72
|
+
|
46
73
|
filename = @helper.parameter_specified? "file"
|
47
74
|
filename ||= @helper.params.first # Do this after all options have been checked for
|
48
75
|
@label ||= filename
|
@@ -55,16 +82,19 @@ class FlexibleInclude < Liquid::Tag
|
|
55
82
|
path = JekyllTagHelper.expand_env(filename)
|
56
83
|
case path
|
57
84
|
when /\A\// # Absolute path
|
58
|
-
return denied("Access to #{path} denied by FLEXIBLE_INCLUDE_PATHS value.") unless access_allowed(path)
|
85
|
+
return denied("Access to #{path} denied by FLEXIBLE_INCLUDE_PATHS value.") unless self.class.access_allowed(path)
|
86
|
+
|
59
87
|
@logger.debug { "Absolute path=#{path}, filename=#{filename}" }
|
60
88
|
when /\A~/ # Relative path to user's home directory
|
61
|
-
return denied("Access to #{path} denied by FLEXIBLE_INCLUDE_PATHS value.") unless access_allowed(path)
|
89
|
+
return denied("Access to #{path} denied by FLEXIBLE_INCLUDE_PATHS value.") unless self.class.access_allowed(path)
|
90
|
+
|
62
91
|
@logger.debug { "User home start filename=#{filename}, path=#{path}" }
|
63
92
|
filename.slice! "~/"
|
64
93
|
path = File.join(ENV['HOME'], filename)
|
65
94
|
@logger.debug { "User home end filename=#{filename}, path=#{path}" }
|
66
95
|
when /\A!/ # Run command and return response
|
67
96
|
return denied("Arbitrary command execution denied by DISABLE_FLEXIBLE_INCLUDE value.") if @execution_denied
|
97
|
+
|
68
98
|
filename = JekyllTagHelper.remove_quotes(@helper.argv.first) if @helper.argv.first
|
69
99
|
filename.slice! "!"
|
70
100
|
contents = run(filename)
|
@@ -82,11 +112,6 @@ class FlexibleInclude < Liquid::Tag
|
|
82
112
|
|
83
113
|
private
|
84
114
|
|
85
|
-
def access_allowed(path)
|
86
|
-
return true unless @read_paths
|
87
|
-
Dir.glob(@read_paths).find { |x| x == path }
|
88
|
-
end
|
89
|
-
|
90
115
|
def denied(msg)
|
91
116
|
@logger.error("#{@helper.page.path} - #{msg}")
|
92
117
|
"<p style='color: white; background-color: red; padding: 2pt 1em 2pt 1em;'>#{msg}</p>"
|
data/lib/jekyll_tag_helper.rb
CHANGED
@@ -1,12 +1,16 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "shellwords"
|
4
|
+
require 'key_value_parser'
|
4
5
|
|
5
6
|
class JekyllTagHelper
|
6
7
|
attr_reader :argv, :liquid_context, :logger, :params, :tag_name
|
7
8
|
|
8
9
|
def self.escape_html(string)
|
9
|
-
string.gsub("
|
10
|
+
string.gsub("&", "&")
|
11
|
+
.gsub("{", "{")
|
12
|
+
.gsub("}", "}")
|
13
|
+
.gsub("<", "<")
|
10
14
|
end
|
11
15
|
|
12
16
|
# Expand a environment variable reference
|
data/spec/glob_spec.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "../lib/flexible_include"
|
4
|
+
|
5
|
+
RSpec.describe(FlexibleInclude) do
|
6
|
+
it "controls access to files" do
|
7
|
+
ENV['FLEXIBLE_INCLUDE_PATHS'] = '~/.*:spec/.*'
|
8
|
+
|
9
|
+
FlexibleInclude.send(:new, 'my_tag', "", Liquid::ParseContext.new)
|
10
|
+
FlexibleInclude.security_check
|
11
|
+
expect(FlexibleInclude.access_allowed(__FILE__)).to be_truthy
|
12
|
+
|
13
|
+
expect(FlexibleInclude.access_allowed("~/.mem_settings.yaml")).to be_truthy
|
14
|
+
|
15
|
+
home_file = JekyllTagHelper.expand_env("$HOME/.mem_settings.yaml")
|
16
|
+
expect(FlexibleInclude.access_allowed(home_file)).to be_truthy
|
17
|
+
|
18
|
+
expect(FlexibleInclude.access_allowed('/asdf')).to be_falsey
|
19
|
+
end
|
20
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "jekyll"
|
4
|
+
|
5
|
+
require_relative "../lib/flexible_include"
|
6
|
+
|
7
|
+
Jekyll.logger.log_level = :info
|
8
|
+
|
9
|
+
RSpec.configure do |config|
|
10
|
+
config.filter_run :focus
|
11
|
+
config.order = "random"
|
12
|
+
config.run_all_when_everything_filtered = true
|
13
|
+
|
14
|
+
# See https://relishapp.com/rspec/rspec-core/docs/command-line/only-failures
|
15
|
+
config.example_status_persistence_file_path = "spec/status_persistence.txt"
|
16
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jekyll_flexible_include
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.
|
4
|
+
version: 2.0.11
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mike Slinn
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: exe
|
12
12
|
cert_chain: []
|
13
|
-
date: 2022-04-
|
13
|
+
date: 2022-04-15 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: jekyll
|
@@ -88,6 +88,9 @@ files:
|
|
88
88
|
- lib/flexible_include.rb
|
89
89
|
- lib/flexible_include/version.rb
|
90
90
|
- lib/jekyll_tag_helper.rb
|
91
|
+
- spec/glob_spec.rb
|
92
|
+
- spec/spec_helper.rb
|
93
|
+
- spec/status_persistence.txt
|
91
94
|
homepage: https://www.mslinn.com/blog/2020/10/03/jekyll-plugins.html#flexibleInclude
|
92
95
|
licenses:
|
93
96
|
- MIT
|
@@ -120,4 +123,7 @@ signing_key:
|
|
120
123
|
specification_version: 4
|
121
124
|
summary: Jekyll plugin supports various ways to include content into the generated
|
122
125
|
site.
|
123
|
-
test_files:
|
126
|
+
test_files:
|
127
|
+
- spec/glob_spec.rb
|
128
|
+
- spec/spec_helper.rb
|
129
|
+
- spec/status_persistence.txt
|