-
• #2
Nothing - by default.
Having said that you can:
- Add a password with
E.setPassword
- Totally move the console device out the way with something like
LoopbackA.setConsole(1)
- Respond to the
NRF.connect
event, check the address, and manually disconnect if you don't like it - Totally disable the BLE UART service with
NRF.setServices
- which I'd suggest for anything remotely production-based
So a whole bunch of options really. Eventually there'll also be the ability to whitelist and also do Bonding (ensuring an encrypted connection) - but that's not in the firmware yet
- Add a password with
-
• #3
Yes! Security please!
I really appreciate how easy it was to give a puck.js to each of my daughters (8 & 9 years old) for Christmas and have them open them and go straight to hacking. Very simple. Very Awesome.
I really appreciate how I was able to pass my puck around the office merely saying "Google this" and introduce "hardware hacking" to a dozen people who expressed an interest in microprocessors but were overwhelmed by where to start.
But now I have a problem. It's become sport for people to send code to my pucks. I'm glad to hear that I can tell them to go buy their own pucks. However, they are hesitant to do so because they see how I am unable to secure my devices from their pranks.
I think it's worth having an official write-up on how to prevent unauthorized pairing.
I don't understand the consequences of the 4 different options Gordon has explained above, or how to implement them.
-
• #4
Argh. Yes, I can see how that would be a problem.
Just writing
E.setPassword("getoffmypuck");E.lockConsole()
is probably a good start :)Or you can do the following:
var locked = true; NRF.setServices(undefined,{uart:!locked}); setWatch(function() { locked = !locked; digitalPulse(locked?LED1:LED2,1,100); NRF.setServices(undefined,{uart:!locked}); }, BTN, {repeat:true, edge:"rising", debounce:50});
Tap in once, the light flashes green, and it's connectable via serial. Tap it again, it flashes red, and it's not.
But yes, I'll add security to my list of tutorials to write :)
-
• #5
Hi Ive have just got a ESP8266 and this was my first thought, my best attempt at the moment is below:
E.on('init', function() { E.setPassword("Password"); E.lockConsole(); });
this works for when the board boots but after i login once I have to remember to reset() or E.lockConsole()
is there a better solution at the moment ?
-
• #6
Perhaps you could add a timeout to autolock the console after a period of inactivity.
-
• #7
Could the WebIDE send
E.lockConsole()
when "Disconnect" is clicked ? -
• #8
It should automatically lock when the connection drops? I imagine it will work on Telnet (and it works on USB with normal Espruino boards, and on Bluetooth onn Puck.js) - but I guess because serial is always connected it doesn't.
-
• #9
I have also found another security hole, is there a way of disabling the port 88 web server used for wifi flashing otherwise anyone on the same WiFi network could just flash the device and take control that way.
Now im no hacker but ive found these holes pretty easily so looks to be quite a bit of work to be done before I could use this in a commercial environment.
I have come from using the Particle Photon witch is secure out of the box but was looking for a device I could program in JavaScript.
-
• #10
@Simon Espruino on ESP8266 is a port. It works very well, but it's not an official board, so it's not a security hole in Espruino as such.
Reflashing over wifi on that port would depend on many factors, but it wouldn't normally give up control of your device.
Wifi settings and program memory persist post-flash. A failed flashing attempt reverts to good binary stored on flash AFAIK.
Whether your stuff works after someone in the know and with access to board successfully flashes your ESP8266 is another matter. A successful flash 'could' leave saved code orphaned if the new Espruino version is different.
Maybe of interest, and you reminded me - the ability to flash over Wifi is disabled on ESP8266-01 - it does not have enough space to keep the good copy should flashing fail. What I don't know is whether flashing the 01 bin to 4Mb board like ESP8266-12 or NodeMCU (because you can) would give you pin availability but disable Wifi Flash.
I have wondered myself, but never asked.
-
• #11
Thanks - the port 88 thing is interesting - I wasn't aware that it was on by default (it'd be good to be able to disable it on the ESP8266 port or at the very least have a very prominent note about its existence as it is quite a big hole).
However it's only available to people with access to the WiFi network - and as there is no HTTPS/TLS on the ESP8266 port at the moment you're going to have security issues there as well.
I have come from using the Particle Photon witch is secure out of the box but was looking for a device I could program in JavaScript.
You could look at http://www.espruino.com/WiFi - which doesn't have any ports open by default and has HTTPS and TLS support.
You're comparing Particle Photon (which is sold for $20, and costs $80/year for commercial use) to the ESP8266, which is sold for about $3 (none of which pays for Espruino software development).
The ESP8266 port has been created by some very impressive work from the Espruino community. The people working on the ESP8266 port are doing it for free - they have absolutely no responsibility to do anything if they don't want to.
This is why I have the official devices that I sell, where I take a responsibility for making sure things 'just work' and spend a lot of time supporting users and trying to make sure that they're reliable, secure and well documented.
So please don't assume that Espruino isn't secure just because you tried a totally unsupported version of it :)
-
• #12
Hi Guys,
Following code is deployed on Puck.
NRF.on('connect',function(addr) { NRF.disconnect(); });
nRF Connect application from Android is used to connect to the device.
Expected behavior: No client can ever connect to the Puck and is always disconnected.
Current behavior: On the first attempt, the client is disconnected. On the second attempt 3 leds (RGB) are ON for a second and then the client can connect. When connected back to the Puck, the current code to the interpreter is flashed.Current firware version is 1v91.
How can always disconnect clients and partially when unknown address is found ? (i.e. apply http://www.espruino.com/Puck.js+Security)
Thank you.
-
• #13
Hi - thanks for letting me know. I'll look into this. I've filed an issue for it here: https://github.com/espruino/Espruino/issues/1088
3 LEDs lit happens when the Puck itself reboots - so it looks like there might have been some internal error.
If you
save()
your code I imagine you can still stop connections - but any bug that can cause the interpreter to reboot needs fixing -
• #14
Just a note to say it's fixed now - it'll be in the 1v92 release
-
• #15
Thank you Gordon.
-
• #17
BLE addresses can be either public (so ideally unique in the world) or 'random'. PCs/Phones tend to be of the form
"xx:xx:xx:xx:xx:xx public"
but other Puck.js devices will be"xx:xx:xx:xx:xx:xx random"
edit: I'll update that example on the Security page
-
• #18
Hi @Gordon,
When trying again with 1v92 to disconnect all connections which are not whitelisted
var serverAddress="xx:xx:xx:xx:xx:xx"; NRF.on('connect',function(addr) { if (addr.split(' ')[0]!=serverAddress) { NRF.disconnect(); } });
On first attempt the non-whitelisted ip is disconnected, while on second attempt the puck reboots.
Thank you.
-
• #19
What does it do when it's rebooted?
I just tried exactly your code here (left it at
xx:xx:xx:xx:xx:xx
so it already rejects) and it works perfectly. Could be a stupid question, but are you sure the battery isn't flat? -
• #20
Hi @Gordon,
The scenario above can be reproduced. Currently I have:
Puck 1:
Puck.getBatteryPercentage() = 33
NRF.getBattery() = 2.39Puck 2:
Puck.getBatteryPercentage() = 100
NRF.getBattery() = 2.97On the first attempt it works fine, but on the second it reboots. I use "nRF connect" to communicate with the Puck.
Thank you.
-
• #21
What does it do when it's rebooted? How do you know it has rebooted?
I do exactly this:
- Insert battery into Puck.js running 1v92
- Connect Web IDE on a PC
Copy/paste exactly this into the left-hand side:
var serverAddress="xx:xx:xx:xx:xx:xx"; NRF.on('connect',function(addr) { if (addr.split(' ')[0]!=serverAddress) { NRF.disconnect(); } });
Disconnect the PC
Try and connect with nRF connect - it shows connected and then disconnected straight after
Try again
and again, and again - still disconnected, and everything is fine
So I can't reproduce using the instructions you have given. Are you running with other code that you're not posting up? And are you sure it's 1v92? I know older versions did have some problems that sound exactly like you're describing
- Insert battery into Puck.js running 1v92
-
• #22
Hi @Gordon,
I use 1v92.
- Connect using WebIDE on PC, upload the code (do not save it) & disconnect.
- Try to connect using "nRF connect" - you are disconnected.
- Try again to connect using "nRF connect" - 3 leds are on for a second.
- Connect using WebIDE on PC - No code is available, the state is as if you called reset();
Thank you.
- Connect using WebIDE on PC, upload the code (do not save it) & disconnect.
-
• #23
Please can you type
process.version
and make absolutely sure that you are using version 1v92?I just tried this yet again, including with bonding, and I can't reproduce it. And yet it's identical to a bug that was in earlier firmwares.
-
• #24
Thanks for the video - yes, that does seem pretty conclusive! I'm just surprised I can't reproduce it on my computer - I'm even using Linux as well!
Was the address you used that of the host PC, or was it the address of your phone?
When I pair with my Puck.js in the Espruino Web IDE my Puck shows up in a list and I never have to enter a pairing code or authenticate in any other way. What keeps a third party from connecting to my puck in the same way and uploading their own instructions to it?