How to fix "Invalid Host Header"

When you run Redwood in dev mode, and would like to test the application as it is rendered from an external source (outside of your network), you will get “Invalid Host Header” when trying to get to the 8910 port (or the one that will be forwarded out).
The fix for that is coming from adding a setting to the webpack configuration as follows:
// web/config/webpack.config.js
module.exports = (config) => {
. config.devServer.disableHostCheck = true
return config
}

This will not be rendered in your production build. This is only for development needs.

3 Likes

Do you know what the implications are for not making this a standard in Redwood’s Webpack configuration?

The most problematic one is that leaving this open, allows hackers to take over the source, complied source and inject malicious code (read more here .)
Due to the fact that the current settings of the Redwood dev server is only with localhost, although there is an option to change it to 0.0.0.0, it is still a problem

There are several options to work with the dev server and test it with an “external” network:

  1. setup the whole environment in a Docker (or any other) container. This is currently an option that is not simple as it requires additional changes to the code base of the dev server as well as the default redwood app.
  2. as the above mentioned article suggests, have the following added to the webpack start script (currently there is no option to add these changes to the yarn rw dev ):
    --host 0.0.0.0 --public example.company.com, where the example.company.com is the external URL for the dev server.

Testing is an important stage of every development process, and one of them is to test the site from an “external” network that has other settings, like for example, mobile device (that has applications installed), other restrictions, etc. You don’t want to get to ta production release and then test these issues.

1 Like

@wiezmankimchi The use case and need 100% makes sense! To be clear, are you suggesting the secure way to implement this would be the following:

  1. add the config to our webpack.development.js file (link here)
  2. add the --host and --public command options to yarn rw dev, with default to something like --host [redwood.toml.api.host] and --public [null | undefined] (or something like that)

yes/no/maybe?

@thedavid,
yes. Excellent idea. This will allow to start the dev server with any host and any public facing address.

We could forward the args from yarn rw dev web to webpack-dev-server, since the port and hostname options are already configurable:

yarn webpack-dev-server --help
yarn run v1.22.4
$ /Users/peterp/Personal/redwoodjs/redwood/node_modules/.bin/webpack-dev-server --help
webpack-dev-server 3.10.3
webpack 4.43.0
Usage:  https://webpack.js.org/configuration/dev-server/

Config options:
  --config               Path to the config file
                         [string] [default: webpack.config.js or webpackfile.js]
  --config-register, -r  Preload one or more modules before loading the webpack
                         configuration      [array] [default: module id or path]
  --config-name          Name of the config to use                      [string]
  --env                  Environment passed to the config, when it is a function
  --mode                 Enable production optimizations or development hints.
                                  [choices: "development", "production", "none"]

Basic options:
  --context    The base directory (absolute path!) for resolving the `entry`
               option. If `output.pathinfo` is set, the included pathinfo is
               shortened to this directory.
                                       [string] [default: The current directory]
  --entry      The entry point(s) of the compilation.                   [string]
  --no-cache   Disables cached builds                                  [boolean]
  --watch, -w  Enter watch mode, which rebuilds on file change.        [boolean]
  --debug      Switch loaders to debug mode                            [boolean]
  --devtool    A developer tool to enhance debugging.                   [string]
  -d           shortcut for --debug --devtool eval-cheap-module-source-map
               --output-pathinfo                                       [boolean]
  -p           shortcut for --optimize-minimize --define
               process.env.NODE_ENV="production"                       [boolean]
  --progress   Print compilation progress in percentage                [boolean]

Module options:
  --module-bind       Bind an extension to a loader                     [string]
  --module-bind-post  Bind an extension to a post loader                [string]
  --module-bind-pre   Bind an extension to a pre loader                 [string]

