DeFiCh / ain

DeFi Blockchain - enabling decentralized finance on Bitcoin
https://defichain.com
MIT License
402 stars 120 forks source link

Add CORS headers to JSONRPC response #1591

Open DerFuchs opened 1 year ago

DerFuchs commented 1 year ago

What would you like to be added:

To access a locally running full wallet with a web-based application, it is necessary to return CORS (Cross-Origin Resource Sharing) headers from localhost.

See: https://enable-cors.org/

Why is this needed:

That's essential to develop apps based on web components. The full node UI is running on Electron, which is basically a Chrome browser without UI. Looking into this application's source code, this flag is turned off:

webPreferences: { webSecurity: false }

Which is declared as not a good practice, but acceptable when not loading data from any public source.

It should not be problematic to return these headers by default or by parameter flag, at least from my current perspective. If there's any concern about that, please let me know!

When returning these headers, the full node UI should be okay to turn that webSecurity flag back to true.

And there are circumstances when developers want to access the full node as well, but also want to gather data from other sources than just the full node. In this case, I'd love to be able to enable that webSecurity flag as well. Then I'd be able to use the Jellyfish SDK in my electron application instead of writing my own integration with fake CORS headers.

defichain-bot commented 1 year ago

@DerFuchs: Thanks for opening an issue, it is currently awaiting triage.

The triage/accepted label can be added by foundation members by writing /triage accepted in a comment.

Details I am a bot created to help the [DeFiCh](https://github.com/DeFiCh) developers manage community feedback and contributions. You can check out my [manifest file](https://github.com/DeFiCh/ain/blob/master/.github/governance.yml) to understand my behavior and what I can do. If you want to use this for your project, you can check out the [DeFiCh/oss-governance-bot](https://github.com/DeFiCh/oss-governance-bot) repository.
prasannavl commented 1 year ago

Hi @DerFuchs -- doesn't https://github.com/DeFiCh/ain/pull/330 that was added a few years ago, address what you need?

prasannavl commented 1 year ago

For well understood usage domains where the use is justified, enabling of CORS headers is supported using -rpcallowcors=<host> - but this cannot be made default as it changes the security exposure.

DerFuchs commented 1 year ago

Hi @prasannavl! Thank you for your hint in direction of that rpcallowcors parameter. That's nice when the user is in full control of the wallet. But the usual user of the desktop wallet is not. That does not help me in what I am planning to develop.

So, I guess I have to keep the webSecurity of my Electron app disabled, just like the desktop wallet. I'll figure out another way :)

prasannavl commented 1 year ago

To access a locally running full wallet with a web-based application, it is necessary to return CORS (Cross-Origin Resource Sharing) headers from localhost.

The -rpcallowcors enables exactly this, for the use case you mention.

But the usual user of the desktop wallet is not

I do think the desktop wallet has significant amount of control, even though it's managed by the desktop wallet. It does respect the defi.conf where you can add these flags in.

the webSecurity of my Electron app disabled

What apps that use the node do, aren't in the domain boundary of the node. The node already provides all of the foundational blocks that it can, that can layered above to build anything you like. I do not understand what you think is missing from a node perspective here.

webPreferences: { webSecurity: false }

If you'd like webSecurity to be enabled on the desktop wallet app, please do open an issue there. If it was disabled, I'm sure there were reasons to do so safely, and can eventually move back to the security best practices.

DerFuchs commented 1 year ago

Hey Prassanna. Thank you again for taking your time to answer :)

Every time I make an issue in here, I feel like an idiot :D

You're right, the node is able to manage CORS and the user is able to make the setting. That's fine and might also be good from a security perspective. Let's keep it how it is.

If you're interested in the background of my request, here it is:

I am thinking and doing research about the question if (IF!) I should build a UI for voting. This is mainly motivated by my belief that DeFiChain will get more master node owners to vote when the voting process itself becomes more easy and convenient. I've been speaking to a lot users of my Masternode Monitor software and they often tell me that they hate voting because of it's "technical" nature. This makes them feel uncomfortable and they don't like to take the time it needs because they always have to re-learn the whole process, resulting in a lot of time spent on that.

So, my idea is to provide them a UI. And this thing has to be easy to use. In the best case, this thing will be a desktop app which is able to vote right after executing it. This app might have to fetch data from external sources like DFX's voting API to display all necessary information. That's why I thought that a not-disabled CORS might be a good idea. Enabling it is only possible via a browser engine flag, which will then force every connection to be CORS compatible, which includes the HTTP connection to the local node. That's only possible by setting -rpcallowcors in defi.conf.

The ease to use will be drastically shrink when the user has to make changes at his defi.conf file to switch on CORS for local connection. Most people, especially those who are not into the tech, will then either assume that this might be some kind of scam or they are uncomfortable to make this change. And this leads us to the same situation we're in right now - many people might not vote because it is too hard to do or does not feel safe.

I can simply switch off webSecurity in my app. My concern is that this might have consequences and will open up some unnecessary attack vectors. Therefore I thought it might be a good thing to enable CORS by default for local connections. But I might just build an application which does not require external connections. This is also way more secure.

Thank you. You have been a great help in my thinking process, even though this was not intended :D