Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Better secure access to states and objects DBs in adapter.js #359

Closed
Apollon77 opened this issue Mar 27, 2019 · 15 comments
Closed

Better secure access to states and objects DBs in adapter.js #359

Apollon77 opened this issue Mar 27, 2019 · 15 comments

Comments

@Apollon77
Copy link
Collaborator

We should prevent adapters from calling methods directly on adapter.states and adapter.objects directly. For this we also need to check which methods are not exposed currently (getObjectView e.g.)

@AlCalzone
Copy link
Collaborator

I agree we shouldn't have to rely on using the methods directly.
But that also means we have to change a BUNCH of adapters.

@Apollon77
Copy link
Collaborator Author

We need to stay backward compatible I fear :( So maybe rename "states" and "objects" in adapter for use internally andf only provide the "old used" methods there :-)

@AlCalzone
Copy link
Collaborator

Maybe log a warning on first use of these proxied methods, so we get the devs to update their stuff?

@foxriver76
Copy link
Collaborator

foxriver76 commented Jul 18, 2019

Would be very important to do this, otherwise there is an easy workaround for the idea of #287

I think at first we should start by providing the methods that are needed and currently have no alternative defined which can be called on the adapter object directly. The most important and maybe only method which pops up in my mind is getObjectView. We could also use the chance to provide this as an async method too.

Checking for adapters which are using adapter.object.<xy> via adapter checker would be pretty nice, but I think it will also be very hard because of different structures, like adapters written in class style. On the other hand we could at least open a forum thread and add a logging warning as soon as there are alternatives.

@AlCalzone
Copy link
Collaborator

AlCalzone commented Jul 18, 2019

Checking for adapters which are using adapter.object.<xy> via adapter checker would be pretty nice, but I think it will also be very hard because of different structures, like adapters written in class style.

Checking stuff like this could be done with the TypeScript API which parses the code (JS code too) and generates a structure (tree) from it. That tree can be walked through to identify such constructs. However that is not trivial.

@foxriver76
Copy link
Collaborator

foxriver76 commented Jul 19, 2019

There also exist some other modules to parse code to an AST object, unfortunately they are including way to less information to indicate where the origin of a function lies. Probably the TypeScript API which you mentioned is the way to go.

On the other hand a forum thread asking which methods called on adapter.states || adapter.objects are in use and are not directly available on the adapter object would be an easier start.

@Apollon77
Copy link
Collaborator Author

On the other hand a forum thread asking which methods called on adapter.states || adapter.objects are in use and are not directly available on the adapter object would be an easier start.

Bevause I have a checkout of nearly all repos I could do a grep ;-)

@foxriver76
Copy link
Collaborator

I think grepping for adapter.states and adapter.objects will give us a meaningful overview. Most devs call their adapter variable adapter. So, go for it. ;-)

@Apollon77
Copy link
Collaborator Author

Results:

Summary:

  • adapter.objects.getObjectView
  • adapter.objects.getObjectList
  • adapter.objects.delObject // adapter.states.delState (why ever only 1 adapter!)

Details (if someone wants to do PRs ;-) )

adapter.states

./ioBroker.tr-064/tr-064.js://                     adapter.states.delState(o.id, function (err, obj) {

adapter.objects

