What's the best way to prefix all urls in an app with a constant string?


#1

I would like to prefix all urls in my app with a constant random string. I am thinking it might make it more secure. What’s the best way to do that?


#2

What sort of urls do you mean you want to prefix? Do you mean all of the internal links within your app?


#3

Yes. Will it make the app more secure? Say, my urls will look like

http://myhost.com/386732921202344356/items

It’s for development only, a very early version.

I am not familiar with DDP yet. What do DDP urls look like, and can you prefix them in a similar manner?


#4

I’m not all too familiar with DDP yet either, but it’s my understanding that Meteor handles all the low-level DDP stuff internally. All you need to worry about is (assuming you’re using the Iron Router package) calling the pathFor (or linkTo) function in your template files, and the Router will take care of ensuring all your links work and stay up to date, even if you change a route or the name of a template.

As for your prefix, assuming again that you’ve installed Iron Router (meteor add iron:router), you could presumably define a variable that contains the string value of your prefix in your Router config file, and then you could just manually add it to each route definition. So, something like this:

var routePrefix = "/386732921202344356";
// Here is a route definition
Router.route( routePrefix + '/items', {name: 'itemsListTemplate'});

You would then use either pathFor, urlFor, or linkTo template helpers whenever you wanted to add a link in one of your templates to one of your routes (i.e. as opposed to typing out the URL in the href attribute). That way, Iron Router takes care of ensuring that none of your links are broken, even when you update your code.

I’m not sure how much you care about absolute vs relative links (your example included the host), but:
pathFor would generate a relative URL value to put in an href attribute, e.g. /38673292.../items
urlFor would generate an absolute link, with the same URL but including the protocol and domain (the FULL url).
linkTo would generate an entire anchor tag but would only provide a relative URL, like pathFor does.

I took a quick look through the Iron Router Guide, but I didn’t see any specific feature that would directly support a feature like a route/URL prefix. Maybe you could find a better way to accomplish it than the suggestion above using the Route Hooks feature.

Or (more likely), someone with more Meteor experience can offer a better solution.


#5

Than you for your response.

DDP can be a problem, because my goal is to provide at least a bit of security, but what’s the point if DDP is open to the world?


#6

@aaabbbccc
DDP is just a transport layer. Most of them, even HTTP (if my understanding is correct) are unencrypted transport layers. Any “man in the middle” could listen in on your communications that took place on any of them (e.g. HTTP, UDP, etc). The difference with HTTPS (again, if I’m correct) is that the protocol specifies that each party (client and server) to a transaction must encrypt data before it is transmitted.

So, you could do the same thing, within your app: encrypt sensitive data before it is transmitted over “the wire,” as they say. There are JavaScript encryption packages. Or, if you couldn’t find one you liked or that worked for your application, you could at least obfuscate your code and/or data. One way data is obfuscated is to convert all the ASCII characters into their hexadecimal (or other type of) encoding. Don’t get me wrong: obfuscation is no substitution for encryption. A (moderately) sophisticated person could still read your data. But it does make it more difficult than a plain-text transmission would be to read. Many people believe, and I’m one of them, that “security through obscurity” (i.e. obfuscating your data, instead of encrypting it properly) is no security at all, really. I just have to put that disclaimer in there. But encryption is hard to get right, and it’s easy to think you’ve implemented it correctly, when you haven’t, thereby giving yourself a false sense of security. That’s why I mentioned obfuscation. It’s better than nothing.

I’ve never worked with any JavaScript encryption packages, so I couldn’t give you any advice there. But you can find them easily with Google. In fact, I think Google is the author of one of the more popular JavaScript encryption packages.

Actually (to be thorough), I googled this quickly just now, and I see that there’s a relatively new standard proposal, called the WebCrypto API. I have no idea what kind of support for it exists in the top browsers, but that’s also something you could find out easily.

I hope your app works out well for you. What kind of app are you building?


#7

Just to be clear here: prefixing URLs with random strings is NO SUBSTITUTE FOR SECURITY

Obfuscation of paths and data names is NO SUBSTITUTE FOR SECURITY

Hiding your DDP endpoint is NO SUBSTITUTE FOR SECURITY

Are you sensing a theme?

DDP is simply a transfer protocol and it CAN work over ssl websockets. Simply put an ssl terminating proxy (such as nginx) on the same box, and suddenly poof your websockets are ssl. Make the non-ssl connections forward to ssl by returning a 301 with the https version and suddenly poof you have forced encryption.

Hiding the URL is a dumb scheme as even if you successfully do that (it’s a bitch) anyone who gets access can still do whatever they want. Instead, put security in your methods. Require that updates happen server side and only after you have authenticated your user in some way.

If you want to limit access to your site, do that in your router. Validate the user before displaying the template. An invalid user can either get a login page, or if you want to be obtuse, they can get a nice under construction style 404 page.

Read any of the good books about meteor out there and they all have at least one chapter on basic security. Start there. Don’t let the application stay wide open, learn how to secure it.


#8

Obfuscation is just the illusion of security, sort of like being forced to take off your shoes at the airport before passing through the gate: All of the suck, but none of the desired benefit.

The door isn’t the problem; the fact that you never bothered to lock it was why it was open to the world. Likewise, DDP isn’t the problem; it’s just the way that you get data from your server to the client.

HTTPS/SSL – most specifically the latest, patched version of TLS, with 2048-bit encryption – is, at this moment, how we lock that door. As soon as a new vulnerability becomes known, applying the patch as soon as it becomes available is how we keep that lock from rusting and falling off the door.

Security is a process, not a one-time, “set it and forget it” step. However, starting out with actual security rather than imagined security will at least ensure that you start out with a locked door.

