-
Notifications
You must be signed in to change notification settings - Fork 17
Sync with upstream v347 #148
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
* Update Node version to 24.x LTS Node 24 [has been LTS since October 2025](https://nodejs.org/en/blog/release/v24.11.0) Signed-off-by: Stefan Wrobel <swrobel@users.noreply.github.com> * Changelog * Apply suggestions from code review Co-authored-by: Stefan Wrobel <swrobel@users.noreply.github.com> Signed-off-by: Richard Schneeman <richard.schneeman+no-recruiters@gmail.com> --------- Signed-off-by: Stefan Wrobel <swrobel@users.noreply.github.com> Signed-off-by: Richard Schneeman <richard.schneeman+no-recruiters@gmail.com> Co-authored-by: Stefan Wrobel <swrobel@users.noreply.github.com>
…et (heroku#1700) * Set WEB_CONCURRENCY_SET_BY=heroku/ruby if WEB_CONCURRENCY gets auto-set The Ruby buildpack sets the `WEB_CONCURRENCY` env var at app boot based on the current dyno size if the (deprecated) `SENSIBLE_DEFAULTS` mode is enabled, so long as the user hasn't specified a custom value via the app's config vars. Now, in addition to setting the `WEB_CONCURRENCY` env var, the buildpack will also set `WEB_CONCURRENCY_SET_BY=heroku/ruby` to allow the app, other boot time scripts, or humans more easily differentiate between a user and a buildpack provided `WEB_CONCURRENCY` (and determine which buildpack actually set it). In addition to assisting with debugging, this allows for UX improvements in other buildpacks such as the PHP buildpack, which can now check for `WEB_CONCURRENCY_SET_BY` in its boot time Apache/Nginx `heroku-php-...` scripts to ignore `WEB_CONCURRENCY` in cases where users have ordered the buildpacks on their app in the wrong order (the "primary" language is supposed to be listed last, otherwise the wrong concurrency value will be used). See also: heroku/heroku-buildpack-nodejs#932 heroku/heroku-buildpack-python#2015 GUS-W-20882005 * Track SENSIBLE_DEFAULTS usage This feature is deprecated, let's see how many people still rely on it. --------- Signed-off-by: Richard Schneeman <rschneeman@salesforce.com> Co-authored-by: Richard Schneeman <rschneeman@salesforce.com>
* Add standardrb gem for Ruby linting
* Add standardrb to CI lint job
* Auto-fix standardrb violations
* Add .standard.yml to exclude test fixture repos from linting
The repos/ directory contains external Rails application fixtures used for
integration testing. These should not be linted as they represent external
code, not the buildpack's own code.
* Fix Style/StringLiterals in Gemfile
Lint failure: Style/StringLiterals - Prefer double-quoted strings unless you
need single quotes to avoid extra backslashes for escaping.
The fix uses double quotes consistently for all gem declarations, matching
the style used by the rest of the Gemfile.
* Disable lint rules for intentional patterns in bin/support scripts
Lint failures disabled:
- Lint/RescueException: Rescuing Exception is intentional in buildpack entry
points to ensure all errors (including SignalException, SystemExit) are
properly reported to users rather than causing cryptic failures.
- Style/MixinUsage: Including modules at top level is intentional for these
standalone scripts, which are not library code and benefit from direct
access to shell helper methods.
* Fix lint violations in heroku_build_report.rb
Lint failures:
- Lint/NonLocalExitFromIterator: Changed 'return' to 'next' in the each block.
Using 'return' would exit the entire capture method, while 'next' correctly
skips to the next iteration.
- Style/RedundantInterpolation: Changed "\#{key}" to key.to_s since the key
is already a string after strip. This is more explicit and avoids
unnecessary string interpolation.
* Fix lint violations in language_pack.rb
Lint failures:
- Lint/AssignmentInCondition: Wrapped 'pack = LanguagePack.detect(...)' in
parentheses to clarify that the assignment is intentional.
- Style/SafeNavigation: Changed 'if pack_klass; pack_klass.new(...); end'
to 'pack_klass&.new(...)' using safe navigation operator. This is more
idiomatic Ruby and clearly expresses the intent to call new only if
pack_klass is not nil.
* Fix Performance/UnfreezeString violations
Lint failure: Performance/UnfreezeString - Use unary plus to get an unfrozen
string literal.
Changed String.new("") and String.new("...") to +"" and +"..."
respectively. The unary plus operator on a frozen string literal returns
an unfrozen copy, which is more idiomatic and performant than String.new.
These mutable strings are necessary because we append to them with <<.
* Fix Lint/AssignmentInCondition and Lint/MixedRegexpCaptureTypes
Lint failures fixed:
- Lint/AssignmentInCondition: Wrapped 'if var = expr' in parentheses to
clarify that the assignment is intentional, not a typo for '=='.
- Lint/MixedRegexpCaptureTypes: Changed numbered capture groups (\r?\n)
to non-capturing groups (?:\r?\n) in regex patterns. Mixing named and
numbered captures causes confusion because numbered captures are
renumbered when named captures are present, making the regex behavior
unpredictable.
* Fix Style/RedundantSort in outdated_ruby_version.rb
Lint failure: Style/RedundantSort - Use max_by instead of sort_by...last.
Changed 'sort_by { |v| Gem::Version.new(v) }.last' to
'max_by { |v| Gem::Version.new(v) }'. Using max_by is more efficient as it
finds the maximum in O(n) time without sorting the entire array, and clearly
expresses the intent to find the maximum value.
* Fix Lint/DuplicateMethods in rake_runner.rb
Lint failure: Lint/DuplicateMethods - Method RakeTask#status is defined at
both line 11 (via attr_accessor) and line 37 (explicit def).
The explicit status method includes validation logic that ensures the status
is set to an allowed value before returning it. Changed 'attr_accessor :status'
to 'attr_writer :status' so we only generate the setter, keeping the custom
getter with its validation logic.
* Fix lint violations in ruby.rb
Lint failures fixed:
- Performance/UnfreezeString: Changed String.new("") to +"" for creating
a mutable string to append to.
- Lint/BinaryOperatorWithIdenticalOperands: Fixed 'version != version' which
always evaluates to false. Changed to 'old_version != version' to correctly
detect when the default Node.js/Yarn version has changed. This was a bug
where the version change warning would never be displayed.
- Lint/IneffectiveAccessModifier: Added file-level ignore in .standard.yml.
The class has public class methods interspersed after a 'private' declaration
that only affects instance methods. The class methods are intentionally
public and called from lib/language_pack.rb.
* Fix lint violations in ruby_version.rb and shell_helpers.rb
Lint failures fixed:
- Style/RedundantInterpolation: Changed "\#{engine_version}" to
engine_version.to_s and "\#{path}" to path.to_s. String interpolation
on a single variable is redundant when the variable is already a string
or should be explicitly converted.
- Removed unused RUBY_VERSION_REGEX constant (dead code).
* Fix lint violations in spec files
Lint failures fixed:
- Lint/RescueException (ruby_spec.rb): Added inline disable. The test
rescues Exception intentionally to provide debugging output for any failure.
- Style/RedundantInterpolation (outdated_ruby_version_spec.rb): Removed
redundant string interpolation.
- Lint/ShadowedArgument (ruby_version_spec.rb): Renamed block arg to _dir
since it's immediately shadowed by a local variable assignment.
- Lint/ConstantDefinitionInBlock (shell_spec.rb): Added inline disable.
Defining test helper classes inside describe blocks is a common RSpec pattern.
- Lint/DuplicateRequire (spec_helper.rb): Removed duplicate require 'hatchet'.
- Lint/MixedRegexpCaptureTypes (spec_helper.rb): Changed numbered capture
group to non-capturing group.
- Lint/DuplicateMethods (spec_helper.rb): Removed duplicate hatchet_path
method definition.
* Fix Layout/IndentationConsistency in ruby.rb
Lint failure: Layout/IndentationConsistency - Inconsistent indentation detected.
Fixed extra indentation on the bundle_command assignment line.
* Changelog
* Remove unused include
* Apply linting fixes
Co-authored-by: heroku-linguist[bot] <136119646+heroku-linguist[bot]@users.noreply.github.com>
Track apps with and without `BUNDLED WITH` in the `Gemfile.lock`. This will show how many apps are using the default bundler version.
| # @option options [Boolean] :user_env whether or not a user's environment variables will be loaded | ||
| def run(command, options = {}) | ||
| %x{ #{command_options_to_string(command, options)} } | ||
| `#{command_options_to_string(command, options)}` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Semgrep identified an issue in your code:
Shell command injection via unsanitized user input in backtick command execution. Attackers can inject arbitrary commands if the command parameter is controlled by untrusted sources.
More details about this
The run method executes a shell command constructed by interpolating command_options_to_string(command, options) directly into a backtick command. If the command parameter comes from unverified user input, an attacker can inject arbitrary shell code.
Exploit scenario:
- An attacker provides a malicious
commandlike"echo safe; rm -rf /"to therun()method - The
command_options_to_string()function wraps it:/usr/bin/env bash -c echo safe; rm -rf / 2>&1 - The backtick operator executes this in a shell, where the semicolon allows chaining commands
- The attacker's injected
rm -rf /command runs with the privileges of the Ruby process
Even though command.shellescape is used inside command_options_to_string(), the function returns a string that is then directly interpolated into the backtick without proper quoting, bypassing the escaping protection.
To resolve this comment:
✨ Commit Assistant fix suggestion
| `#{command_options_to_string(command, options)}` | |
| require 'open3' | |
| def run(command, options = {}) | |
| command_array = command_options_to_array(command, options) # We'll define this helper below | |
| stdout_str, status = Open3.capture2e(*command_array) | |
| stdout_str | |
| end | |
| # Helper method to return an array for command and args for Open3 | |
| def command_options_to_array(command, options) | |
| options[:env] ||= {} | |
| options[:env] = user_env_hash.merge(options[:env]) if options[:user_env] | |
| env = options[:env].transform_keys(&:to_s) | |
| # Build the bash command part safely | |
| bash_command = command.to_s | |
| # Anything to redirect output (e.g., "2>&1") is best handled in Ruby itself, not shell, to avoid injection. | |
| # We'll ignore options[:out] to avoid passing dangerous redirects; Open3.capture2e already merges stderr into stdout. | |
| [env, '/usr/bin/env', 'bash', '-c', bash_command] | |
| end |
View step-by-step instructions
- Avoid using backticks with string interpolation to execute shell commands, as this can allow command injection if any part of the command or options is user-controlled.
- Replace the line
`#{command_options_to_string(command, options)}`with usage of the safer Open3 or system method, which accepts command and arguments as an array. - Refactor
command_options_to_stringto return an array: for example, split up the command and its arguments so you can pass them toOpen3.capture2eorsystem. - In the
runmethod, replace the dangerous call with:Open3.capture2e(*command_array)(after requiringopen3at the top of the file:require 'open3'), wherecommand_arrayis the securely built command and its arguments. - Make sure to never pass user-controlled input directly to the shell unless properly validated or escaped.
Alternatively, if you must use backticks,
validate and strictly sanitize all parts of the command string to only allow safe, expected values. This is less robust than avoiding the shell entirely.
💬 Ignore this finding
Reply with Semgrep commands to ignore this finding.
/fp <comment>for false positive/ar <comment>for acceptable risk/other <comment>for all other reasons
Alternatively, triage in Semgrep AppSec Platform to ignore the finding created by dangerous-subshell.
You can view more details about this finding in the Semgrep AppSec Platform.
If your `Gemfile.lock` doesn’t include the `BUNDLED WITH` key, Heroku installs a [default bundler version](https://devcenter.heroku.com/articles/ruby-support-reference#default-bundler-version): - Apps using [Classic Buildpacks](https://devcenter.heroku.com/articles/buildpacks#classic-buildpacks) was `2.3.25` now `2.5.23` - Apps using [Cloud Native Buildpacks](https://devcenter.heroku.com/articles/buildpacks#heroku-cloud-native-buildpacks) stays `2.5.23` >note >Ruby's [standard version of bundler](https://stdgems.org/bundler/) takes precedence if it's greater than Heroku's installed version. When there is no `BUNDLED WITH` in the `Gemfile.lock`, then `bundle install` uses the highest version of Bundler available. It is strongly recommended that you have both a `RUBY VERSION` and `BUNDLED WITH` version listed in your `Gemfile.lock`. If you do not have those values, you can generate them and commit them to git: ``` $ bundle update --ruby $ git add Gemfile.lock $ git commit -m "Update Gemfile.lock" ``` Applications without these values specified in the `Gemfile.lock` may break unexpectedly when the defaults change. This is an alternative to downgrading the CNB version heroku#1706 (comment).
…eroku#1709) Bumps the ruby-dependencies group with 1 update: [standard](https://github.com/standardrb/standard). Updates `standard` from 1.52.0 to 1.53.0 - [Release notes](https://github.com/standardrb/standard/releases) - [Changelog](https://github.com/standardrb/standard/blob/main/CHANGELOG.md) - [Commits](standardrb/standard@v1.52.0...v1.53.0) --- updated-dependencies: - dependency-name: standard dependency-version: 1.53.0 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: ruby-dependencies ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: heroku-linguist[bot] <136119646+heroku-linguist[bot]@users.noreply.github.com>
Co-authored-by: heroku-linguist[bot] <136119646+heroku-linguist[bot]@users.noreply.github.com>
Related to #147