I am having trouble with certificate when using websocket (WSS://).
What is working
For now, I've been using websocket with WEB_SOCKET_FORCE_FLASH = true and I had no issues with connecting to my websocket server.
What is not working
I am trying to turn that option off, to stop using flash plugin for connecting. Problem occurs when i try to connect my websocket client to server. WebSocket opening handshake was canceled message appears.
I can disable this message, by going to https://127.0.0.1:9999. My browser will show that "This Connection is Untrusted", and if I add an exception here, my websocket connection will start working without any problem from now on. But i CAN'T make every end user to do that, right?
Google groups with this idea
What I need?
Is there any way, to buy, or create some self-signed certificate, which I can use? The problem is also that, it doesn't have to be localhost/127.0.0.1 but also any other IP in local network. (like 192.168.0.100 etc). End user can change that IP whenever he likes to. He just needs to point on the PC where my desktop app/websocket server is running.
What have I tried?
I sure tried to find my answer in google, browsing tons of forums, sites, and even few questions and all answers here on stack overflow.
I also tried not using certificate at all, but my page is on https:// so connection using ws:// is impossible.
Code
I know, code is usually obligatory, but I actually got my websocket client/server working, but the issue is certificate, so i hope you can forgive me lack of code.
missing info?
Do i need to provide any more information? I am willing to make multiple edits if needed.
While the current certificate system is kind of broken it is fortunately not broken enough to allow what you want. What you expect to get based on your description is a certificate for an IP addresses (bad idea anyway) which you don't even own fully (you cannot claim to be the owner of 127.0.0.1 or similar addresses) which then will be accepted by every browser without the need to add a manual exception by the user.
Related
I have built a websocket in C++ (using boost::beast).
It is going to serve a website (client) with a JSON string if requested.
When designing my setup I made a disastrous mistake: I forgot that the client web browser (that is running on a separate device from the server) will not know the IP address of the server. It will know the port that the server is listening on.
I should specify: Both (server and client) are running in a local network.
So I have two clumsy ideas to resolve this. I would be very happy to hear your input – I am sure there will be a more elegant way to fix my problem.
Send some kind of broadcast message “Very specific string” into the network. My server will know that it is been looked for and will respond with its IP, so that the connection can be established.
This post seems to indicate that this approach will not be possible.
Have the user input the (known) IP address of the device that is running the server. I would really like to avoid this last resort solution.
Unfortunately, I cannot run node.js on the device that is hosting the websocket server.
I might not be understanding the problem. Why aren't you capable of knowing the IP of the server? Is it due because it changes? Is it because it's a server you don't know?
Maybe the solution is not about finding the IP rather than knowing beforehand the server IP address.
I could recommend checking out this post to find out the IP address in your local network. If you at least know the servername of the server that could be helpful.
#E.Soria
Thank you for your answer! I was not precise enough.
The problem was, that the server is running on a device that is going to be part of our customer’s network. The customer will define the IP address for the device, which means that I need some way of getting the address of the server.
But I might have found another solution (as you might already be able to tell I am very new to networking, so this just may be wrong): I will host the website on the same device that is hosting the server and supplying the data. Then I can just establish a websocket connection through javascript like this: let socket = new WebSocket(ws://127.0.0.1:8080); and have the website read data from the server. This seems to be very straightforward and I am a little embarrassed that I did not think of this before.
I just had not really understood how the internet works :) As long as the user who wants to see the website knows where it is hosted, he/she can just connect to the website and will see anything that I put on there.
I'm trying to make an application with NodeJS which heavily depends on users connecting to it via the typcial WebSocket protocol from their browsers, I'm using the ws library for this in nodeJS.
The actual application works fine, and I'm able to disconnect any user (if I can detect that the current IP address has already connected), and authorize it with a user name and password (all taken care of on the server side, after they send the username and password via the websocket, and I can even make a timer on the server side to prevent the client from brute forcing the server to try to authorize itself with a username and password); however, I have not yet found a way to block the connections from happening in the first place.
What to I mean? For example, someone, on the client side, can open up their javascript console and simply type something like:
setInterval(function() {
new WebSocket("ws://myServerURL")
}, 1)
and simply let that keep going, and pretty soon the entire server will be completely blocked off and / or crashed from the mass amount of constant connections from the same client.
So, although I am able to disconnect a user once it's attempted to connect (if I detect that it has already connected on the same IP address, for example), but how can I stop someone from simply sending in constant connections and / or commands like the above code? How can I completely block an entire IP address from opening any new connections, from the outset?
There are npm packages to help with rate-limiting, but I prefer to keep this out of the app server completely as they will still consume resources.
In practice I use Nginx as proxies to our api and configure these to rate-limit requests.
The following example will limit 10 requests per second based on user's ip:
limit_req_zone $binary_remote_addr zone=mylimit:10m rate=10r/s;
Nginx is easy to get up and running, battle-tested and well documented.
If using Heroku, you can configure this pretty easily using a buildpack. Here is a demo repo to look at.
You can do this at your application if you must, but I'd recommend putting your server behind Nginx (or similar) and letting Nginx handle preventing these sorts of generic attacks.
https://www.nginx.com/blog/mitigating-ddos-attacks-with-nginx-and-nginx-plus/
That way, you can focus on building your application without having to reinvent the whole thing.
Recently, I was trying to build a bot for myself. It works flawlessly when I'm using ngrok to test my bot locally, but when I deployed to AWS, I started seeing the error captured below occasionally, and causing no webhook request sent to my server from Facebook. I have no idea what could possibly go wrong. I have check the request going to my server with tcpflow as well, but there's no luck, it seems like Facebook just didn't send that particular request to my server. This is a really weird problem that happens in no particular point of my bot conversation flow. I always need to repeat my answer or my postback in order to get it to work.
Some basic server info (don't know if this matters) :
Availability zone: ap-southeast-1b
Type: t2.micro
CPU usage (at that moment): 4%
I would really appreciated if anyone could solve my mystery. Thanks.
FYI, I have reported this to Facebook: https://developers.facebook.com/bugs/1825253057751227
Your webhook server has to work over valid https (not self signed).
My advice - add https to webhook server, using cloudflare service (it`s free), or get a free valid certificate using letsencrypt
If your error is occasional, I would recommend moving your instance size up from Micro, to at least Medium or Large and make it a Dedicated instance. The resources required to run the letsencrypt client, combined with your bot traffic and noisy neighbors might overcome a shared micro instance.
So I currently have a node.js app that reads my website user ips from a file and using geoip places a dot in a map for each visitor location.
Problem is, everytime a new visitor comes the message sent through the websocket can be seen by the client if he inspects traffic with wireshark or fiddler.
Obviously displaying user ips is out of the question, so I am wondering if using TLS would be enough to make this information unreadable or impossible to debug from the javascript code.
Thanks
The information is sent to the user's browser. The browser must be able to decode it to be able to work with it. The browser also incidentally offers debugging tools which allow the user to inspect everything that's going on. Ergo, the user is able to inspect anything and everything that the browser can. No, what you want is not possible. If the information is confidential, never send it to any client in the first place.
It will make it more-or-less impossible to sniff the data in transit.
It does nothing to stop people taking your JS and tweaking it slightly to log the data after the browser has received it.
You can't hide data you send to the browser from the person who controls the browser.
The biggest question is why are you sending the IP and the position to the browser? To place the marker on the map, you just need the position.
If you need to distinct the users by IP address on the client side, you could write an own hashing algorithm which concats the ip with a predefined string(secret). So the identifier is always the same for the same IP, but the IP is not reconstructable without the corresponding secret.
TLS helps against traffic snipping by 3rd party attackers. If normal users can access sensitive information, then TLS worths nothing. It is called Transport Layer Security for a good reason.
I have a SignalR chat site that's meant for a school project (also uses C#). Theoretically, it is for trusted users, but as everyone will attest - never trust your users. This was proven to me as I sent out the link to a couple of my friends and they immediately tried to break it, ha ha.
I've sanitized all inputs properly now, but one thing that they were still able to do was to use the browser console tools to manually call the functions needed to send messages, etc..
Example: $.connection.chatHub.server.sendMessageToAll('FakeUser','FakeMsg',0);
I would like to prevent these types of actions. I recall a while back Facebook actually disabled the console window for "security" purposes. I even found several{1} resources{2}, which detail how this was done and attempts to further prevent console use once Chrome had fixed this.
However, none of these options work anymore and because browsers are constantly in flux, I'd rather not attempt to block at this level.
I was wondering if anyone on Stack knows of a better way to prevent these types of attacks? Is there a good way to check where the call is coming from? Does SignalR have a good method to prevent this? Ideas/Discussion would be surely welcome.
Trying to lock down the client like that might work reasonably well to prevent non-technical users from messing with your app, but it will do next to nothing against a knowledgeable and resourceful opponent. The circumstances under which such security measures make sense are rather limited, and certainly do not include any application that is accessible to everyone from the internet.
The only safe approach is well-known and very simple: the server does not trust the client for anything. It doesn't then matter what the client attempts to do as the server will refuse all actions it does not deem valid.
In your example, the server would assign a randomized opaque connection id to each session. The client would only be able to convince the server to do anything if they sent a valid id as part of their request; then, the server would not need to trust the client for a username because it would already know what connection each user has logged in from and could produce the username when given the id.