Jump to content
Sign in to follow this  
iia

New JavaScript Bindings for Test

Recommended Posts

Hei Tinkerers,

 

We have finished working on the new Javascript bindings which will support both browser and Node.JS. Currently for testing only the Node.JS version is available.

 

The bindings are already in NPM registry.

 

First of all, you need to have a working Node.JS installation and NPM installed on your system (better if they are updated to the latest version).

 

Then you can install the bindings using the following command,

sudo npm -g install tinkerforge

 

You must make sure that the environment variable `NODE_PATH` is in your env list. This is usually pointing to `/usr/local/lib/node_modules/`.

 

After that you should be able to try out all the examples found in the attached archive with the following command,

node <exmaple_to_execute.js>

 

Don't forget to change the UID and network parameters depending on the setup you are testing on.

 

Have fun trying out the new bindings and it would be very much appreciated if you post your findings and feedback on this post.

 

 

Cheers,

Ishraq

NodeJS_Examples.zip

NodeJS_Examples.tar.bz2

Share this post


Link to post
Share on other sites

I just added a miniature version of a websocket server to brickd: https://github.com/Tinkerforge/brickd/commit/45b8da4a27af5c61054ea8093e2a1149784e7b23

 

It needs some more testing before we can publish it as a beta, but i already have a question about some details:

 

What do you think would be the right port for the websocket server in brickd? I am currently using port 80 (as defined in the standard). But this will obviously interfere with normal webservers if they happen to run on the same machine.

 

Do you think we should use a default websocket port that is different from 80? Independent of the default port you can change the port in the brickd config of course.

Share this post


Link to post
Share on other sites

Hi,

 

please don't use port 80 as default. I suggest to use something uncommon that other servers aren't likely to use, i.e. please also don't use 8080, 8888, etc. I suggest e.g. 16880.

Share this post


Link to post
Share on other sites

Hello,

 

I did some simple tests with the new Bindings. Everything worked fine except for the example in "ExampleSwitchSocket" for the RemoteSwitch-Bricklet.

 

Error message:

/home/pi/node_progs/tinkerforge/RemoteSwitch/ExampleSwitchSocket.js:24
        rs.switchSocketA(17, 1, BrickletRemoteSwitch.SWITCH_TO_ON);
                                ^
ReferenceError: BrickletRemoteSwitch is not defined
    at Object.0 (/home/pi/node_progs/tinkerforge/RemoteSwitch/ExampleSwitchSocket.js:24:33)
    at IPConnection.handleConnect (/home/pi/node_modules/tinkerforge/lib/IPConnection.js:280:70)
    at Socket.EventEmitter.emit (events.js:117:20)
    at Object.afterConnect [as oncomplete] (net.js:883:10)

 

Replacing "BrickletRemoteSwitch.SWITCH_TO_ON" with "1" works fine.

Setup:

Tinkerforge stack is connected via WiFi Extension to a Raspberry Pi running Node.js in version v0.10.23.

Share this post


Link to post
Share on other sites

Dear Equinox,

 

Good finding. The problem is it should be,

 

Tinkerforge.BrickletRemoteSwitch.SWITCH_TO_ON

 

instead of,

 

BrickletRemoteSwitch.SWITCH_TO_ON

 

Will be fixed in the examples.

Share this post


Link to post
Share on other sites

Here's Brick Daemon 2.1.0 RC1 that accepts WebSocket connections on port 4280:

 

Windows, Linux (amd64, i386, armhf), Mac OS X

 

And here's also an updated version of the JavaScript bindings that includes the browser version of the bindings and examples for them.

 

tinkerforge_javascript_bindings_2_0_0_rc1.zip

 

Just put an example HTML file and the Tinkerforge.js file from the browser subdirectory in the ZIP in the same directory and open the HTML file in your browser. This was tested and works in the latest versions of Chrome/Chromium, Firefox and Internet Explorer. Other browsers that support the current WebSocket version should work as well.

Share this post


Link to post
Share on other sites

RESPEKT!  :D  It works!

 

 

BTW:

 

~# dpkg -i brickd-2.1.0-rc1_i386.deb

Vorbereitung zum Ersetzen von brickd 2.0.10 (durch brickd-2.1.0-rc1_i386.deb) ...