Output options:
  --output, -o                  The output path and file for compilation assets
  --output-path                 The output directory as **absolute path**
                                (required).
                                       [string] [default: The current directory]
  --output-filename             Specifies the name of each output file on disk.
                                You must **not** specify an absolute path here!
                                The `output.path` option determines the location
                                on disk the files are written to, filename is
                                used solely for naming the individual files.
                                                   [string] [default: [name].js]
  --output-chunk-filename       The filename of non-entry chunks as relative
                                path inside the `output.path` directory.
       [string] [default: filename with [id] instead of [name] or [id] prefixed]
  --output-source-map-filename  The filename of the SourceMaps for the
                                JavaScript files. They are inside the
                                `output.path` directory.                [string]
  --output-public-path          The `publicPath` specifies the public URL
                                address of the output files when referenced in a
                                browser.                                [string]
  --output-jsonp-function       The JSONP function used by webpack for async
                                loading of chunks.                      [string]
  --output-pathinfo             Include comments with information about the
                                modules.                               [boolean]
  --output-library              Expose the exports of the entry point as library
                                                                         [array]
  --output-library-target       Type of library
         [string] [choices: "var", "assign", "this", "window", "self", "global",
      "commonjs", "commonjs2", "commonjs-module", "amd", "umd", "umd2", "jsonp"]