Once you’re done with turning on forced SSL, go read up on the Zero Trust Model, and you’ll be able to lock your windows, the sliding glass doors on the second story balcony, and even the cellar door.


#9

I don’t worry about man in the middle attack. Like I said, we are at early development, and there is almost nothing valuable on the server at this point. When we go to production, we’ll nuke this server and redo it from scratch anyway. I just wanted a quick and dirty solution protecting the site from the world; using your metaphor, an unlocked door is still marginally better than no door at all.

Since no one is linking at us at the moment, the only way we can be found is by a random port scan. As long as the root url is giving no indication it’s a Meteor app, and the real urls are obscure, and we don’t have that much to hide anyway at this point, I don’t feel very threatened by this scenario. Should I be? Since there are only 5 of us or so, and we try not to use unencrypted networks, man in the middle is probably not very likely to happen, statistically speaking.

I am under a deadline and the windows can just go dark if I invest into non-vital concerns early,


#10

So you have an unlisted number, and you conclude that the only way that someone can get into your unlocked house is by looking in the phone book, noting your address, and then trying the door manually? Did I mention the latch on your door isn’t very good, so locking it is the only way to ensure that the slightest breeze doesn’t blow it open?

Nobody uses phone books, these days. Anyone with Google maps can figure out your house exists, and because you never locked the door, the Google street view car photographed your front door wide open and made this fact available to anyone with an internet connection. Additionally, anyone walking down the street can glance in the direction of your house and see that it’s wide open.

If you think I’m taking this metaphor too far, bear this in mind: If I recall correctly, around year 2000, MIT did a study to see how long it typically took before a computer/server first connected to the Internet would be remotely probed for intrusion. 15 years ago, it took only 2.6 seconds. Think about the significance of that. Since then, the onslaught of remote attacks has only intensified, and the tools for identifying vulnerabilities on an automated basis have only proliferated.

Here’s another fun fact from about 2 years ago: What Happened When One Man Pinged the Whole Internet Good times, that.

Respectfully, what we are helpfully trying to suggest to you is that prefixing all the URLs in your app with a constant random string will not provide you with any increase in security at all. None, whatsoever. Worse yet, it has the dangerous side effect of reassuring you that you’ve done something “quick and dirty” to make it less vulnerable (which you haven’t). As a result, you “don’t feel very threatened by this scenario”, and the tendency in such situations, is that you don’t pursue actual security. Only the illusion of it…

If you’re not concerned about a MITM (Man-in-the-MIddle) attack (which you should be), at the very least you should be concerned about all of the other types of attacks that you don’t know about.

I assure you there are other means aside from random port scans, many of them are anything but random. Any system that can connect to your server can easily (and automatically) determine whether it is a Meteor app. Rather than enumerating all of these techniques, I will be the first to admit that I don’t know all of them. Even the NSA, the Chinese, and private security firms don’t know all of them (just ask The Hacking Team, Kaspersky, or Edward Snowden). New zero-day exploits are being discovered, announced, and patched every day. Many more are discovered and intentionally kept secret every day, so they can be used to compromise systems in the future.

That’s the point: Security is a process. You start with the assumption that if something is theoretically vulnerable, then you assume that it will become exploited using those (or other) means, and look for ways to prevent that from happening in the first place. Hence locking your doors with full-time/forced HTTPS. If you don’t want just anyone to gain access to the system, you implement two-factor authentication, with strong passwords. This is, quite literally, the least you can do to implement something “quick and dirty” to add any measure of security. This is step 1. There is no step 0.1 or 0.5. Either you’re encrypted or you’re not. Either you require authentication or you don’t.

You also presume that your efforts to prevent exploitation will eventually fail on at least one of your systems, and so you look for ways to mitigate the damage that can be done with the assumption that a breach will eventually occur. Hence, the Zero Trust Model.

As a result, you realize that you never transmit or store passwords in plain text. You never reuse the same password for all your systems (or for any other system or service you access, in case those passwords are compromised).

Things like that become obvious once you start with those assumptions and think through every aspect of building out a server – even if it’s just a proof-of-concept or prototype. The good news: Since this is step 1 for every new site you do, once you figure out how to apply these settings, it will be SOP (standard operating procedure) and comparatively old hat for every new site you create.


#11

[quote=“aaabbbccc, post:9, topic:8067”]
I don’t worry about man in the middle attack. Like I said, we are at early development, and there is almost nothing valuable on the server at this point. [/quote]

If there is no concern about the content on your server then why hide it? Either way, if what you say is true, then you can go with obfuscated paths for now though it doesn’t really offer you any security.

If your code base isn’t secure, than how are you going to be ok moving to production. If your only goal is to keep competitors from seeing what you are doing, then changing your paths might buy you something. If your goal is security, make it an early concern in the application, not a late one.

That is even more concerning than anything else you’ve said. You literally could be forced to shut down a startup if you take the time to do security right? That means that you have a startup and are diving into meteor head first and your idea of security is this? Do your investors know that your idea of security was to obfuscate the urls? I’m sure they’ll be super happy about that.

Take the couple of hours it takes to learn about accounts systems and method and publication security then remove autopublish and insecure from your application. Finally, check out bulletproof meteor. If you haven’t gone through everything on that site, you are NOT ready to be running a meteor startup. Make it something you do on the weekend if you have to, but make sure you understand security from the ground up.

If none of that matters to you right now and you just want to get this site running, don’t waste your time prefixing your URLs as it is not worth the effort. If you don’t want google etc to find it, use robots.txt. Just keep going and when you come around to security (pre launch I hope) take the information in this thread as a starting point to do it right.