jekyll_flexible_include 2.0.7 → 2.0.8

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 38eeb054b62e4c999437208ce95cb7291174167839d344db3df48670954b32ef
4
- data.tar.gz: '0962b93b74c28d6521c655cea29f0646c11051d8f3ddaf690618b9ed91e7276b'
3
+ metadata.gz: 64eb6af1f283738c8152205359b97b42081c571cc8cd16dc30d263108e21aba0
4
+ data.tar.gz: 87b46d76f2f43022c458fff1dc4f3ea5523ccc0afe29ca7eb4c6c7f41554427d
5
5
  SHA512:
6
- metadata.gz: 2e3ec9a8c269bda135c245a54b995abd6f2229658190a5f89e1bad97372e85f4a37af7c7227cbaa8b518f1ae90a6b70ecc3f0f9c881859329fdf241123047ca6
7
- data.tar.gz: b8f6497ee5505ac0f43f28a6c9d0bb639be7b7c2bc712375f8ae6774522ccaae6ecd0108be1bdcb0d72cb1656e0b1a268ffa52d3feb675722295aca6c698961d
6
+ metadata.gz: 143e9c8cc4e9d5a109ce41020e46c4c8c0366e9c30bf4201263767e5276818ca32293430d6464afbea3a1925c90256219394dcf77b57735dd49ff3efa42dd940
7
+ data.tar.gz: 2dd1b9df7fa2936231ef0bb85ef8ecb87fc7afa9d519a9fda3dd9167869b13671c9ece3c13b1576ac11d9c0abc1adc498e7bc66fd5fb3fdb9634e417666119a6
data/CHANGELOG.md CHANGED
@@ -1,3 +1,6 @@
1
+ ## 2.0.8 / 2022-04-14
2
+ * Added the ability to restrict arbitrary command execution, and specify the allowable directories to read from.
3
+
1
4
  ## 2.0.7 / 2022-04-14
2
5
  * Added `file=` option, so the included file or process is better defined. This option is not required; the file/process can be specified without it as before.
3
6
  * Documented `data-lt-active="false"`.
data/README.md CHANGED
@@ -48,6 +48,34 @@ The following options imply `pre`:
48
48
  * `label` specifies that an automatically generated label be placed above the contents. There is no need to specify this option if `download` or `copy_button` options are provided.
49
49
  * `label="blah blah"` specifies a label for the contents; this value overrides the default label. The value can be enclosed in single or double quotes.
50
50
 
51
+ ### Restricting Directory Access
52
+ By default, `flexible_include` can read from all directories according to the permissions of the user account that launched the `jekyll` process.
53
+ For security-conscience environments, the accessible paths can be restricted.
54
+
55
+ Defining an environment variable called `FLEXIBLE_INCLUDE_PATHS` prior to launching Jekyll will restrict the paths that `flexible_include` will be able to read from.
56
+ This environment variable consists of a colon-delimited set of
57
+ [file and directory glob patterns](https://docs.ruby-lang.org/en/2.7.0/Dir.html#method-c-glob).
58
+ For example, the following restricts access to only the files within:
59
+ 1. The `~/my_dir` directory tree of the account of the user that launched Jekyll.
60
+ 2. The directory tree rooted at `/var/files`.
61
+ 3. The directory tree rooted at the expanded value of the `$work` environment variable.
62
+ ```shell
63
+ export FLEXIBLE_INCLUDE_PATHS='~/my_dir/**/{*,.*}:/var/files/**/{*,.*}:$work/**/{*,.*}'
64
+ ```
65
+ Note that the above matches dot (hidden) files as well as regular files.
66
+ To just match visible files:
67
+ ```shell
68
+ export FLEXIBLE_INCLUDE_PATHS='~/my_dir/**/*:/var/files/**/*:$work/**/*'
69
+ ```
70
+
71
+
72
+ ### Restricting Arbitrary Processes
73
+ 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.
74
+ ```shell
75
+ export DISABLE_FLEXIBLE_INCLUDE=true
76
+ ```
77
+
78
+ If a potential command execution is intercepted, a big red message will appear on the generated web page that says `Arbitrary command execution denied by DISABLE_FLEXIBLE_INCLUDE value.`, and a red error message will be logged on the console that says something like: `ERROR FlexibleInclude: _posts/2020/2020-10-03-jekyll-plugins.html - Arbitrary command execution denied by DISABLE_FLEXIBLE_INCLUDE value.`
51
79
 
52
80
 
53
81
  ## Installation
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module JekyllFlexibleIncludePluginVersion
4
- VERSION = "2.0.7"
4
+ VERSION = "2.0.8"
5
5
  end
@@ -24,6 +24,13 @@ class FlexibleInclude < Liquid::Tag
24
24
  super
25
25
  @logger = PluginMetaLogger.instance.new_logger(self, PluginMetaLogger.instance.config)
26
26
  @helper = JekyllTagHelper.new(tag_name, markup, @logger)
27
+
28
+ @execution_denied = ENV['DISABLE_FLEXIBLE_INCLUDE']
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
27
34
  end
28
35
 
29
36
  # @param liquid_context [Liquid::Context]
@@ -48,13 +55,16 @@ class FlexibleInclude < Liquid::Tag
48
55
  path = JekyllTagHelper.expand_env(filename)
49
56
  case path
50
57
  when /\A\// # Absolute path
58
+ return denied("Access to #{path} denied by FLEXIBLE_INCLUDE_PATHS value.") unless access_allowed(path)
51
59
  @logger.debug { "Absolute path=#{path}, filename=#{filename}" }
52
60
  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)
53
62
  @logger.debug { "User home start filename=#{filename}, path=#{path}" }
54
63
  filename.slice! "~/"
55
64
  path = File.join(ENV['HOME'], filename)
56
65
  @logger.debug { "User home end filename=#{filename}, path=#{path}" }
57
66
  when /\A!/ # Run command and return response
67
+ return denied("Arbitrary command execution denied by DISABLE_FLEXIBLE_INCLUDE value.") if @execution_denied
58
68
  filename = JekyllTagHelper.remove_quotes(@helper.argv.first) if @helper.argv.first
59
69
  filename.slice! "!"
60
70
  contents = run(filename)
@@ -72,6 +82,16 @@ class FlexibleInclude < Liquid::Tag
72
82
 
73
83
  private
74
84
 
85
+ def access_allowed(path)
86
+ return true unless @read_paths
87
+ Dir.glob(@read_paths).find { |x| x == path }
88
+ end
89
+
90
+ def denied(msg)
91
+ @logger.error("#{@helper.page.path} - #{msg}")
92
+ "<p style='color: white; background-color: red; padding: 2pt 1em 2pt 1em;'>#{msg}</p>"
93
+ end
94
+
75
95
  def read_file(file)
76
96
  File.read(file)
77
97
  end
@@ -9,7 +9,7 @@ class JekyllTagHelper
9
9
  string.gsub("{", "&#123;").gsub("}", "&#125;").gsub("<", "&lt;")
10
10
  end
11
11
 
12
- # Expand environment variable references
12
+ # Expand a environment variable reference
13
13
  def self.expand_env(str)
14
14
  str.gsub(/\$([a-zA-Z_][a-zA-Z0-9_]*)|\${\g<1>}|%\g<1>%/) { ENV[Regexp.last_match(1)] }
15
15
  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.7
4
+ version: 2.0.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mike Slinn