{"record":{"id":"105497a46817d23e","repo":"puppetlabs/puppet","slug":"the-environment-must-be-purely-alphanumeric-not","errorCode":null,"errorMessage":"The environment must be purely alphanumeric, not '%{environment}'","messagePattern":"The environment must be purely alphanumeric, not '%(.+?)'","errorType":"http","errorClass":"Puppet::Network::HTTP::Error::HTTPBadRequestError","httpStatus":400,"severity":"error","filePath":"lib/puppet/network/http/api/indirected_routes.rb","lineNumber":90,"sourceCode":"    # request\n    if url_prefix != IndirectionType.url_prefix_for(indirection_name)\n      raise Puppet::Network::HTTP::Error::HTTPBadRequestError, _(\"Indirection '%{indirection_name}' does not match url prefix '%{url_prefix}'\") % { indirection_name: indirection_name, url_prefix: url_prefix }\n    end\n\n    indirection = Puppet::Indirector::Indirection.instance(indirection_name.to_sym)\n    unless indirection\n      raise Puppet::Network::HTTP::Error::HTTPNotFoundError.new(\n        _(\"Could not find indirection '%{indirection_name}'\") % { indirection_name: indirection_name },\n        Puppet::Network::HTTP::Issues::HANDLER_NOT_FOUND\n      )\n    end\n\n    unless environment\n      raise Puppet::Network::HTTP::Error::HTTPBadRequestError, _(\"An environment parameter must be specified\")\n    end\n\n    unless Puppet::Node::Environment.valid_name?(environment)\n      raise Puppet::Network::HTTP::Error::HTTPBadRequestError, _(\"The environment must be purely alphanumeric, not '%{environment}'\") % { environment: environment }\n    end\n\n    configured_environment = Puppet.lookup(:environments).get(environment)\n    unless configured_environment.nil?\n      configured_environment = configured_environment.override_from_commandline(Puppet.settings)\n      params[:environment] = configured_environment\n    end\n\n    if configured_environment.nil? && indirection.terminus.require_environment?\n      raise Puppet::Network::HTTP::Error::HTTPNotFoundError, _(\"Could not find environment '%{environment}'\") % { environment: environment }\n    end\n\n    params.delete(:bucket_path)\n\n    if key == \"\" or key.nil?\n      raise Puppet::Network::HTTP::Error::HTTPBadRequestError, _(\"No request key specified in %{uri}\") % { uri: uri }\n    end\n","sourceCodeStart":72,"sourceCodeEnd":108,"githubUrl":"https://github.com/puppetlabs/puppet/blob/e227c27540975c25aa22d533a52424a9d2fc886a/lib/puppet/network/http/api/indirected_routes.rb#L72-L108","documentation":"Before resolving an environment, the handler checks Puppet::Node::Environment.valid_name?, which only accepts word characters (letters, digits, underscore) via /\\A\\w+\\Z/. Environment names containing dashes, dots, slashes or any other punctuation are rejected with HTTP 400. This guards the filesystem-backed environment lookup against malformed and path-traversal names.","triggerScenarios":"Requests with environment=my-env (dash), environment=prod.example.com (dot) or environment=../../etc (traversal attempt); an agent whose environment setting was derived from a git branch name containing '-' or '/'.","commonSituations":"Sites naming environments after git branches that contain dashes or slashes; environment names copied from hostnames/DNS labels with dots; automated scanners probing the API with relative paths. Environment directory names on the master must be alphanumeric/underscore for the API to accept them.","solutions":["Rename the environment so it contains only letters, digits and underscores (my_env, not my-env)","If environments come from branch names, sanitize them when deploying (r10k/code-manager mapping) instead of passing raw branch names","Fix the agent's environment setting in puppet.conf so it sends a valid name","Normalize or reject suspicious environment values at the edge if the API is exposed to untrusted clients"],"exampleFix":"# before (branch name with slash and dash used directly)\ncurl \"https://puppet:8140/puppet/v3/catalog/mynode?environment=feature/x-1\"\n\n# after (branch mapped to a safe environment name on deploy)\ncurl \"https://puppet:8140/puppet/v3/catalog/mynode?environment=feature_x_1\"","handlingStrategy":"validation","validationCode":"def valid_environment_name?(name)\n  name.is_a?(String) && name.match(/\\A\\w+\\Z/)\nend\n\nraise ArgumentError, \"invalid environment name #{env.inspect}\" unless valid_environment_name?(env)","typeGuard":"def valid_environment_name?(name)\n  name.is_a?(String) && name.match(/\\A\\w+\\Z/)\nend","tryCatchPattern":null,"preventionTips":["Enforce word-character naming when branch-based environments are created (r10k hooks, ENCs)","Validate environment names at the edge instead of relying on the API 400 to catch them"],"tags":["http","environment","validation","security"],"backgroundTag":"invalid-parameter-name","analyzedSha":"e227c27540975c25aa22d533a52424a9d2fc886a","analyzedAt":"2026-08-21T20:49:46.650Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}