diff options
author | Fabio Pitino <fpitino@gitlab.com> | 2019-07-02 06:23:06 +0000 |
---|---|---|
committer | Marin Jankovski <marin@gitlab.com> | 2019-07-02 06:23:06 +0000 |
commit | abceda6cc5fa796d9bd0d7311b386787e6919266 (patch) | |
tree | 3a6f0cc62d9e0c42267562547be45ea5ea2d858f /lib/gitlab/config | |
parent | 23dedd53a73a01429c0a5c99414548694f1fab0b (diff) | |
download | gitlab-ce-abceda6cc5fa796d9bd0d7311b386787e6919266.tar.gz |
Prevent Billion Laughs attack
It keeps track of the memory being used when loading the YAML file
as well as the depth of nesting.
Track exception when YAML is too big
Diffstat (limited to 'lib/gitlab/config')
-rw-r--r-- | lib/gitlab/config/loader/yaml.rb | 34 |
1 files changed, 30 insertions, 4 deletions
diff --git a/lib/gitlab/config/loader/yaml.rb b/lib/gitlab/config/loader/yaml.rb index 8159f8b8026..4cedab1545c 100644 --- a/lib/gitlab/config/loader/yaml.rb +++ b/lib/gitlab/config/loader/yaml.rb @@ -4,6 +4,13 @@ module Gitlab module Config module Loader class Yaml + DataTooLargeError = Class.new(Loader::FormatError) + + include Gitlab::Utils::StrongMemoize + + MAX_YAML_SIZE = 1.megabyte + MAX_YAML_DEPTH = 100 + def initialize(config) @config = YAML.safe_load(config, [Symbol], [], true) rescue Psych::Exception => e @@ -11,16 +18,35 @@ module Gitlab end def valid? - @config.is_a?(Hash) + hash? && !too_big? end def load! - unless valid? - raise Loader::FormatError, 'Invalid configuration format' - end + raise DataTooLargeError, 'The parsed YAML is too big' if too_big? + raise Loader::FormatError, 'Invalid configuration format' unless hash? @config.deep_symbolize_keys end + + private + + def hash? + @config.is_a?(Hash) + end + + def too_big? + return false unless Feature.enabled?(:ci_yaml_limit_size, default_enabled: true) + + !deep_size.valid? + end + + def deep_size + strong_memoize(:deep_size) do + Gitlab::Utils::DeepSize.new(@config, + max_size: MAX_YAML_SIZE, + max_depth: MAX_YAML_DEPTH) + end + end end end end |