mitre-settingslogic 3.0.0
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 +7 -0
- data/CHANGELOG.md +67 -0
- data/CONTRIBUTING.md +119 -0
- data/LICENSE.md +16 -0
- data/README.md +204 -0
- data/ROADMAP.md +39 -0
- data/SECURITY.md +122 -0
- data/lib/settingslogic/version.rb +5 -0
- data/lib/settingslogic.rb +360 -0
- metadata +172 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: cabca9894cc72e6bf4207679d3847b539f15ba2c99cbd30165271b3988568b86
|
4
|
+
data.tar.gz: 1dead53a7b4c408796cb7439bf15fce7a3cef28e868a755ec595d759def19252
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 70ed779744d55559bbc1db46ec27700b6406f93c88e82e157de222b30b1264361e702d1c55d9012d234f94de2f3e541f13606d36b30893530b96f76efd2cb030
|
7
|
+
data.tar.gz: f920eadd8d2e1191209d1bab0497b845978a690a0e1b03da0f4ef29189221dad2c2638a1522023bb6e4cf6e25fe4727849c533b287f1f57e9a65fa420f28e8fe
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
# Changelog
|
2
|
+
|
3
|
+
All notable changes to this project will be documented in this file.
|
4
|
+
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
7
|
+
|
8
|
+
## [3.0.0] - 2025-01-11
|
9
|
+
|
10
|
+
### 🔒 Security (BREAKING CHANGES)
|
11
|
+
|
12
|
+
- **Critical**: Replace `YAML.unsafe_load` with `YAML.safe_load` to prevent arbitrary code execution
|
13
|
+
- Default permitted YAML classes: `Symbol, Date, Time, DateTime, BigDecimal`
|
14
|
+
- Replace vulnerable `open-uri` with `Net::HTTP` for URL loading
|
15
|
+
- Add protocol validation to block dangerous URI schemes (file://, ftp://, etc.)
|
16
|
+
|
17
|
+
### ✨ Features
|
18
|
+
|
19
|
+
- Add Ruby 3.x compatibility (3.0, 3.1, 3.2, 3.3, 3.4)
|
20
|
+
- Add Rails 7.x and 8.x compatibility
|
21
|
+
- Add Psych 4 support with YAML alias handling
|
22
|
+
- Add configurable permitted classes via `Settingslogic.yaml_permitted_classes`
|
23
|
+
- Add migration path with deprecated `Settingslogic.use_yaml_unsafe_load` flag
|
24
|
+
- Add helpful error messages with migration instructions
|
25
|
+
|
26
|
+
### 🐛 Fixes
|
27
|
+
|
28
|
+
- Fix RSpec Array#flatten issues with `to_ary` method
|
29
|
+
- Fix deprecated `has_key?` usage (now `key?`)
|
30
|
+
- Fix eval security with proper `__FILE__` and `__LINE__` tracking
|
31
|
+
- Fix Ruby 3.4 compatibility with explicit bigdecimal dependency
|
32
|
+
- Fix CI issues with Ruby 2.7 + Rails 6.1 zeitwerk conflict
|
33
|
+
|
34
|
+
### 📦 Infrastructure
|
35
|
+
|
36
|
+
- Add comprehensive test suite (94.63% coverage)
|
37
|
+
- Add RuboCop linting with rubocop-rspec and rubocop-performance
|
38
|
+
- Add GitHub Actions CI for all Ruby/Rails combinations
|
39
|
+
- Add automated release tooling with version management
|
40
|
+
- Add security testing suite (19 security-specific tests)
|
41
|
+
|
42
|
+
### 📚 Documentation
|
43
|
+
|
44
|
+
- Add comprehensive README with migration guide
|
45
|
+
- Add SECURITY.md with vulnerability reporting process
|
46
|
+
- Add ROADMAP.md for future development plans
|
47
|
+
- Add CONTRIBUTING.md for contribution guidelines
|
48
|
+
- Update all documentation for v3.0.0
|
49
|
+
|
50
|
+
### ⚠️ Breaking Changes
|
51
|
+
|
52
|
+
- YAML files can no longer instantiate arbitrary Ruby objects by default
|
53
|
+
- To allow custom classes: `Settingslogic.yaml_permitted_classes += [MyClass]`
|
54
|
+
- Temporary opt-out available: `Settingslogic.use_yaml_unsafe_load = true` (deprecated)
|
55
|
+
|
56
|
+
### 📝 Notes
|
57
|
+
|
58
|
+
This is a major security release addressing CVE-2022-32224-like vulnerabilities. All users should upgrade and review their YAML files for compatibility with safe_load restrictions.
|
59
|
+
|
60
|
+
## [2.0.9] - 2012-10-19
|
61
|
+
|
62
|
+
Last release of the original gem by Ben Johnson (binarylogic).
|
63
|
+
|
64
|
+
---
|
65
|
+
|
66
|
+
Maintained by MITRE Corporation
|
67
|
+
Primary maintainer: Aaron Lippold <lippold@gmail.com>
|
data/CONTRIBUTING.md
ADDED
@@ -0,0 +1,119 @@
|
|
1
|
+
# Contributing to Settingslogic
|
2
|
+
|
3
|
+
Thank you for your interest in contributing to the MITRE fork of settingslogic! This fork provides Ruby 3.x and Rails 7.x+ compatibility for the classic settingslogic gem.
|
4
|
+
|
5
|
+
## 🚀 Quick Start
|
6
|
+
|
7
|
+
```bash
|
8
|
+
# Fork and clone
|
9
|
+
git clone https://github.com/mitre/settingslogic.git
|
10
|
+
cd settingslogic
|
11
|
+
|
12
|
+
# Install dependencies
|
13
|
+
bundle install
|
14
|
+
|
15
|
+
# Run tests
|
16
|
+
bundle exec rspec
|
17
|
+
```
|
18
|
+
|
19
|
+
## 🛠️ Development Setup
|
20
|
+
|
21
|
+
### Prerequisites
|
22
|
+
|
23
|
+
- Ruby 2.7+ (we test against 2.7, 3.0, 3.1, 3.2, 3.3, and 3.4)
|
24
|
+
- Bundler
|
25
|
+
|
26
|
+
### Running Tests
|
27
|
+
|
28
|
+
```bash
|
29
|
+
# Run all tests
|
30
|
+
bundle exec rspec
|
31
|
+
|
32
|
+
# Run tests with specific Ruby version
|
33
|
+
rbenv local 3.2.0 # or rvm use 3.2.0
|
34
|
+
bundle exec rspec
|
35
|
+
|
36
|
+
# Run linting
|
37
|
+
bundle exec rubocop
|
38
|
+
```
|
39
|
+
|
40
|
+
## 📝 Making Changes
|
41
|
+
|
42
|
+
1. **Fork the repository** on GitHub
|
43
|
+
2. **Create a feature branch** from `master`
|
44
|
+
```bash
|
45
|
+
git checkout -b feature/my-new-feature
|
46
|
+
```
|
47
|
+
3. **Make your changes**
|
48
|
+
- Add tests for any new functionality
|
49
|
+
- Ensure all tests pass
|
50
|
+
- Follow existing code style
|
51
|
+
4. **Commit your changes**
|
52
|
+
```bash
|
53
|
+
git commit -m "Add new feature"
|
54
|
+
```
|
55
|
+
5. **Push to your fork**
|
56
|
+
```bash
|
57
|
+
git push origin feature/my-new-feature
|
58
|
+
```
|
59
|
+
6. **Create a Pull Request** on GitHub
|
60
|
+
|
61
|
+
## 🧪 Testing Requirements
|
62
|
+
|
63
|
+
All changes must:
|
64
|
+
- Include tests for new functionality
|
65
|
+
- Pass all existing tests
|
66
|
+
- Work with Ruby 2.7 through 3.4
|
67
|
+
- Maintain backwards compatibility where possible
|
68
|
+
|
69
|
+
### Testing YAML Aliases
|
70
|
+
|
71
|
+
Since the main purpose of this fork is Psych 4 compatibility, ensure YAML aliases work:
|
72
|
+
|
73
|
+
```ruby
|
74
|
+
# test.yml
|
75
|
+
defaults: &defaults
|
76
|
+
host: localhost
|
77
|
+
port: 3000
|
78
|
+
|
79
|
+
development:
|
80
|
+
<<: *defaults
|
81
|
+
database: dev_db
|
82
|
+
```
|
83
|
+
|
84
|
+
## 🎯 Focus Areas
|
85
|
+
|
86
|
+
We're particularly interested in:
|
87
|
+
- Ruby 3.x compatibility improvements
|
88
|
+
- Rails 7.x and 8.x compatibility
|
89
|
+
- Performance improvements
|
90
|
+
- Security enhancements
|
91
|
+
- Better error messages
|
92
|
+
|
93
|
+
## 📋 Code Style
|
94
|
+
|
95
|
+
- Use frozen string literals
|
96
|
+
- Follow Ruby community conventions
|
97
|
+
- Run `bundle exec rubocop` before committing
|
98
|
+
- Keep methods small and focused
|
99
|
+
- Document complex logic
|
100
|
+
|
101
|
+
## 🐛 Reporting Issues
|
102
|
+
|
103
|
+
When reporting issues, please include:
|
104
|
+
- Ruby version
|
105
|
+
- Rails version (if applicable)
|
106
|
+
- Minimal reproduction example
|
107
|
+
- Full error message and stack trace
|
108
|
+
|
109
|
+
## 📄 License
|
110
|
+
|
111
|
+
By contributing, you agree that your contributions will be licensed under the MIT License.
|
112
|
+
|
113
|
+
## 📧 Contact
|
114
|
+
|
115
|
+
For questions about contributing, please open an issue on GitHub or contact the maintainers at lippold@gmail.com.
|
116
|
+
|
117
|
+
## 🙏 Acknowledgments
|
118
|
+
|
119
|
+
Thanks to Ben Johnson for creating the original settingslogic gem, and to all the fork maintainers who have kept it alive for the Ruby community.
|
data/LICENSE.md
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
---
|
2
|
+
title: License
|
3
|
+
description: Apache 2.0 license for the cyber-trackr-live project
|
4
|
+
layout: doc
|
5
|
+
sidebar: true
|
6
|
+
---
|
7
|
+
|
8
|
+
Licensed under the apache-2.0 license, except as noted below.
|
9
|
+
|
10
|
+
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
11
|
+
|
12
|
+
* Redistributions of source code must retain the above copyright/ digital rights legend, this list of conditions and the following Notice.
|
13
|
+
|
14
|
+
* Redistributions in binary form must reproduce the above copyright copyright/ digital rights legend, this list of conditions and the following Notice in the documentation and/or other materials provided with the distribution.
|
15
|
+
|
16
|
+
* Neither the name of The MITRE Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
|
data/README.md
ADDED
@@ -0,0 +1,204 @@
|
|
1
|
+
# Settingslogic - MITRE Fork
|
2
|
+
|
3
|
+
[](https://github.com/mitre/settingslogic/actions/workflows/ci.yml)
|
4
|
+
[](http://badge.fury.io/rb/settingslogic)
|
5
|
+
|
6
|
+
A simple and straightforward settings solution that uses an ERB enabled YAML file and a singleton design pattern. This is a MITRE-maintained fork with Ruby 3.x and Rails 7.x+ compatibility.
|
7
|
+
|
8
|
+
## 🎯 Why This Fork?
|
9
|
+
|
10
|
+
The original settingslogic gem hasn't been updated since 2012 but is still widely used. This fork provides:
|
11
|
+
|
12
|
+
- ✅ **Ruby 3.x compatibility** - Full support for Ruby 3.0, 3.1, 3.2, 3.3, and 3.4
|
13
|
+
- ✅ **Psych 4 support** - Handles YAML aliases correctly with Ruby 3.1+
|
14
|
+
- ✅ **Rails 7.x/8.x compatibility** - Works with modern Rails versions
|
15
|
+
- ✅ **Security updates** - Modern security practices and dependency updates
|
16
|
+
- ✅ **Maintained** - Active maintenance and support
|
17
|
+
|
18
|
+
## 📦 Installation
|
19
|
+
|
20
|
+
Add this to your Gemfile:
|
21
|
+
|
22
|
+
```ruby
|
23
|
+
# Use the MITRE fork for Ruby 3.x compatibility
|
24
|
+
gem 'settingslogic', github: 'mitre/settingslogic', branch: 'master'
|
25
|
+
```
|
26
|
+
|
27
|
+
Or if we publish to RubyGems:
|
28
|
+
|
29
|
+
```ruby
|
30
|
+
gem 'mitre-settingslogic'
|
31
|
+
```
|
32
|
+
|
33
|
+
## 🚀 Quick Start
|
34
|
+
|
35
|
+
### 1. Define your settings class
|
36
|
+
|
37
|
+
```ruby
|
38
|
+
# app/models/settings.rb (for Rails)
|
39
|
+
# or anywhere in your Ruby project
|
40
|
+
class Settings < Settingslogic
|
41
|
+
source "#{Rails.root}/config/application.yml"
|
42
|
+
namespace Rails.env
|
43
|
+
end
|
44
|
+
```
|
45
|
+
|
46
|
+
### 2. Create your YAML configuration
|
47
|
+
|
48
|
+
```yaml
|
49
|
+
# config/application.yml
|
50
|
+
defaults: &defaults
|
51
|
+
host: localhost
|
52
|
+
port: 3000
|
53
|
+
ssl: false
|
54
|
+
|
55
|
+
development:
|
56
|
+
<<: *defaults
|
57
|
+
database: myapp_development
|
58
|
+
|
59
|
+
production:
|
60
|
+
<<: *defaults
|
61
|
+
host: production.example.com
|
62
|
+
port: 443
|
63
|
+
ssl: true
|
64
|
+
database: myapp_production
|
65
|
+
```
|
66
|
+
|
67
|
+
### 3. Use your settings
|
68
|
+
|
69
|
+
```ruby
|
70
|
+
Settings.host # => "localhost" in development, "production.example.com" in production
|
71
|
+
Settings.port # => 3000 in development, 443 in production
|
72
|
+
Settings.ssl? # => false in development, true in production
|
73
|
+
Settings.database # => "myapp_development" in development
|
74
|
+
|
75
|
+
# Nested settings
|
76
|
+
Settings.smtp.address # => Access nested configuration
|
77
|
+
Settings['smtp']['address'] # => Hash-style access also works
|
78
|
+
```
|
79
|
+
|
80
|
+
## 🔧 Advanced Features
|
81
|
+
|
82
|
+
### Dynamic Settings
|
83
|
+
|
84
|
+
```ruby
|
85
|
+
# Settings with ERB
|
86
|
+
production:
|
87
|
+
secret_key: <%= ENV['SECRET_KEY_BASE'] %>
|
88
|
+
redis_url: <%= ENV['REDIS_URL'] || 'redis://localhost:6379' %>
|
89
|
+
```
|
90
|
+
|
91
|
+
### Multiple Configuration Files
|
92
|
+
|
93
|
+
```ruby
|
94
|
+
class DatabaseSettings < Settingslogic
|
95
|
+
source "#{Rails.root}/config/database_settings.yml"
|
96
|
+
namespace Rails.env
|
97
|
+
end
|
98
|
+
|
99
|
+
class FeatureFlags < Settingslogic
|
100
|
+
source "#{Rails.root}/config/features.yml"
|
101
|
+
namespace Rails.env
|
102
|
+
end
|
103
|
+
```
|
104
|
+
|
105
|
+
### Suppress Errors
|
106
|
+
|
107
|
+
```ruby
|
108
|
+
class Settings < Settingslogic
|
109
|
+
source "#{Rails.root}/config/application.yml"
|
110
|
+
namespace Rails.env
|
111
|
+
suppress_errors true # Returns nil instead of raising errors for missing keys
|
112
|
+
end
|
113
|
+
```
|
114
|
+
|
115
|
+
### Dynamic Access
|
116
|
+
|
117
|
+
```ruby
|
118
|
+
# Access nested keys with dot notation
|
119
|
+
Settings.get('database.pool.size') # => 5
|
120
|
+
Settings.get('redis.cache.ttl') # => 3600
|
121
|
+
```
|
122
|
+
|
123
|
+
## 🏗️ What's Fixed in This Fork
|
124
|
+
|
125
|
+
### Psych 4 / Ruby 3.1+ Compatibility
|
126
|
+
|
127
|
+
The main issue with the original gem is that Ruby 3.1+ ships with Psych 4, which disables YAML aliases by default. This fork handles that correctly:
|
128
|
+
|
129
|
+
```ruby
|
130
|
+
# This YAML with aliases now works correctly in Ruby 3.1+
|
131
|
+
defaults: &defaults
|
132
|
+
timeout: 30
|
133
|
+
retries: 3
|
134
|
+
|
135
|
+
production:
|
136
|
+
<<: *defaults # This alias expansion works!
|
137
|
+
timeout: 60
|
138
|
+
```
|
139
|
+
|
140
|
+
### Other Improvements
|
141
|
+
|
142
|
+
- ✅ Fixed deprecated `has_key?` → `key?`
|
143
|
+
- ✅ Added `to_ary` method for RSpec compatibility
|
144
|
+
- ✅ Improved `symbolize_keys` for nested hashes
|
145
|
+
- ✅ Added `stringify_keys` for Rails compatibility
|
146
|
+
- ✅ Better error messages
|
147
|
+
- ✅ Security improvements for eval usage
|
148
|
+
- ✅ Frozen string literals
|
149
|
+
- ✅ Modern Ruby idioms
|
150
|
+
|
151
|
+
## 🧪 Compatibility
|
152
|
+
|
153
|
+
Tested and working with:
|
154
|
+
|
155
|
+
- **Ruby:** 2.7, 3.0, 3.1, 3.2, 3.3, 3.4
|
156
|
+
- **Rails:** 5.2, 6.0, 6.1, 7.0, 7.1, 8.0
|
157
|
+
- **Psych:** 3.x and 4.x
|
158
|
+
|
159
|
+
## 🔒 Security
|
160
|
+
|
161
|
+
### YAML Safe Loading (v3.0.0+)
|
162
|
+
- **Default behavior**: Uses `YAML.safe_load` to prevent arbitrary code execution
|
163
|
+
- **Permitted classes**: `Symbol, Date, Time, DateTime, BigDecimal`
|
164
|
+
- **Custom classes**: Add via `Settingslogic.yaml_permitted_classes += [MyClass]`
|
165
|
+
- **Migration path**: Temporary opt-out with `Settingslogic.use_yaml_unsafe_load = true` (deprecated, will be removed in v4.0.0)
|
166
|
+
|
167
|
+
### Other Security Features
|
168
|
+
- URL loading uses `Net::HTTP` instead of vulnerable `open-uri`
|
169
|
+
- All eval usage includes proper `__FILE__` and `__LINE__` tracking
|
170
|
+
- No arbitrary code execution vulnerabilities in default configuration
|
171
|
+
|
172
|
+
## 🤝 Contributing
|
173
|
+
|
174
|
+
We welcome contributions! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for details.
|
175
|
+
|
176
|
+
## 📄 License
|
177
|
+
|
178
|
+
This project is licensed under the MIT License - see [LICENSE.md](LICENSE.md) for details.
|
179
|
+
|
180
|
+
## 🙏 Acknowledgments
|
181
|
+
|
182
|
+
- Original gem created by [Ben Johnson](https://github.com/binarylogic) (binarylogic)
|
183
|
+
- Community maintainers at [settingslogic/settingslogic](https://github.com/settingslogic/settingslogic)
|
184
|
+
- Key fixes incorporated from:
|
185
|
+
- [minorun99/settingslogic](https://github.com/minorun99/settingslogic) - Ruby 3.2 compatibility
|
186
|
+
- [etozzato/settingslogic](https://github.com/etozzato/settingslogic) - Psych 4 safe_load implementation
|
187
|
+
- [bigcommerce/settingslogic](https://github.com/bigcommerce/settingslogic) - Various compatibility fixes
|
188
|
+
- [tvw/settingslogic](https://github.com/tvw/settingslogic) - Ruby 3 support
|
189
|
+
- And many others who kept this gem alive through their forks and PRs
|
190
|
+
- Special thanks to all who submitted PRs to the original repo, especially PR #86 for Psych 4 compatibility
|
191
|
+
|
192
|
+
## 📚 Documentation
|
193
|
+
|
194
|
+
- [Original Documentation](http://rdoc.info/github/binarylogic/settingslogic)
|
195
|
+
- [MITRE Fork Issues](https://github.com/mitre/settingslogic/issues)
|
196
|
+
- [MITRE Fork Repository](https://github.com/mitre/settingslogic)
|
197
|
+
|
198
|
+
## 🏢 About MITRE
|
199
|
+
|
200
|
+
This fork is maintained by [MITRE Corporation](https://www.mitre.org/) to support our Ruby applications, particularly [Vulcan](https://github.com/mitre/vulcan) and other security tools.
|
201
|
+
|
202
|
+
---
|
203
|
+
|
204
|
+
**Maintained with ❤️ by the MITRE Security Automation Framework Team**
|
data/ROADMAP.md
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
# Settingslogic Roadmap
|
2
|
+
|
3
|
+
## Version 3.0.0 (Current Release)
|
4
|
+
- ✅ Ruby 3.x compatibility through Ruby 3.4+
|
5
|
+
- ✅ Rails 7.x and 8.x compatibility
|
6
|
+
- ✅ Security: Replaced `YAML.unsafe_load` with `YAML.safe_load`
|
7
|
+
- ✅ Configurable permitted classes via `Settingslogic.yaml_permitted_classes`
|
8
|
+
- ✅ Migration path with deprecated `use_yaml_unsafe_load` flag
|
9
|
+
- ✅ 94%+ test coverage with reorganized specs
|
10
|
+
|
11
|
+
## Version 3.x (Maintenance)
|
12
|
+
- Rename master branch to main (v3.0.1 or v3.1)
|
13
|
+
- Test gem autopublishing workflow
|
14
|
+
- Bug fixes as needed
|
15
|
+
- Maintain compatibility with new Ruby/Rails releases
|
16
|
+
- No new features planned - focus on stability
|
17
|
+
|
18
|
+
## Version 4.0.0 (Future - Aligned with Vulcan Rewrite)
|
19
|
+
### Breaking Changes
|
20
|
+
- Drop Ruby 2.7 support (already EOL as of March 2023)
|
21
|
+
- Remove deprecated `use_yaml_unsafe_load` flag
|
22
|
+
- Minimum Ruby version: 3.0+ (or higher based on adoption)
|
23
|
+
|
24
|
+
### Goals
|
25
|
+
- Simplify codebase by removing legacy compatibility code
|
26
|
+
- Maintain as a simple, focused settings gem
|
27
|
+
- Ensure compatibility with Ruby 3.4+ for the long term
|
28
|
+
|
29
|
+
## Maintenance Philosophy
|
30
|
+
This is a MITRE-maintained fork created specifically for Vulcan and other MITRE projects. We recognize that many in the Ruby community are moving to other configuration solutions, but settingslogic remains valuable for existing projects.
|
31
|
+
|
32
|
+
Our focus:
|
33
|
+
- Security and stability over features
|
34
|
+
- Maintaining compatibility for existing users
|
35
|
+
- Clear migration paths when changes are needed
|
36
|
+
- No unnecessary complexity
|
37
|
+
|
38
|
+
## Note
|
39
|
+
Given the gem's maturity and decreasing usage in new projects, we don't anticipate significant feature development. This fork exists primarily to ensure MITRE projects using settingslogic can safely upgrade to modern Ruby and Rails versions.
|
data/SECURITY.md
ADDED
@@ -0,0 +1,122 @@
|
|
1
|
+
# Security Policy
|
2
|
+
|
3
|
+
## Reporting Security Issues
|
4
|
+
|
5
|
+
The MITRE team takes security seriously. If you discover a security vulnerability in the settingslogic fork, please report it responsibly.
|
6
|
+
|
7
|
+
### Contact Information
|
8
|
+
|
9
|
+
- **Email**: [saf-security@mitre.org](mailto:saf-security@mitre.org)
|
10
|
+
- **GitHub**: Use the [Security tab](https://github.com/mitre/settingslogic/security) to report vulnerabilities privately
|
11
|
+
- **Direct Contact**: lippold@gmail.com for urgent issues
|
12
|
+
|
13
|
+
### What to Include
|
14
|
+
|
15
|
+
When reporting security issues, please provide:
|
16
|
+
|
17
|
+
1. **Description** of the vulnerability
|
18
|
+
2. **Steps to reproduce** the issue
|
19
|
+
3. **Affected versions** (Ruby version, settingslogic version)
|
20
|
+
4. **Potential impact** assessment
|
21
|
+
5. **Suggested fix** (if you have one)
|
22
|
+
|
23
|
+
### Response Timeline
|
24
|
+
|
25
|
+
- **Acknowledgment**: Within 48 hours
|
26
|
+
- **Initial Assessment**: Within 1 week
|
27
|
+
- **Fix Timeline**: Depends on severity
|
28
|
+
- Critical: Within 1 week
|
29
|
+
- High: Within 2 weeks
|
30
|
+
- Medium: Within 1 month
|
31
|
+
- Low: Next release
|
32
|
+
|
33
|
+
## Security Considerations
|
34
|
+
|
35
|
+
### YAML Loading (v3.0.0+)
|
36
|
+
|
37
|
+
This gem uses YAML for configuration files with secure defaults:
|
38
|
+
|
39
|
+
- **Default**: Uses `YAML.safe_load` to prevent arbitrary code execution
|
40
|
+
- **Permitted classes**: `Symbol, Date, Time, DateTime, BigDecimal`
|
41
|
+
- **Customizable**: Add your own classes via `Settingslogic.yaml_permitted_classes`
|
42
|
+
- **YAML aliases**: Fully supported with `aliases: true` parameter
|
43
|
+
|
44
|
+
**⚠️ Important**: Configuration files should be:
|
45
|
+
- Stored in secure locations
|
46
|
+
- Not user-uploadable
|
47
|
+
- Protected with appropriate file permissions
|
48
|
+
|
49
|
+
### ERB Processing
|
50
|
+
|
51
|
+
Configuration files support ERB templates. This means:
|
52
|
+
- Environment variables can be embedded
|
53
|
+
- Ruby code can be executed during configuration loading
|
54
|
+
|
55
|
+
**Best Practices**:
|
56
|
+
```yaml
|
57
|
+
# Good - using environment variables
|
58
|
+
production:
|
59
|
+
secret_key: <%= ENV['SECRET_KEY_BASE'] %>
|
60
|
+
|
61
|
+
# Avoid - executing arbitrary code
|
62
|
+
production:
|
63
|
+
value: <%= `whoami` %> # Don't do this!
|
64
|
+
```
|
65
|
+
|
66
|
+
### File Access
|
67
|
+
|
68
|
+
The gem can load configuration from:
|
69
|
+
- Local files (recommended)
|
70
|
+
- HTTP/HTTPS URLs (use with caution)
|
71
|
+
|
72
|
+
For production environments, always use local files with proper permissions.
|
73
|
+
|
74
|
+
## Supported Versions
|
75
|
+
|
76
|
+
| Version | Ruby Versions | Supported |
|
77
|
+
| ------- | ------------- | ------------------ |
|
78
|
+
| 3.0.x | 2.7 - 3.4 | :white_check_mark: |
|
79
|
+
| 2.0.x | 1.9 - 2.6 | :x: |
|
80
|
+
|
81
|
+
## Security Enhancements in v3.0.0
|
82
|
+
|
83
|
+
### Critical Security Fixes
|
84
|
+
- **YAML deserialization security**: Replaced `YAML.unsafe_load` with `YAML.safe_load` to prevent arbitrary object instantiation (addresses CVE-2022-32224 pattern)
|
85
|
+
- **Removed open-uri vulnerability**: Replaced `open-uri` with `Net::HTTP` to prevent SSRF attacks
|
86
|
+
- **Protocol validation**: Explicitly blocks dangerous protocols (file://, ftp://, gopher://, etc.)
|
87
|
+
- **Safe YAML loading**: Default permitted classes: Symbol, Date, Time, DateTime, BigDecimal
|
88
|
+
- **Input sanitization**: Dynamic method names validated with `/^\w+$/` to prevent code injection
|
89
|
+
|
90
|
+
### Security Features
|
91
|
+
- **No automatic redirects**: HTTP client doesn't follow redirects automatically
|
92
|
+
- **Controlled deserialization**: Prevents arbitrary object instantiation in YAML
|
93
|
+
- **Proper error handling**: Security errors fail safely without exposing internals
|
94
|
+
- **Comprehensive testing**: 18 security-specific test cases added
|
95
|
+
|
96
|
+
### Known Security Issues
|
97
|
+
|
98
|
+
#### Original Gem (2.0.9)
|
99
|
+
- **CVE-2020-8287 (related)**: Uses vulnerable `open-uri` for URL loading
|
100
|
+
- No Psych 4 support (Ruby 3.1+ compatibility issues)
|
101
|
+
- Uses deprecated `YAML.load` without restrictions
|
102
|
+
- No security updates since 2012
|
103
|
+
|
104
|
+
#### This Fork (3.0.0+)
|
105
|
+
- All known security issues have been addressed
|
106
|
+
- Regular security audits via bundler-audit
|
107
|
+
- Active maintenance by MITRE SAF team
|
108
|
+
- Comprehensive security test coverage (94.63%)
|
109
|
+
|
110
|
+
## Disclosure Policy
|
111
|
+
|
112
|
+
We follow responsible disclosure:
|
113
|
+
|
114
|
+
1. Security issues are fixed in private
|
115
|
+
2. Patches are released with security advisories
|
116
|
+
3. Credit is given to reporters (unless they prefer anonymity)
|
117
|
+
|
118
|
+
## Additional Resources
|
119
|
+
|
120
|
+
- [MITRE CVE Database](https://cve.mitre.org/)
|
121
|
+
- [Ruby Security Advisories](https://www.ruby-lang.org/en/security/)
|
122
|
+
- [Rails Security Guide](https://guides.rubyonrails.org/security.html)
|
@@ -0,0 +1,360 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'yaml'
|
4
|
+
require 'erb'
|
5
|
+
require 'date'
|
6
|
+
require 'bigdecimal'
|
7
|
+
|
8
|
+
# A simple settings solution using a YAML file. See README for more information.
|
9
|
+
class Settingslogic < Hash
|
10
|
+
class MissingSetting < StandardError; end
|
11
|
+
|
12
|
+
class << self
|
13
|
+
def name # :nodoc:
|
14
|
+
superclass != Hash && instance.key?('name') ? instance.name : super
|
15
|
+
end
|
16
|
+
|
17
|
+
# Configure additional permitted classes for YAML deserialization
|
18
|
+
# Default: [Symbol, Date, Time, DateTime, BigDecimal]
|
19
|
+
# Example: Settingslogic.yaml_permitted_classes += [MyCustomClass]
|
20
|
+
def yaml_permitted_classes
|
21
|
+
@yaml_permitted_classes ||= [Symbol, Date, Time, DateTime, BigDecimal]
|
22
|
+
end
|
23
|
+
|
24
|
+
attr_writer :yaml_permitted_classes
|
25
|
+
|
26
|
+
# DEPRECATED: Temporarily allow unsafe YAML loading for backwards compatibility
|
27
|
+
# This option will be removed in v4.0.0
|
28
|
+
# WARNING: This enables arbitrary code execution vulnerabilities!
|
29
|
+
def use_yaml_unsafe_load=(value)
|
30
|
+
if value
|
31
|
+
warn '[DEPRECATION] Settingslogic.use_yaml_unsafe_load is deprecated and will be removed in v4.0.0. ' \
|
32
|
+
'Please migrate to using Settingslogic.yaml_permitted_classes instead.'
|
33
|
+
end
|
34
|
+
@use_yaml_unsafe_load = value
|
35
|
+
end
|
36
|
+
|
37
|
+
def use_yaml_unsafe_load
|
38
|
+
@use_yaml_unsafe_load ||= false
|
39
|
+
end
|
40
|
+
|
41
|
+
# Enables Settings.get('nested.key.name') for dynamic access
|
42
|
+
def get(key)
|
43
|
+
parts = key.split('.')
|
44
|
+
curs = self
|
45
|
+
while (p = parts.shift)
|
46
|
+
curs = curs.send(p)
|
47
|
+
end
|
48
|
+
curs
|
49
|
+
end
|
50
|
+
|
51
|
+
def source(value = nil)
|
52
|
+
@source ||= value
|
53
|
+
end
|
54
|
+
|
55
|
+
def namespace(value = nil)
|
56
|
+
@namespace ||= value
|
57
|
+
end
|
58
|
+
|
59
|
+
def suppress_errors(value = nil)
|
60
|
+
@suppress_errors ||= value
|
61
|
+
end
|
62
|
+
|
63
|
+
def [](key)
|
64
|
+
instance.fetch(key.to_s, nil)
|
65
|
+
end
|
66
|
+
|
67
|
+
def []=(key, val)
|
68
|
+
# Setting[:key][:key2] = 'value' for dynamic settings
|
69
|
+
val = new(val, source) if val.is_a? Hash
|
70
|
+
instance.store(key.to_s, val)
|
71
|
+
instance.create_accessor_for(key, val)
|
72
|
+
end
|
73
|
+
|
74
|
+
def load!
|
75
|
+
instance
|
76
|
+
true
|
77
|
+
end
|
78
|
+
|
79
|
+
def reload!
|
80
|
+
@instance = nil
|
81
|
+
load!
|
82
|
+
end
|
83
|
+
|
84
|
+
private
|
85
|
+
|
86
|
+
def instance
|
87
|
+
return @instance if @instance
|
88
|
+
|
89
|
+
@instance = new
|
90
|
+
create_accessors!
|
91
|
+
@instance
|
92
|
+
end
|
93
|
+
|
94
|
+
def method_missing(name, *args, &block)
|
95
|
+
instance.send(name, *args, &block)
|
96
|
+
end
|
97
|
+
|
98
|
+
# It would be great to DRY this up somehow, someday, but it's difficult because
|
99
|
+
# of the singleton pattern. Basically this proxies Setting.foo to Setting.instance.foo
|
100
|
+
def create_accessors!
|
101
|
+
instance.each_key do |key|
|
102
|
+
create_accessor_for(key)
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
def create_accessor_for(key)
|
107
|
+
return unless /^\w+$/.match?(key.to_s) # could have "some-setting:" which blows up eval
|
108
|
+
|
109
|
+
instance_eval "def #{key}; instance.send(:#{key}); end", __FILE__, __LINE__
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
# Initializes a new settings object. You can initialize an object in any of the following ways:
|
114
|
+
#
|
115
|
+
# Settings.new(:application) # will look for config/application.yml
|
116
|
+
# Settings.new("application.yaml") # will look for application.yaml
|
117
|
+
# Settings.new("/var/configs/application.yml") # will look for /var/configs/application.yml
|
118
|
+
# Settings.new(:config1 => 1, :config2 => 2)
|
119
|
+
#
|
120
|
+
# Basically if you pass a symbol it will look for that file in the configs directory of your rails app,
|
121
|
+
# if you are using this in rails. If you pass a string it should be an absolute path to your settings file.
|
122
|
+
# Then you can pass a hash, and it just allows you to access the hash via methods.
|
123
|
+
def initialize(hash_or_file = self.class.source, section = nil)
|
124
|
+
# puts "new! #{hash_or_file}"
|
125
|
+
case hash_or_file
|
126
|
+
when nil
|
127
|
+
raise Errno::ENOENT, 'No file specified as Settingslogic source'
|
128
|
+
when Hash
|
129
|
+
replace hash_or_file
|
130
|
+
else
|
131
|
+
file_contents = read_file(hash_or_file)
|
132
|
+
hash = file_contents.empty? ? {} : parse_yaml_content(file_contents)
|
133
|
+
if self.class.namespace
|
134
|
+
hash = hash[self.class.namespace] or
|
135
|
+
return missing_key("Missing setting '#{self.class.namespace}' in #{hash_or_file}")
|
136
|
+
end
|
137
|
+
|
138
|
+
replace hash
|
139
|
+
end
|
140
|
+
@section = section || self.class.source # so end of error says "in application.yml"
|
141
|
+
create_accessors!
|
142
|
+
end
|
143
|
+
|
144
|
+
# Called for dynamically-defined keys, and also the first key deferenced at the top-level, if load! is not used.
|
145
|
+
# Otherwise, create_accessors! (called by new) will have created actual methods for each key.
|
146
|
+
def method_missing(name, *_args)
|
147
|
+
key = name.to_s
|
148
|
+
return missing_key("Missing setting '#{key}' in #{@section}") unless key? key
|
149
|
+
|
150
|
+
value = fetch(key)
|
151
|
+
create_accessor_for(key)
|
152
|
+
value.is_a?(Hash) ? self.class.new(value, "'#{key}' section in #{@section}") : value
|
153
|
+
end
|
154
|
+
|
155
|
+
def [](key)
|
156
|
+
fetch(key.to_s, nil)
|
157
|
+
end
|
158
|
+
|
159
|
+
def []=(key, val)
|
160
|
+
# Setting[:key][:key2] = 'value' for dynamic settings
|
161
|
+
val = self.class.new(val, @section) if val.is_a? Hash
|
162
|
+
store(key.to_s, val)
|
163
|
+
create_accessor_for(key, val)
|
164
|
+
end
|
165
|
+
|
166
|
+
# Returns an instance of a Hash object
|
167
|
+
def to_hash
|
168
|
+
to_h
|
169
|
+
end
|
170
|
+
|
171
|
+
# Prevents Array#flatten from trying to expand Settings objects
|
172
|
+
# This fixes RSpec issues when Settings objects are included in arrays
|
173
|
+
def to_ary
|
174
|
+
nil
|
175
|
+
end
|
176
|
+
|
177
|
+
# This handles naming collisions with Sinatra/Vlad/Capistrano. Since these use a set()
|
178
|
+
# helper that defines methods in Object, ANY method_missing ANYWHERE picks up the Vlad/Sinatra
|
179
|
+
# settings! So settings.deploy_to title actually calls Object.deploy_to (from set :deploy_to, "host"),
|
180
|
+
# rather than the app_yml['deploy_to'] hash. Jeezus.
|
181
|
+
def create_accessors!
|
182
|
+
each do |key, _val|
|
183
|
+
create_accessor_for(key)
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
# Use instance_eval/class_eval because they're actually more efficient than define_method{}
|
188
|
+
# http://stackoverflow.com/questions/185947/ruby-definemethod-vs-def
|
189
|
+
# http://bmorearty.wordpress.com/2009/01/09/fun-with-rubys-instance_eval-and-class_eval/
|
190
|
+
def create_accessor_for(key, val = nil)
|
191
|
+
return unless /^\w+$/.match?(key.to_s) # could have "some-setting:" which blows up eval
|
192
|
+
|
193
|
+
instance_variable_set("@#{key}", val)
|
194
|
+
self.class.class_eval <<-ENDEVAL, __FILE__, __LINE__ + 1
|
195
|
+
def #{key}
|
196
|
+
return @#{key} if @#{key}
|
197
|
+
return missing_key("Missing setting '#{key}' in #{@section}") unless key? '#{key}'
|
198
|
+
value = fetch('#{key}')
|
199
|
+
@#{key} = if value.is_a?(Hash)
|
200
|
+
self.class.new(value, "'#{key}' section in #{@section}")
|
201
|
+
elsif value.is_a?(Array) && value.all?{|v| v.is_a? Hash}
|
202
|
+
value.map{|v| self.class.new(v)}
|
203
|
+
else
|
204
|
+
value
|
205
|
+
end
|
206
|
+
end
|
207
|
+
ENDEVAL
|
208
|
+
end
|
209
|
+
|
210
|
+
# Convert all keys to symbols recursively
|
211
|
+
def symbolize_keys
|
212
|
+
each_with_object({}) do |(key, value), memo|
|
213
|
+
k = begin
|
214
|
+
key.to_sym
|
215
|
+
rescue StandardError
|
216
|
+
key
|
217
|
+
end
|
218
|
+
# Access the value properly through the accessor method
|
219
|
+
v = respond_to?(key) ? send(key) : value
|
220
|
+
# Recursively symbolize nested hashes
|
221
|
+
memo[k] = if v.is_a?(self.class)
|
222
|
+
v.symbolize_keys
|
223
|
+
elsif v.respond_to?(:symbolize_keys)
|
224
|
+
v.symbolize_keys
|
225
|
+
else
|
226
|
+
v
|
227
|
+
end
|
228
|
+
end
|
229
|
+
end
|
230
|
+
|
231
|
+
# Convert all keys to strings recursively (Rails compatibility)
|
232
|
+
def stringify_keys
|
233
|
+
each_with_object({}) do |(key, value), memo|
|
234
|
+
k = key.to_s
|
235
|
+
v = begin
|
236
|
+
send(key)
|
237
|
+
rescue StandardError
|
238
|
+
value
|
239
|
+
end
|
240
|
+
memo[k] = v.respond_to?(:stringify_keys) ? v.stringify_keys : v
|
241
|
+
end
|
242
|
+
end
|
243
|
+
|
244
|
+
# Deep merge settings (useful for overrides)
|
245
|
+
def deep_merge(other_hash)
|
246
|
+
self.class.new(deep_merge_hash(to_hash, other_hash))
|
247
|
+
end
|
248
|
+
|
249
|
+
# Deep merge in place
|
250
|
+
def deep_merge!(other_hash)
|
251
|
+
replace(deep_merge_hash(to_hash, other_hash))
|
252
|
+
end
|
253
|
+
|
254
|
+
private
|
255
|
+
|
256
|
+
# Helper for deep merging
|
257
|
+
def deep_merge_hash(hash, other_hash)
|
258
|
+
hash.merge(other_hash) do |_key, old_val, new_val|
|
259
|
+
if old_val.is_a?(Hash) && new_val.is_a?(Hash)
|
260
|
+
deep_merge_hash(old_val, new_val)
|
261
|
+
else
|
262
|
+
new_val
|
263
|
+
end
|
264
|
+
end
|
265
|
+
end
|
266
|
+
|
267
|
+
def missing_key(msg)
|
268
|
+
return nil if self.class.suppress_errors
|
269
|
+
|
270
|
+
raise MissingSetting, msg
|
271
|
+
end
|
272
|
+
|
273
|
+
# Parse YAML content with Psych 4 / Ruby 3.1+ compatibility
|
274
|
+
# Handles YAML aliases which are disabled by default in Psych 4
|
275
|
+
def parse_yaml_content(file_content)
|
276
|
+
erb_result = ERB.new(file_content).result
|
277
|
+
|
278
|
+
# Check if unsafe loading is enabled (deprecated)
|
279
|
+
if self.class.use_yaml_unsafe_load
|
280
|
+
# Use the old unsafe behavior (security risk!)
|
281
|
+
if YAML.respond_to?(:unsafe_load)
|
282
|
+
# unsafe_load doesn't take aliases parameter, it allows them by default
|
283
|
+
YAML.unsafe_load(erb_result).to_hash
|
284
|
+
else
|
285
|
+
# Fallback to regular load for older Ruby versions
|
286
|
+
YAML.load(erb_result).to_hash # rubocop:disable Security/YAMLLoad
|
287
|
+
end
|
288
|
+
else
|
289
|
+
# Use safe_load for security (recommended)
|
290
|
+
permitted_classes = self.class.yaml_permitted_classes
|
291
|
+
|
292
|
+
begin
|
293
|
+
if YAML.respond_to?(:safe_load)
|
294
|
+
# Try with modern safe_load signature (Ruby 2.6+)
|
295
|
+
YAML.safe_load(erb_result, permitted_classes: permitted_classes, aliases: true).to_hash
|
296
|
+
else
|
297
|
+
# Fallback for older Ruby versions
|
298
|
+
YAML.safe_load(erb_result, permitted_classes, [], true).to_hash
|
299
|
+
end
|
300
|
+
rescue ArgumentError => e
|
301
|
+
# Handle older safe_load signature (Ruby 2.5 and earlier)
|
302
|
+
raise e unless e.message.include?('unknown keyword') || e.message.include?('wrong number of arguments')
|
303
|
+
|
304
|
+
# Old signature: safe_load(yaml, whitelist_classes, whitelist_symbols, aliases)
|
305
|
+
YAML.safe_load(erb_result, permitted_classes, [], true).to_hash
|
306
|
+
end
|
307
|
+
end
|
308
|
+
rescue Psych::DisallowedClass => e
|
309
|
+
# Extract class name from error message
|
310
|
+
class_name = e.message[/Tried to load unspecified class: (.+)/, 1] || e.message
|
311
|
+
|
312
|
+
# Provide helpful error message with migration instructions
|
313
|
+
raise MissingSetting, "YAML file contains disallowed class: #{class_name}\n\n" \
|
314
|
+
"To fix this, you have two options:\n" \
|
315
|
+
"1. Add the class to permitted classes:\n " \
|
316
|
+
"Settingslogic.yaml_permitted_classes += [#{class_name}]\n" \
|
317
|
+
"2. (NOT RECOMMENDED) Temporarily use unsafe loading:\n " \
|
318
|
+
"Settingslogic.use_yaml_unsafe_load = true\n\n" \
|
319
|
+
"Current permitted classes: #{self.class.yaml_permitted_classes.inspect}"
|
320
|
+
rescue Psych::BadAlias => e
|
321
|
+
# This shouldn't happen with aliases: true, but handle it just in case
|
322
|
+
raise MissingSetting, "YAML file contains aliases but they could not be processed. " \
|
323
|
+
"Error: #{e.message}"
|
324
|
+
end
|
325
|
+
|
326
|
+
# Read file contents handling both local files and URIs
|
327
|
+
# Uses Net::HTTP for security instead of open-uri
|
328
|
+
def read_file(source)
|
329
|
+
source_str = source.to_s
|
330
|
+
|
331
|
+
# Check for dangerous protocols first
|
332
|
+
if source_str.match?(%r{\A(file|ftp|gopher|ldap|dict|tftp|sftp)://}i)
|
333
|
+
raise ArgumentError, "Invalid URL protocol: #{source}"
|
334
|
+
end
|
335
|
+
|
336
|
+
if source_str.match?(%r{\Ahttps?://}i)
|
337
|
+
# For HTTP/HTTPS URLs, use Net::HTTP which is more secure
|
338
|
+
require 'net/http'
|
339
|
+
require 'uri'
|
340
|
+
|
341
|
+
uri = URI.parse(source_str)
|
342
|
+
|
343
|
+
# Security: validate the URI
|
344
|
+
raise ArgumentError, "Invalid URL: #{source}" unless uri.is_a?(URI::HTTP)
|
345
|
+
|
346
|
+
# Use Net::HTTP with proper error handling
|
347
|
+
response = Net::HTTP.get_response(uri)
|
348
|
+
|
349
|
+
case response
|
350
|
+
when Net::HTTPSuccess
|
351
|
+
response.body
|
352
|
+
else
|
353
|
+
raise "Failed to fetch #{source}: #{response.code} #{response.message}"
|
354
|
+
end
|
355
|
+
else
|
356
|
+
# For local files, use File.read which is more efficient
|
357
|
+
File.read(source_str)
|
358
|
+
end
|
359
|
+
end
|
360
|
+
end
|
metadata
ADDED
@@ -0,0 +1,172 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: mitre-settingslogic
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 3.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Ben Johnson
|
8
|
+
- MITRE SAF Team
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2025-08-11 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: bigdecimal
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - "~>"
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: '3.1'
|
21
|
+
type: :runtime
|
22
|
+
prerelease: false
|
23
|
+
version_requirements: !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - "~>"
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
version: '3.1'
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: bundler-audit
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - "~>"
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: '0.9'
|
35
|
+
type: :development
|
36
|
+
prerelease: false
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - "~>"
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '0.9'
|
42
|
+
- !ruby/object:Gem::Dependency
|
43
|
+
name: rake
|
44
|
+
requirement: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - "~>"
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: '13.2'
|
49
|
+
type: :development
|
50
|
+
prerelease: false
|
51
|
+
version_requirements: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - "~>"
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '13.2'
|
56
|
+
- !ruby/object:Gem::Dependency
|
57
|
+
name: rspec
|
58
|
+
requirement: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - "~>"
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: '3.13'
|
63
|
+
type: :development
|
64
|
+
prerelease: false
|
65
|
+
version_requirements: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - "~>"
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '3.13'
|
70
|
+
- !ruby/object:Gem::Dependency
|
71
|
+
name: rubocop
|
72
|
+
requirement: !ruby/object:Gem::Requirement
|
73
|
+
requirements:
|
74
|
+
- - "~>"
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '1.65'
|
77
|
+
type: :development
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
81
|
+
- - "~>"
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: '1.65'
|
84
|
+
- !ruby/object:Gem::Dependency
|
85
|
+
name: rubocop-performance
|
86
|
+
requirement: !ruby/object:Gem::Requirement
|
87
|
+
requirements:
|
88
|
+
- - "~>"
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: '1.21'
|
91
|
+
type: :development
|
92
|
+
prerelease: false
|
93
|
+
version_requirements: !ruby/object:Gem::Requirement
|
94
|
+
requirements:
|
95
|
+
- - "~>"
|
96
|
+
- !ruby/object:Gem::Version
|
97
|
+
version: '1.21'
|
98
|
+
- !ruby/object:Gem::Dependency
|
99
|
+
name: rubocop-rspec
|
100
|
+
requirement: !ruby/object:Gem::Requirement
|
101
|
+
requirements:
|
102
|
+
- - "~>"
|
103
|
+
- !ruby/object:Gem::Version
|
104
|
+
version: '3.0'
|
105
|
+
type: :development
|
106
|
+
prerelease: false
|
107
|
+
version_requirements: !ruby/object:Gem::Requirement
|
108
|
+
requirements:
|
109
|
+
- - "~>"
|
110
|
+
- !ruby/object:Gem::Version
|
111
|
+
version: '3.0'
|
112
|
+
- !ruby/object:Gem::Dependency
|
113
|
+
name: simplecov
|
114
|
+
requirement: !ruby/object:Gem::Requirement
|
115
|
+
requirements:
|
116
|
+
- - "~>"
|
117
|
+
- !ruby/object:Gem::Version
|
118
|
+
version: '0.22'
|
119
|
+
type: :development
|
120
|
+
prerelease: false
|
121
|
+
version_requirements: !ruby/object:Gem::Requirement
|
122
|
+
requirements:
|
123
|
+
- - "~>"
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: '0.22'
|
126
|
+
description: A simple and straightforward settings solution that uses an ERB enabled
|
127
|
+
YAML file and a singleton design pattern. This is a MITRE-maintained fork with Ruby
|
128
|
+
3.x and Rails 7.x compatibility.
|
129
|
+
email:
|
130
|
+
- saf@mitre.org
|
131
|
+
executables: []
|
132
|
+
extensions: []
|
133
|
+
extra_rdoc_files: []
|
134
|
+
files:
|
135
|
+
- CHANGELOG.md
|
136
|
+
- CONTRIBUTING.md
|
137
|
+
- LICENSE.md
|
138
|
+
- README.md
|
139
|
+
- ROADMAP.md
|
140
|
+
- SECURITY.md
|
141
|
+
- lib/settingslogic.rb
|
142
|
+
- lib/settingslogic/version.rb
|
143
|
+
homepage: https://github.com/mitre/settingslogic
|
144
|
+
licenses:
|
145
|
+
- MIT
|
146
|
+
metadata:
|
147
|
+
homepage_uri: https://github.com/mitre/settingslogic
|
148
|
+
source_code_uri: https://github.com/mitre/settingslogic
|
149
|
+
changelog_uri: https://github.com/mitre/settingslogic/blob/main/CHANGELOG.md
|
150
|
+
bug_tracker_uri: https://github.com/mitre/settingslogic/issues
|
151
|
+
documentation_uri: https://www.rubydoc.info/gems/settingslogic
|
152
|
+
rubygems_mfa_required: 'true'
|
153
|
+
post_install_message:
|
154
|
+
rdoc_options: []
|
155
|
+
require_paths:
|
156
|
+
- lib
|
157
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
158
|
+
requirements:
|
159
|
+
- - ">="
|
160
|
+
- !ruby/object:Gem::Version
|
161
|
+
version: 2.7.0
|
162
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
163
|
+
requirements:
|
164
|
+
- - ">="
|
165
|
+
- !ruby/object:Gem::Version
|
166
|
+
version: '0'
|
167
|
+
requirements: []
|
168
|
+
rubygems_version: 3.3.27
|
169
|
+
signing_key:
|
170
|
+
specification_version: 4
|
171
|
+
summary: A simple settings solution using YAML and a singleton pattern
|
172
|
+
test_files: []
|