tendermint: Unable to specify cors_allowed_origins via command line

A tendermint upgrade 0.25.x -> 0.27.4 now forces me to set cors_allowed_origins instead of auto-generating the header from the request.

However, I am not able to set the value via command line (--rpc.cors_allowed_origins), as I do with laddr.

This is how I start Tendermint:

docker run --user="$UID" \
  --name "$NAME" \
  -p "${PORT}:26657" -v "${TMP_DIR}:/tendermint" \
  -e "TM_TX_INDEX_INDEX_ALL_TAGS=true" \
  "tendermint/tendermint:${VERSION}" node \
  --proxy_app=kvstore \
  --rpc.laddr=tcp://0.0.0.0:26657 \
  --rpc.cors_allowed_origins='["*"]' \
  --log_level=state:info,rpc:info,*:error \
  > "$LOGFILE" &

Which leads to the following error output

$ ./scripts/tendermint/all_start.sh 
Starting tendermint-27 (0.27.4) on port 11127 ...
Using temporary dir /var/folders/98/71tcbww552n4w9npxt0v0hmr0000gn/T//tendermint.ufN1PniE0
0.27.4: Pulling from tendermint/tendermint
Digest: sha256:6a6691c448554392ab05c0b5754489e02628d9539d3887458bdc4f69251697cd
Status: Image is up to date for tendermint/tendermint:0.27.4
I[28016-01-28|08:42:11.264] Generated private validator                  module=main path=/tendermint/config/priv_validator.json
I[28016-01-28|08:42:11.267] Generated node key                           module=main path=/tendermint/config/node_key.json
I[28016-01-28|08:42:11.274] Generated genesis file                       module=main path=/tendermint/config/genesis.json
Tendermint running and logging into /var/folders/98/71tcbww552n4w9npxt0v0hmr0000gn/T//tendermint.ufN1PniE0/tendermint.log
ERROR: unknown flag: --rpc.cors_allowed_origins

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Comments: 22 (17 by maintainers)

Most upvoted comments

Unpopular opinion here: CORS in the current setup is not really useful. We should rip it out of tendermint and leave it to the web security layer above (nginx or load-balancers). OR we have to implement TLS too. The only people who could maybe benefit from the current setup are developers and developer setups usually don’t need CORS. Also, it cannot be nicely implemented in production.

  1. CORS does not limit who can access the API. It is the browser who makes that limitation. I can still easily browse the API, from a script, for example and ignore origin headers. CORS only has value, if the API is used from a client-side web interface on a different domain, like for example a VueJS website.
  2. CORS keeps the protocol across the client and the server. This means that if tendermint runs plain-text (http), only http websites will be able to connect to it (and only the ones that are allowed in the CORS header, obviously). Usually, the websites run https, so tendermint needs to run https for the connection to work.

Because of the above two properties, when implementing a web frontend for tendermint, there has to be a TLS layer implemented somewhere (nginx, ELB, etc) so the website can connect to tendermint over https. That TLS layer already supports CORS and it’s usually well understood how to set it up.

I discourage the team from implementing TLS into tendermint - for now. TLS is a complex technology and implementing a half-baked solution does more harm to security than completely leaving it to mature products. GaiaD is suffering from exactly this problem. Self-signed certificates (since you need to have something at start) are a false sense of security and a pain in the butt when trying to implement any load-balancing in front of the service. Not to mention, that client websites will still have problems with it, until the certificate is imported as trusted.

Obviously, there might be better solution here that I didn’t discuss in length, this note is just to raise a few key points. If we keep going in this direction, it would be nice to have an option to completely disable CORS/TLS the same way we have the option to enable/disable routing restrictions based on internal IP addresses. (I had a similar argument back then, to not implement IP routing rules in Tendermint and the compromise was that it can be enabled/disabled.)

@melekes I just tried to do the above update and validated that simply updating viper dependency in Gopkg.toml and running dep ensure will make the string slice parsing work.

[[constraint]]
  name = "github.com/spf13/viper"
  version = "^1.3.1"

Not really such a bad idea, since the currenly pinned v1.0.0 is a year and a half old…

Thanks! Unfortunately I did not have luck with any of those -e “TM_RPC_CORS_ALLOWED_ORIGINS=‘‘" -e "TM_RPC_CORS_ALLOWED_ORIGINS=’""’” -e “TM_RPC_CORS_ALLOWED_ORIGINS=‘["*"]’”

Note, the reason it is like this, is we use the generic tendermint docker image, but want to configure it run time, rather than add a new subimage and docker build. Seems like a reasonable use-case.

I think there are two issues:

  1. How to set cors in the commandline in the current builds (using env vars or otherwise)
  2. How to properly implement cors support (note gregs suggestion above).

A tested solution to point 1 would close this issue. I think the discussion around 2 is valuable to have as a separate issue to finalize how cors should work by the 1.0 release

@greg-szabo I just verified (I’m not an expert here): a website at http://localhost:9876 is not allowd to access Tendermint at http://localhost:11127/. This makes sense when you check the definition of origin in CORS: An origin is defined as a combination of URI scheme, host name, and port number.

Some tests what you can access from a browser:

  1. Full tab http://localhost:11127/status works
  2. <iframe src="http://localhost:11127/status"></iframe> works
  3. <script>fetch("http://localhost:11127/status")</script> does not work
  4. <script>fetch("http://localhost:11127/status", {mode: "cors"})</script> does not work
  5. <script>fetch("http://localhost:11127/status", {mode: "no-cors"})</script> performs a request but the result is not available in JavaScript
  6. <script>fetch("http://localhost:11127/status", {mode: "same-origin"})</script> is blocked because it is not the same origin

So the only thing you can do from a browser in terms of API access is having a manual loock at the JSON document.

Thanks for raising your concerns @greg-szabo 👍 Definitely some food for thought here. We’ll probably need to think more before making any further decisions on this.

Note: CORS can be turned on/off using the config (it’s off by default now).

Original issue: https://github.com/tendermint/tendermint/issues/2582

Yes, the command line flags are a small subset of the config flags, there is a clear mapping when they are present, but most are not exposed on the cli. The only option is to add this to the config:

Here are all command-line flags accepted by tendermint node: https://github.com/tendermint/tendermint/blob/master/cmd/tendermint/commands/run_node.go#L14-L46

For comparison, here is the list of all rpc flags supported from the config: https://github.com/tendermint/tendermint/blob/master/config/config.go#L285-L326

If you do not want to (or cannot) modify the config file, you can also use the little-documented environmental variables. Just as -e "TM_TX_INDEX_INDEX_ALL_TAGS=true" will set a config argument not exposed over the cli flags, you can also use a similar mapping to convert rpc.cors_allowed_origins to TM_RPC_CORS_ALLOWED_ORIGINS='*' (I think that is the proper format here, maybe '["*"]' as you wrote)