brickd hängt ab von pm-utils; aber:  <--- ??

  Paket pm-utils ist nicht installiert.

 

~# apt-get -f install

Die folgenden zusätzlichen Pakete werden installiert:

  libx86-1 pm-utils powermgmt-base vbetool

Vorgeschlagene Pakete:

  cpufrequtils wireless-tools ethtool radeontool

 

Package: pm-utils (1.4.1-9)

utilities and scripts for power management

This package provides simple shell command line tools to suspend and hibernate your computer.

 

 

Der Loetkolben

 

Share this post


Link to post
Share on other sites
Guest Robin

I expect  the new binding might be a security risk. I think that it is possible to use this binding on any website? In this case external web pages would be able to connect to a stack. If they switch a Bricklet like the analog out, they could destroy the device which is used with it. I recommend to add a pass code protection to make sure external web pages can't connect.

Share this post


Link to post
Share on other sites

The risk is the same as before, but i can see your point. It is easier to get me to open a malicious website that uses port 4280 then to plant a malicious program on my pc that uses port 4223.

 

I see two possible ways to prevent an attack from a random malicious website:

 

1. We use the origin field from the websocket handshake. In this case the user would have to give the brickd or Ethernet Extension a list of websites that are allowed to connect. The problem here is that we can't store a big list of websites on the Ethernet Extension, perhaps two or three?

 

Another problem is that URLs are allowed to use any UTF8 character nowadays, we may have problems handling some URLs on the Brick because of that.

 

2. We (mis-)use the Sec-WebSocket-Protocol field of the websocket handshake and add a passphrase to our protocol that has to be configured for the Ethernet Extension or brickd. This would stop the attacks from a random malicious website but it couldn't do anything against "man-in-the-middle" attacks for obvious reasons.

 

But for security relevant projects where you fear that someone is trying to actively attack your Bricks/Bricklets you should only allow secure connections from a VPN or similar in any case!

 

Edit: We could also add the passphrase to the Request-Line field of the websocket handshake. That would probably make more sense, we wouldn't have to misuse any of the handshake fields.

Share this post


Link to post
Share on other sites

Hallo photron,

 

thanks for the "pm-utils" note.  :)

 

 

Hello Robin, borg.

 

I´m not shure if you talk about the same thing? The BROWSER connects to the Stack. ONLY local PC (Same Network) can access the Stack. NOT the Webserver is connecting to the Stack. This is the same situation as with the Brickviewer.

 

Or am I wrong?

 

Edit: I think I am wrong. If you load a webpage from external server, it can search/connect inside your local network for hosts with open port 4280.

 

Neverless. As discussed many times ago a PIN protection in the protocol, also for port 4223, would be fine. This gives protection if the Stack is reachable from outside via Router-Portforwarding.

 

 

Der Loetkolben

Share this post


Link to post
Share on other sites

This is the same situation as with the Brickviewer.

 

No. An external party/attacker cannot access your stack, assuming you didn't expose port 4223 to the Internet.

 

But with WebSocket support in brickd any website you open in your browser can access your stack via the brickd WebSocket, even if the WebSocket is only reachable from your PC. So any website out there that you open in your browser can access your stack, even if you didn't expose port 4280 to the Internet.

 

The problem here is that you're basically running untrusted code from external sources in your browser. That's why there is so much sand-boxing in modern browsers. That's also the reason why WebSockets in the browser cannot connect to normal sockets. Otherwise any website could access all services on your local network via your browser.

 

So, a malicious webserver cannot attack your stack directly, but it can deliver you a website that can do this.

Share this post


Link to post
Share on other sites

Hi,

 

So any website out there that you open in your browser can access your stack, even if you didn't expose port 4280 to the Internet.

 

How does this work? If I block port 4280 for accesses from the Internet, I think (and hope) that no browser will be able to access the stack. Of course, if you want to access your stack from the Internet, that doesn't work either.

Share this post


Link to post
Share on other sites

Equinox, your browser is executing the JavaScript code. Your browser has access to your local network and any brickd running there. No direct connection from the Internet to your local 4280 port necessary.

Share this post


Link to post
Share on other sites

Sorry, I don't understand  :(