./ioBroker.admin/main.js:    adapter.objects.getObjectList({include_docs: true}, (err, res) => {
./ioBroker.artnet/main.js:        adapter.objects.getObjectView('system', 'state', {startkey: adapter.namespace + '.', endkey: adapter.namespace + '.\u9999', include_docs: true}, function (err, res) {
./ioBroker.artnet/main.js:            adapter.objects.getObjectView('system', 'channel', {startkey: adapter.namespace + '.', endkey: adapter.namespace + '.\u9999', include_docs: true}, function (err, _channels) {
./ioBroker.cul/cul.js:    adapter.objects.getObject('cul.meta.roles', function (err, res) {
./ioBroker.cul/cul.js:        adapter.objects.getObjectView('system', 'device', {startkey: adapter.namespace + '.', endkey: adapter.namespace + '.\u9999'}, function (err, res) {
./ioBroker.cul/cul.js:            adapter.objects.getObjectView('system', 'state', {startkey: adapter.namespace + '.', endkey: adapter.namespace + '.\u9999'}, function (err, res) {
./ioBroker.discovery-/main.js:    adapter.objects.getObjectView('system', 'instance', {startkey: 'system.adapter.', endkey: 'system.adapter.\u9999'}, (err, doc) => {
./ioBroker.fullcalendar/main.js:    adapter.objects.getObjectView('system', 'enum', {
./ioBroker.fullcalendar/main.js:        adapter.objects.getObjectView('system', 'enum', {
./ioBroker.fullcalendar/main.js:    adapter.objects.getObjectView('schedule', 'schedule', {
./ioBroker.fullcalendar/main.js:                adapter.objects.getObjectView('custom', 'state', {startkey: '', endkey: '\u9999'}, function (err, res) {
./ioBroker.history/main.js:        adapter.objects.getObjectView('custom', 'state', {}, (err, doc) => {
./ioBroker.hm-rega/hm-rega.js:    adapter.objects.getObjectView('hm-rega', 'programs', {
./ioBroker.hm-rega/hm-rega.js:            adapter.objects.getObjectView('system', 'device', {
./ioBroker.hm-rega/hm-rega.js:                adapter.objects.getObjectView('system', 'channel', {
./ioBroker.hm-rega/hm-rega.js:                    adapter.objects.getObjectView('system', 'state', {
./ioBroker.hm-rega/hm-rega.js:    adapter.objects.getObjectView('hm-rega', 'variables', {
./ioBroker.hm-rpc/hm-rpc.js:    adapter.objects.getObjectView('hm-rpc', 'paramsetDescription', {
./ioBroker.hm-rpc/hm-rpc.js:    adapter.objects.getObjectView('system', 'state', {
./ioBroker.hm-rpc/hm-rpc.js:                adapter.objects.getObjectView('hm-rpc', 'listDevices', {
./ioBroker.hm-rpc/hm-rpc.js:            adapter.objects.getObjectView('hm-rpc', 'listDevices', {
./ioBroker.hm-rpc/hm-rpc.js:                    adapter.objects.getObjectView('hm-rpc', 'listDevices', {
./ioBroker.influxdb/main.js:        adapter.objects.getObjectView('custom', 'state', {}, function (err, doc) {
./ioBroker.info/main.js:    adapter.objects.getObjectView('system', 'instance', {startkey: 'system.adapter.', endkey: 'system.adapter.\u9999'}, (err, doc) => {
./ioBroker.javascript/main.js:                    adapter.objects.getObjectView('script', 'javascript', {}, (err, doc) => {
./ioBroker.javascript/main.js:    adapter.objects.getObjectList({include_docs: true}, (err, res) => {
./ioBroker.klf200/main.js:    if (undefined === adapter.objects.getObjectViewAsync)
./ioBroker.klf200/main.js:        adapter.objects.getObjectViewAsync = Promise.promisify(adapter.objects.getObjectView);
./ioBroker.klf200/main.js:            let scenes = yield adapter.objects.getObjectViewAsync(
./ioBroker.maxcube/main.js:    adapter.objects.getObjectView('system', 'channel', {startkey: adapter.namespace + '.', endkey: adapter.namespace + '.\u9999'}, (err, res) => {
./ioBroker.maxcube/main.js:        adapter.objects.getObjectView('system', 'state', {startkey: adapter.namespace + '.', endkey: adapter.namespace + '.\u9999'}, (err, res) => {
./ioBroker.maxcul/main.js:    adapter.objects.getObjectView('system', 'channel', {startkey: adapter.namespace + '.', endkey: adapter.namespace + '.\u9999'}, (err, res) => {
./ioBroker.maxcul/main.js:        adapter.objects.getObjectView('system', 'state', {startkey: adapter.namespace + '.', endkey: adapter.namespace + '.\u9999'}, (err, res) => {
./ioBroker.miio/main.js:         * Save latest miio adapter objects.
./ioBroker.mqtt-client/client.js:        adapter.objects.getObjectView('mqttclient', 'state', {}, function (err, doc) {
./ioBroker.opi/main.js:            adapter.objects.getObjectList({startkey: adapter.name + '.' + adapter.instance, endkey: adapter.name + '.' + adapter.instance + '\u9999'}, function (err, res) {
./ioBroker.opi/main.js:        adapter.objects.getObjectList({include_docs: true}, function (err, res) {
./ioBroker.owntracks/owntracks.js:	adapter.objects.getObjectView('system', 'instance', {startkey: 'system.adapter.mqtt.', endkey: 'system.adapter.mqtt.\u9999'}, (err, instances) =>
./ioBroker.rpi2/main.js:            adapter.objects.getObjectList({startkey: adapter.name + '.' + adapter.instance, endkey: adapter.name + '.' + adapter.instance + '\u9999'}, function (err, res) {
./ioBroker.rpi2/main.js:        adapter.objects.getObjectList({include_docs: true}, (err, res) => {
./ioBroker.scriptgui/main.js:            adapter.objects.getObjectList({include_docs: true}, function (err, res) {
./ioBroker.sql/main.js:                adapter.objects.getObjectView('custom', 'state', {}, (err, doc) => {
./ioBroker.statistics/main.js:    adapter.objects.getObjectView('custom', 'state', {}, (err, doc) => {
./ioBroker.systeminfo/myAdapter.js:        this.getObjectList = this.c2p(adapter.objects.getObjectList);
./ioBroker.systeminfo/myAdapter.js:        return adapter.objects;
./ioBroker.telegram/main.js:        adapter.objects.getObjectView('custom', 'state', {}, (err, doc) => {
./ioBroker.telegram/main.js:        adapter.objects.getObjectView('system', 'enum', {startkey: 'enum.' + name + '.', endkey: 'enum.' + name + '.\u9999'}, (err, doc) => {
./ioBroker.tinker/main.js:            adapter.objects.getObjectList({startkey: adapter.name + '.' + adapter.instance, endkey: adapter.name + '.' + adapter.instance + '\u9999'}, function (err, res) {
./ioBroker.tinker/main.js:        adapter.objects.getObjectList({include_docs: true}, function (err, res) {
./ioBroker.tr-064/tr-064.js://     adapter.objects.getObjectView('system', 'state', { startkey: ch + '.', endkey: ch + '.\u9999' }, function (err, res) {
./ioBroker.tr-064/tr-064.js://                          adapter.objects.delObject(o.id);
./ioBroker.tr-064/tr-064.js:    adapter.objects.getObjectView('system', 'state', { startkey: ch + '.', endkey: ch + '.\u9999' }, function (err, res) {
./ioBroker.upnp/main.js:        adapter.objects.getObjectView('custom', 'state', {startkey: adapter.namespace + '.', endkey: adapter.namespace + '.\uFFFF'}, (err, doc) => {
./ioBroker.web/main.js:    adapter.objects.getObjectView('system', 'instance', null, (err, doc) => {
./ioBroker.web/main.js:        adapter.objects.getObjectView('system', 'instance', {}, (err, instances) => {
./ioBroker.web/main.js:            adapter.objects.getObjectView('system', 'adapter', {}, (err, adapters) => {
./ioBroker.zwave/main.js:            adapter.objects.getObjectList({
./ioBroker.zwave/main.js:                adapter.objects.getObjectList({
./iobroker.bosesoundtouch/bosesoundtouch.js:        this.adapter.objects.getObjectView(
./iobroker.bosesoundtouch/bosesoundtouch.js:        this.adapter.objects.getObjectView(
./iobroker.js2fs/js2fs.js:        adapter.objects.getObjectList({
./iobroker.paw/main.js:  adapter.objects.getObjectList({
./ioBroker.powermonitor/main.js:		this.objects.getObjectView("custom", "state", {}, (err, doc) => {

@foxriver76
Copy link
Collaborator

We need to add getObjectList to adapter.js. The rest is already implemented, just needs to be replaced in the adapters.

@Apollon77
Copy link
Collaborator Author

Do you find Time to do that in next days ?! Then it could come into 2,.0.0

@foxriver76
Copy link
Collaborator

Sure, please check the PR.
IMHO as soon as js-c 2 is stable we can create PRs to the adapters which are using getObjectList and getObjectView (+ we should add js-c 2 as dependency then). delObject and delState replacement PRs can be done from now on.

@Apollon77
Copy link
Collaborator Author

Should we leave this Issue open till then or we need to create a new one

@foxriver76
Copy link
Collaborator

foxriver76 commented Sep 15, 2019

Step 1: Replace methods which are independent of js-c 2.0

Step 2: Replace methods which are dependent on js-c 2.0 and add js-c 2.0 as adapter dep

  • ./ioBroker.admin/main.js: adapter.objects.getObjectList({include_docs: true}, (err, res) => {
  • ./ioBroker.artnet/main.js: adapter.objects.getObjectView('system', 'state', {startkey: adapter.namespace + '.', endkey: adapter.namespace + '.\u9999', include_docs: true}, function (err, res) {
  • ./ioBroker.artnet/main.js: adapter.objects.getObjectView('system', 'channel', {startkey: adapter.namespace + '.', endkey: adapter.namespace + '.\u9999', include_docs: true}, function (err, _channels) {
  • ./ioBroker.cul/cul.js: adapter.objects.getObject('cul.meta.roles', function (err, res) {
  • ./ioBroker.cul/cul.js: adapter.objects.getObjectView('system', 'device', {startkey: adapter.namespace + '.', endkey: adapter.namespace + '.\u9999'}, function (err, res) {
  • ./ioBroker.cul/cul.js: adapter.objects.getObjectView('system', 'state', {startkey: adapter.namespace + '.', endkey: adapter.namespace + '.\u9999'}, function (err, res) {
  • ./ioBroker.discovery-/main.js: adapter.objects.getObjectView('system', 'instance', {startkey: 'system.adapter.', endkey: 'system.adapter.\u9999'}, (err, doc) => {
  • ./ioBroker.fullcalendar/main.js: adapter.objects.getObjectView('system', 'enum', {
  • ./ioBroker.fullcalendar/main.js: adapter.objects.getObjectView('system', 'enum', {
  • ./ioBroker.fullcalendar/main.js: adapter.objects.getObjectView('schedule', 'schedule', {
  • ./ioBroker.fullcalendar/main.js: adapter.objects.getObjectView('custom', 'state', {startkey: '', endkey: '\u9999'}, function (err, res) {
  • ./ioBroker.history/main.js: adapter.objects.getObjectView('custom', 'state', {}, (err, doc) => {
  • ./ioBroker.hm-rega/hm-rega.js: adapter.objects.getObjectView('hm-rega', 'programs', {
  • ./ioBroker.hm-rega/hm-rega.js: adapter.objects.getObjectView('system', 'device', {
  • ./ioBroker.hm-rega/hm-rega.js: adapter.objects.getObjectView('system', 'channel', {
  • ./ioBroker.hm-rega/hm-rega.js: adapter.objects.getObjectView('system', 'state', {
  • ./ioBroker.hm-rega/hm-rega.js: adapter.objects.getObjectView('hm-rega', 'variables', {
  • ./ioBroker.hm-rpc/hm-rpc.js: adapter.objects.getObjectView('hm-rpc', 'paramsetDescription', {
  • ./ioBroker.hm-rpc/hm-rpc.js: adapter.objects.getObjectView('system', 'state', {
  • ./ioBroker.hm-rpc/hm-rpc.js: adapter.objects.getObjectView('hm-rpc', 'listDevices', {
  • ./ioBroker.hm-rpc/hm-rpc.js: adapter.objects.getObjectView('hm-rpc', 'listDevices', {
  • ./ioBroker.hm-rpc/hm-rpc.js: adapter.objects.getObjectView('hm-rpc', 'listDevices', {
  • ./ioBroker.influxdb/main.js: adapter.objects.getObjectView('custom', 'state', {}, function (err, doc) {
  • ./ioBroker.info/main.js: adapter.objects.getObjectView('system', 'instance', {startkey: 'system.adapter.', endkey: 'system.adapter.\u9999'}, (err, doc) => {
  • ./ioBroker.javascript/main.js: adapter.objects.getObjectView('script', 'javascript', {}, (err, doc) => {
  • ./ioBroker.javascript/main.js: adapter.objects.getObjectList({include_docs: true}, (err, res) => {
  • ./ioBroker.klf200/main.js: if (undefined === adapter.objects.getObjectViewAsync)
  • ./ioBroker.klf200/main.js: adapter.objects.getObjectViewAsync = Promise.promisify(adapter.objects.getObjectView);
  • ./ioBroker.klf200/main.js: let scenes = yield adapter.objects.getObjectViewAsync(
  • ./ioBroker.maxcube/main.js: adapter.objects.getObjectView('system', 'channel', {startkey: adapter.namespace + '.', endkey: adapter.namespace + '.\u9999'}, (err, res) => {
  • ./ioBroker.maxcube/main.js: adapter.objects.getObjectView('system', 'state', {startkey: adapter.namespace + '.', endkey: adapter.namespace + '.\u9999'}, (err, res) => {
  • ./ioBroker.maxcul/main.js: adapter.objects.getObjectView('system', 'channel', {startkey: adapter.namespace + '.', endkey: adapter.namespace + '.\u9999'}, (err, res) => {
  • ./ioBroker.maxcul/main.js: adapter.objects.getObjectView('system', 'state', {startkey: adapter.namespace + '.', endkey: adapter.namespace + '.\u9999'}, (err, res) => {
  • ./ioBroker.miio/main.js: * Save latest miio adapter objects.
  • ./ioBroker.mqtt-client/client.js: adapter.objects.getObjectView('mqttclient', 'state', {}, function (err, doc) {
  • ./ioBroker.opi/main.js: adapter.objects.getObjectList({startkey: adapter.name + '.' + adapter.instance, endkey: adapter.name + '.' + adapter.instance + '\u9999'}, function (err, res) {
  • ./ioBroker.opi/main.js: adapter.objects.getObjectList({include_docs: true}, function (err, res) {
  • ./ioBroker.owntracks/owntracks.js: adapter.objects.getObjectView('system', 'instance', {startkey: 'system.adapter.mqtt.', endkey: 'system.adapter.mqtt.\u9999'}, (err, instances) =>
  • ./ioBroker.rpi2/main.js: adapter.objects.getObjectList({startkey: adapter.name + '.' + adapter.instance, endkey: adapter.name + '.' + adapter.instance + '\u9999'}, function (err, res) {
  • ./ioBroker.rpi2/main.js: adapter.objects.getObjectList({include_docs: true}, (err, res) => {
  • ./ioBroker.scriptgui/main.js: adapter.objects.getObjectList({include_docs: true}, function (err, res) {
  • ./ioBroker.sql/main.js: adapter.objects.getObjectView('custom', 'state', {}, (err, doc) => {
  • ./ioBroker.statistics/main.js: adapter.objects.getObjectView('custom', 'state', {}, (err, doc) => {
  • ./ioBroker.systeminfo/myAdapter.js: this.getObjectList = this.c2p(adapter.objects.getObjectList);
  • ./ioBroker.telegram/main.js: adapter.objects.getObjectView('custom', 'state', {}, (err, doc) => {
  • ./ioBroker.telegram/main.js: adapter.objects.getObjectView('system', 'enum', {startkey: 'enum.' + name + '.', endkey: 'enum.' + name + '.\u9999'}, (err, doc) => {
  • ./ioBroker.tinker/main.js: adapter.objects.getObjectList({startkey: adapter.name + '.' + adapter.instance, endkey: adapter.name + '.' + adapter.instance + '\u9999'}, function (err, res) {
  • ./ioBroker.tinker/main.js: adapter.objects.getObjectList({include_docs: true}, function (err, res) {
  • ./ioBroker.tr-064/tr-064.js:// adapter.objects.getObjectView('system', 'state', { startkey: ch + '.', endkey: ch + '.\u9999' }, function (err, res) {
  • ./ioBroker.tr-064/tr-064.js: adapter.objects.getObjectView('system', 'state', { startkey: ch + '.', endkey: ch + '.\u9999' }, function (err, res) {
  • ./ioBroker.upnp/main.js: adapter.objects.getObjectView('custom', 'state', {startkey: adapter.namespace + '.', endkey: adapter.namespace + '.\uFFFF'}, (err, doc) => {
  • ./ioBroker.web/main.js: adapter.objects.getObjectView('system', 'instance', null, (err, doc) => {
  • ./ioBroker.web/main.js: adapter.objects.getObjectView('system', 'instance', {}, (err, instances) => {
  • ./ioBroker.web/main.js: adapter.objects.getObjectView('system', 'adapter', {}, (err, adapters) => {
  • ./ioBroker.zwave/main.js: adapter.objects.getObjectList({
  • ./ioBroker.zwave/main.js: adapter.objects.getObjectList({
  • ./iobroker.bosesoundtouch/bosesoundtouch.js: this.adapter.objects.getObjectView(
  • ./iobroker.bosesoundtouch/bosesoundtouch.js: this.adapter.objects.getObjectView(
  • ./iobroker.js2fs/js2fs.js: adapter.objects.getObjectList({
  • ./iobroker.paw/main.js: adapter.objects.getObjectList({
  • ./ioBroker.powermonitor/main.js: this.objects.getObjectView("custom", "state", {}, (err, doc) => {

Step 3: Remove possibility to directly call adapter.objects and adapter.states in lib/adapter.js

foxriver76 added a commit to foxriver76/ioBroker.bosesoundtouch that referenced this issue Dec 9, 2019
foxriver76 added a commit to foxriver76/ioBroker.tr-064-community that referenced this issue Dec 10, 2019
foxriver76 added a commit to foxriver76/ioBroker.fullcalendar that referenced this issue Dec 14, 2019
foxriver76 added a commit to foxriver76/ioBroker.artnet that referenced this issue Dec 23, 2019
foxriver76 added a commit to foxriver76/ioBroker.rpi2 that referenced this issue Jan 17, 2020
foxriver76 added a commit to foxriver76/ioBroker.discovery that referenced this issue Jan 21, 2020
Garfonso added a commit to iobroker-community-adapters/ioBroker.rpi2 that referenced this issue Feb 7, 2020
@foxriver76
Copy link
Collaborator

IMHO closed by 4acb1c4

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
No open projects
Development

No branches or pull requests

3 participants