Advanced options:
  --records-input-path       Store compiler state to a json file.       [string]
  --records-output-path      Load compiler state from a json file.      [string]
  --records-path             Store/Load compiler state from/to a json file. This
                             will result in persistent ids of modules and
                             chunks. An absolute path is expected. `recordsPath`
                             is used for `recordsInputPath` and
                             `recordsOutputPath` if they left undefined.[string]
  --define                   Define any free var in the bundle          [string]
  --target                   Environment to build for                   [string]
  --cache                    Cache generated modules and chunks to improve
                             performance for multiple incremental builds.
                      [boolean] [default: It's enabled by default when watching]
  --watch-stdin, --stdin     close when stdin ends                     [boolean]
  --watch-aggregate-timeout  Delay the rebuilt after the first change. Value is
                             a time in ms.                              [number]
  --watch-poll               Enable polling mode for watching           [string]
  --hot                      Enables Hot Module Replacement            [boolean]
  --prefetch                 Prefetch this request (Example: --prefetch
                             ./file.js)                                 [string]
  --provide                  Provide these modules as free vars in all modules
                             (Example: --provide jQuery=jquery)         [string]
  --labeled-modules          Enables labeled modules                   [boolean]
  --plugin                   Load this plugin                           [string]
  --bail                     Report the first error as a hard error instead of
                             tolerating it.            [boolean] [default: null]
  --profile                  Print compilation profile data for progress steps
                                                       [boolean] [default: null]
  --hot-only                 Do not refresh page if HMR fails          [boolean]

Resolving options:
  --resolve-alias         Redirect module requests                      [string]
  --resolve-extensions    Redirect module requests                       [array]
  --resolve-loader-alias  Setup a loader alias for resolving            [string]

Optimizing options:
  --optimize-max-chunks      Try to keep the chunk count below a limit
  --optimize-min-chunk-size  Minimal size for the created chunk
  --optimize-minimize        Enable minimizing the output. Uses
                             optimization.minimizer.                   [boolean]

Stats options:
  --color, --colors, --colors     Enables/Disables colors on the console
                                           [boolean] [default: (supports-color)]
  --no-color, --no-colors         Force no colors on the console       [boolean]
  --sort-modules-by               Sorts the modules list by property in module
                                                                        [string]
  --sort-chunks-by                Sorts the chunks list by property in chunk
                                                                        [string]
  --sort-assets-by                Sorts the assets list by property in asset
                                                                        [string]
  --hide-modules                  Hides info about modules             [boolean]
  --display-exclude               Exclude modules in the output         [string]
  --display-modules               Display even excluded modules in the output
                                                                       [boolean]
  --display-max-modules           Sets the maximum number of visible modules in
                                  output                                [number]
  --display-chunks                Display chunks in the output         [boolean]
  --display-entrypoints           Display entry points in the output   [boolean]
  --display-origins               Display origins of chunks in the output
                                                                       [boolean]
  --display-cached                Display also cached modules in the output
                                                                       [boolean]
  --display-cached-assets         Display also cached assets in the output
                                                                       [boolean]
  --display-reasons               Display reasons about module inclusion in the
                                  output                               [boolean]
  --display-depth                 Display distance from entry point for each
                                  module                               [boolean]
  --display-used-exports          Display information about used exports in
                                  modules (Tree Shaking)               [boolean]
  --display-provided-exports      Display information about exports provided
                                  from modules                         [boolean]
  --display-optimization-bailout  Display information about why optimization
                                  bailed out for modules               [boolean]
  --display-error-details         Display details about errors         [boolean]
  --display                       Select display preset
              [string] [choices: "", "verbose", "detailed", "normal", "minimal",
                                                          "errors-only", "none"]
  --verbose                       Show more details                    [boolean]
  --info-verbosity                Controls the output of lifecycle messaging
                                  e.g. Started watching files...
                 [string] [choices: "none", "info", "verbose"] [default: "info"]
  --build-delimiter               Display custom text after build output[string]
  --info                          Info                 [boolean] [default: true]
  --quiet                         Quiet                                [boolean]
  --client-log-level              Log level in the browser (trace, debug, info,
                                  warn, error or silent)
                                                      [string] [default: "info"]

SSL options:
  --https           HTTPS                                              [boolean]
  --http2           HTTP/2, must be used with HTTPS                    [boolean]
  --key             Path to a SSL key.                                  [string]
  --cert            Path to a SSL certificate.                          [string]
  --cacert          Path to a SSL CA certificate.                       [string]
  --pfx             Path to a SSL pfx file.                             [string]
  --pfx-passphrase  Passphrase for pfx file.                            [string]

Response options:
  --content-base          A directory or URL to serve HTML content from.[string]
  --watch-content-base    Enable live-reloading of the content-base.   [boolean]
  --history-api-fallback  Fallback to /index.html for Single Page Applications.
                                                                       [boolean]
  --compress              Enable gzip compression                      [boolean]

Connection options:
  --port                The port
  --disable-host-check  Will not check the host                        [boolean]
  --socket              Socket to listen
  --public              The public hostname/ip address of the server    [string]
  --host                The hostname/ip address the server will bind to
                                                 [string] [default: "localhost"]
  --allowed-hosts       A comma-delimited string of hosts that are allowed to
                        access the dev server                           [string]

Options:
  --help, -h    Show help                                              [boolean]
  --silent      Prevent output from being displayed in stdout          [boolean]
  --json, -j    Prints the result as JSON.                             [boolean]
  --version     Show version number                                    [boolean]
  --bonjour     Broadcasts the server via ZeroConf networking on start [boolean]
  --lazy        Lazy                                                   [boolean]
  --liveReload  Enables/Disables live reloading on changing files
                                                       [boolean] [default: true]
  --serveIndex  Enables/Disables serveIndex middleware [boolean] [default: true]
  --inline      Inline mode (set to false to disable including client scripts
                like livereload)                       [boolean] [default: true]
  --open        Open the default browser, or optionally specify a browser name
                                                                        [string]
  --useLocalIp  Open default browser with local IP                     [boolean]
  --open-page   Open default browser with the specified page            [string]
✨  Done in 1.04s.

@peterp Do you want to outline this approach as a GH Issue with a “help wanted” label? I bet we’d have quick turnaround with a community PR.

Done. #534

Thanks @wiezmankimchi! I edited for formatting readability if you’d like to confirm. But left text the same, added labels, and added my suggested solution.

1 Like

Great. Thank you.

Thank you again for an excellent work on the Redwood solution. It is a great (and going to be even a greater one) solution

3 Likes