Why does a browser running on a PC somewhere in the Internet (e.g. Internet-Café) have access to my local network or brickd if I block all connections from outside?

Share this post


Link to post
Share on other sites

Not any browser running anywhere, but YOUR browser running on YOUR PC. I could make you open a website that I control and have it mess with your stack connected to your PC. I don't need external access to your network I just need you to open my website.

 

In fact we will do exactly that. We plan to create an online version of Brick Viewer. You will be able to open brickv.com and it will be able to access your stack connected to your PC and provide the same features a locally installed Brick Viewer has. All this without installing any files to your PC, you just loaded a website with some JavaScript code that is executed in your browser.

Share this post


Link to post
Share on other sites

Hmm, still don't understand  :(

The JavaScript-Code from your fraudulent website may know the port (but even that can be changed as you said), but it doesn't know the IP-address of the stack or the brickd, right? So, how can it access my stack without knowing ip-address and port?

Share this post


Link to post
Share on other sites

It'll just connect to localhost:4280 to connect to the brickd on your PC. And even if you change the port then it can just probe all ports.

Share this post


Link to post
Share on other sites

Authentication

 

The original plan for authentication in Protocol 2.0 was to have a pre-shared key that the user and the Brick know. This would be used to sign all messages send between Brick and user. Both sides verify that the messages are correctly signed. This way an attacker can neither claim to be a user nor to be a Brick.

 

The problem with this plan is the complexity it adds to the Brick. Due to the way it works it would have to be directly integrated in the already very complex WIFI Extension logic. That's why we didn't do this yet.

 

A simpler option would be to do authentication per-connection, were the user has to prove that he knows the pre-shared key. There are basically two options how to do this:

 

Only for WebSockets

 

The user's pre-shared key is send to the WebSocket server (Ethernet/WIFI Extension or Brick Daemon) as part of the WebSocket handshake during the connection process. Then the WebSocket server can compare it to its stored pre-shared key. If it matches then the connection attempt is accepted and the connection is authenticated. Otherwise the connection attempt is aborted.

 

Before WebSockets can be used the user has to configure the pre-shared key of the WebSocket server. And in the JavaScript bindings the connect() function gets a third parameter that takes the pre-shared key to be include in the WebSocket handshake.

 

For all communication

 

By default authentication would be disabled to be compatible with the current system. If authentication is enabled then all TCP/IP connections to the TCP/IP server (Ethernet/WIFI Extension or Brick Daemon) start in unauthenticated state and all incoming and outgoing messages are thrown away until the user authenticates. For this the IPConnection of all bindings will get a authenticate() function that takes the pre-shared key, does the authentication process and proves to the TCP/IP server that the user knows the pre-shared key. This is done using a signing mechanism that avoids sending the pre-shared key over the wire. After this the connection is in authenticated state and all messages on this connection are handled as they are now.

 

Because this type of authentication would be disabled by default WebSockets would also be disabled by default as we don't want to release something that is easily attacked by a malicious website in the default configuration.

 

Any opinions, suggestions, questions?

Share this post


Link to post
Share on other sites
Guest Robin

You might create an interactive installation which asks the user if he wants to use authentification or not and which informs him about all risks and problems. This way everybody could easily decide which configuration he wants to use. Maybe the brickd also might get some restrictions such as authentification disabled => websockets disabled or a warning message.

 

To ensure backwards compatibilty, the only way would be to make it possible to choose for both, websockets and TCP connection if authentification should be enabled.

Share this post


Link to post
Share on other sites

To ensure backwards compatibilty, the only way would be to make it possible to choose for both, websockets and TCP connection if authentification should be enabled.

 

Both options are completely backward compatible. With option 1 the authentication only touches the new websocket bindings and with option 2 the default will still be that authentication is off.

Share this post


Link to post
Share on other sites

It'll just connect to localhost:4280 to connect to the brickd on your PC. And even if you change the port then it can just probe all ports.

 

What if the stack is connected via e.g. WiFi-Extension and no brickd is running on the localhost?

Share this post


Link to post
Share on other sites

What if the stack is connected via e.g. WiFi-Extension and no brickd is running on the localhost?

Then the attacker would indeed have to know the IP of the WiFi-Extension. There is no way for the browser to scan your network or similar.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this  

×
×
  • Create New...