@@ -268,9 +268,18 @@ def run_production_like(_verbose: false, route: nil, rails_env: nil)
268268 )
269269
270270 # Precompile assets with production webpack optimizations (includes pack generation automatically)
271- env_vars = [ "NODE_ENV=production" ]
272- env_vars << "RAILS_ENV=#{ rails_env } " if rails_env
273- command = "#{ env_vars . join ( ' ' ) } bundle exec rails assets:precompile"
271+ env = { "NODE_ENV" => "production" }
272+
273+ # Validate and sanitize rails_env to prevent shell injection
274+ if rails_env
275+ unless rails_env . match? ( /\A [a-z0-9_]+\z /i )
276+ puts "❌ Invalid rails_env: '#{ rails_env } '. Must contain only letters, numbers, and underscores."
277+ exit 1
278+ end
279+ env [ "RAILS_ENV" ] = rails_env
280+ end
281+
282+ argv = [ "bundle" , "exec" , "rails" , "assets:precompile" ]
274283
275284 puts "🔨 Precompiling assets with production webpack optimizations..."
276285 puts ""
@@ -288,12 +297,14 @@ def run_production_like(_verbose: false, route: nil, rails_env: nil)
288297 puts " • Gets production webpack bundles without production Rails complexity"
289298 end
290299 puts ""
291- puts "#{ Rainbow ( '💻 Running:' ) . blue } #{ command } "
300+
301+ env_display = env . map { |k , v | "#{ k } =#{ v } " } . join ( " " )
302+ puts "#{ Rainbow ( '💻 Running:' ) . blue } #{ env_display } #{ argv . join ( ' ' ) } "
292303 puts ""
293304
294305 # Capture both stdout and stderr
295306 require "open3"
296- stdout , stderr , status = Open3 . capture3 ( command )
307+ stdout , stderr , status = Open3 . capture3 ( env , * argv )
297308
298309 if status . success?
299310 puts "✅ Assets precompiled successfully"
@@ -317,11 +328,12 @@ def run_production_like(_verbose: false, route: nil, rails_env: nil)
317328 end
318329
319330 puts Rainbow ( "🛠️ To debug this issue:" ) . yellow . bold
331+ command_display = "#{ env_display } #{ argv . join ( ' ' ) } "
320332 puts "#{ Rainbow ( '1.' ) . cyan } #{ Rainbow ( 'Run the command separately to see detailed output:' ) . white } "
321- puts " #{ Rainbow ( command ) . cyan } "
333+ puts " #{ Rainbow ( command_display ) . cyan } "
322334 puts ""
323335 puts "#{ Rainbow ( '2.' ) . cyan } #{ Rainbow ( 'Add --trace for full stack trace:' ) . white } "
324- puts " #{ Rainbow ( "#{ command } --trace" ) . cyan } "
336+ puts " #{ Rainbow ( "#{ command_display } --trace" ) . cyan } "
325337 puts ""
326338 puts "#{ Rainbow ( '3.' ) . cyan } #{ Rainbow ( 'Or try with development webpack (faster, less optimized):' ) . white } "
327339 puts " #{ Rainbow ( 'NODE_ENV=development bundle exec rails assets:precompile' ) . cyan } "
0 commit comments