Meteor DDOS Protection

1,259 views
Skip to first unread message

Marc MacLeod

unread,
Jun 9, 2014, 3:06:14 PM6/9/14
to meteo...@googlegroups.com
What's to stop a user from opening up the console and running something like:

while (true) {
    Posts.insert({title: 'foo', userId: 'my id'});
}

Are there any best practices for preventing this type of thing across all the collections in an app?

dcsan

unread,
Jun 9, 2014, 8:41:51 PM6/9/14
to meteo...@googlegroups.com

Marc MacLeod

unread,
Jun 9, 2014, 8:57:03 PM6/9/14
to meteo...@googlegroups.com
I assume you're referring to #1, meteor doesn't have data security? I'm well aware of how general security in Meteor works.

In this case, I'm talking about a user that has permission to create a post. If a user can create a post, what's to stop them from creating 5000 posts with that 3 line JS snippet? Now, I could add a check everywhere an insert is made on any collection, to see when the user last inserted into the collection and stop them if it's less than a certain threshold. I'm simply wondering if there's a better way to do this..

Is the best way to add a deny insert function that checks when the user last inserted?

Slava Kim

unread,
Jun 9, 2014, 9:50:26 PM6/9/14
to meteo...@googlegroups.com
Hi,

You would start by looking at `this.connection` inside the method invocation http://docs.meteor.com/#method_connection. The connection object has an unique id for the session and the ip address of the client. Considering that insert/update/remove commands are implemented as Meteor.methods too, I assume one could write a package that wraps every method and rate-limits it per id or per ip.

Marc MacLeod

unread,
Jun 9, 2014, 9:53:40 PM6/9/14
to meteo...@googlegroups.com
Perfect, thanks for pointing me in the right direction Slava.

Arunoda Susiripala

unread,
Jun 9, 2014, 10:04:18 PM6/9/14
to meteo...@googlegroups.com
And also, be careful about using IP to detect users. Sometimes tons of users use the same IP.
In that case, find a way to verify the legitimate user by asking a captcha and add a localStorage token indicating he is a verified user/connection.

--
You received this message because you are subscribed to the Google Groups "meteor-talk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to meteor-talk...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Andrew Mao

unread,
Jun 10, 2014, 8:41:29 PM6/10/14
to meteo...@googlegroups.com

Александр Подкидышев

unread,
Jun 11, 2014, 4:09:57 AM6/11/14
to meteo...@googlegroups.com
What a terrible topic, never thought about that side of the meteor!

And it is possible somehow, for example, forbid adding on client, but only through methods? 

We must do something...

среда, 11 июня 2014 г., 3:41:29 UTC+3 пользователь Andrew Mao написал:

Serkan Durusoy

unread,
Jun 11, 2014, 7:27:50 AM6/11/14
to meteo...@googlegroups.com
Basic rate-limiting is alread possible by creating timestamps at every insert and checking new inserts against the date of the previous one. Fairly simple, and it works.

Batist Leman

unread,
Jun 11, 2014, 8:05:50 AM6/11/14
to meteo...@googlegroups.com
Isn't this concern applicable to all platforms? In rails you could just execute a curl post in a loop I guess...? 

Gabriel Pugliese

unread,
Jun 11, 2014, 10:42:31 AM6/11/14
to meteo...@googlegroups.com
In Django, rate limiting is also a package, not even built-in: https://github.com/jsocol/django-ratelimit



Gabriel Pugliese
CodersTV.com
@coderstv


--

Andrew Mao

unread,
Jun 11, 2014, 2:48:18 PM6/11/14
to meteo...@googlegroups.com
I don't see why rate-limiting couldn't just be built in to Meteor, tracked by DDP connections. Method calls and subscriptions will just throw an error if some rate is exceeded, and it would rarely if ever be encountered in a regular app.

This won't even require many changes to the current API, because method calls already support errors being thrown. The two things that could be added are 1) automatic retries for method calls that fail, for redundancy in a regular app and 2) The ability for subscriptions to throw errors properly.

Andrew Mao

unread,
Jun 11, 2014, 2:51:05 PM6/11/14
to meteo...@googlegroups.com
Never mind (2): errors are already supported in subscriptions (http://docs.meteor.com/#meteor_subscribe), they just aren't used much right now because mainly only query errors cause them.

I think this topic has been already considered by MDG; it's probably just not implemented yet because of the focus on fast prototyping and not introducing pitfalls for programmers. It certainly fits in to the current API though.

Andrew Mao

unread,
Jun 11, 2014, 2:53:26 PM6/11/14
to meteo...@googlegroups.com
Another, more transparent way to approach this is just for over-rate method calls to take a long time to return, rather than throwing errors. This rate should be settable in Meteor.settings for a tradeoff between performance and security. I'm thinking about the way that the current UNIX login works.

Ralph Haygood

unread,
Jun 11, 2014, 4:29:15 PM6/11/14
to meteo...@googlegroups.com
I like this idea.

Emily Stark

unread,
Jun 11, 2014, 6:33:32 PM6/11/14
to meteo...@googlegroups.com
Is there any reason this can't be an atmosphere package?


--

Arunoda Susiripala

unread,
Jun 11, 2014, 7:35:18 PM6/11/14
to meteo...@googlegroups.com
See my comment on trello board. We need to guard account-password with rate limiting for password retries and reset emails. 

It's possible to override core methods and implement this. It don't have a value arguing this on too much. 

Sooner or later, we need a solution. 


--

Emily Stark

unread,
Jun 11, 2014, 8:13:38 PM6/11/14
to meteo...@googlegroups.com
Arunoda, I'm not sure that you need to override many core methods... login hooks should be sufficient for rate-limiting login attempts.

Arunoda Susiripala

unread,
Jun 11, 2014, 8:14:36 PM6/11/14
to meteo...@googlegroups.com
got it :)

Andrew Mao

unread,
Jun 11, 2014, 8:49:11 PM6/11/14
to meteo...@googlegroups.com
Ah, the beauty of Fibers :D

However, it could block other client methods while being rate limited. I suppose that is okay though. What about other methods? Can we have some method hooks?


On Wednesday, June 11, 2014 5:14:36 PM UTC-7, Arunoda Susiripala wrote:
got it :)
On Thu, Jun 12, 2014 at 5:42 AM, Emily Stark <em...@meteor.com> wrote:
Arunoda, I'm not sure that you need to override many core methods... login hooks should be sufficient for rate-limiting login attempts.
On Wed, Jun 11, 2014 at 4:35 PM, Arunoda Susiripala <aru...@meteorhacks.com> wrote:
See my comment on trello board. We need to guard account-password with rate limiting for password retries and reset emails. 

It's possible to override core methods and implement this. It don't have a value arguing this on too much. 

Sooner or later, we need a solution. 

On Thursday, June 12, 2014, Emily Stark <em...@meteor.com> wrote:
Is there any reason this can't be an atmosphere package?
On Wed, Jun 11, 2014 at 1:29 PM, Ralph Haygood <ralph....@gmail.com> wrote:
I like this idea.


On Wednesday, June 11, 2014 2:53:26 PM UTC-4, Andrew Mao wrote:
Another, more transparent way to approach this is just for over-rate method calls to take a long time to return, rather than throwing errors. This rate should be settable in Meteor.settings for a tradeoff between performance and security. I'm thinking about the way that the current UNIX login works.

--
You received this message because you are subscribed to the Google Groups "meteor-talk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to meteor-talk+unsubscribe@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "meteor-talk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to meteor-talk+unsubscribe@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.


--
--
You received this message because you are subscribed to the Google Groups "meteor-talk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to meteor-talk...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Andrew Mao

unread,
Jun 11, 2014, 8:50:46 PM6/11/14
to meteo...@googlegroups.com
@estark37: the Meteor security guru may or may not want to be outsourcing some of Meteor's core security to random atmosphere packages :)

Stefano Diem

unread,
Jun 11, 2014, 9:40:25 PM6/11/14
to meteo...@googlegroups.com
Regarding rails, you cant really do the loop thing (at least for standart forms) because before you can submit a document you need to first fetch an authenticity token present in the form's html. So you need to do a GET request for the form and then you can submit it with a POST. Off course, if you create a webservice then you would need to implement something like this yourself, as you wouldn't fetch the authenticity token.


Abraços,
Stefano Diem Benatti

phone: 55 11 9343 0994
skype:  teonimesic

Slava Kim

unread,
Jun 12, 2014, 12:41:52 AM6/12/14
to meteo...@googlegroups.com
Andrew, I don't get the importance of Fibers here. Do you mean to suspend a Fiber processing a loud connection? You should be careful with it as each Fiber actually has some cost for memory.

And I don't understand your "the Meteor security guru" comment. Please, keep it to the topic.

Almog Koren

unread,
Jun 12, 2014, 6:54:25 AM6/12/14
to meteo...@googlegroups.com
This is an interesting never thought about this, I think this can become very problematic and would expect a built in solution within Meteor and not a package.  

Andrew Mao

unread,
Jun 12, 2014, 12:16:43 PM6/12/14
to meteo...@googlegroups.com
I meant that a Fiber can synchronously block a method call for a loud connection. But, you're right that a DDoS attack could still bring the server down if each Fiber is consuming resources. Good point.

Regarding the comment, I was just responding to Emily that something that is a potentially central security issue should be tackled in core and not delegated to the community - even if it's possible to do it entirely with hooks and smart packages. I just typed it quickly in an attempt to be funny, and I'm sorry.

Louis DeScioli

unread,
Jun 12, 2014, 7:30:58 PM6/12/14
to meteo...@googlegroups.com
The practice I've seen and used in my couple projects has been to write your inserts as Meteor methods and include them in your collections file. Is there a way to restrict database inserts, on the client, to only come from defined Meteor methods? Make it where calling Posts.insert(newPost) fails, you have to say Meteor.call('newPost', newPost);

Shawn Lim

unread,
Jun 17, 2014, 3:38:34 AM6/17/14
to meteo...@googlegroups.com
Hello. I'm also in favor of a built in solution within Meteor with some defaults for the DDOS problem. 

One idea is : 

Limited rate of calling methods (for the same context) for logged in users. Many functions especially data mutating types usually require at least an authenticated user, so perhaps a built in solution can limit the number of times a user can call a method within a minute. 

Matteo De Micheli

unread,
Nov 1, 2014, 6:15:52 PM11/1/14
to meteo...@googlegroups.com
I have taken a basic shot at this by wrapping all Meteor.methods with a basic rate limit, the package is available here: https://github.com/matteodem/meteor-easy-security.

I'm still in favor of a solution within Meteor Core but I hope this could be useful to some of you until then.

PEM

unread,
Nov 2, 2014, 4:29:20 AM11/2/14
to meteo...@googlegroups.com
Thanks for sharing Matteo. Also looking forward to see that in the core.

tom1v...@gmail.com

unread,
Nov 2, 2014, 6:34:01 AM11/2/14
to meteo...@googlegroups.com
That's cool Matteo

Shawn Lim

unread,
Nov 2, 2014, 9:01:19 AM11/2/14
to meteo...@googlegroups.com
Very interesting solution! This covers only custom methods created by us right? Not Collection.inserts, remove, update? 

On Sunday, November 2, 2014 7:34:01 PM UTC+8, tom1v...@gmail.com wrote:
That's cool Matteo

Matteo De Micheli

unread,
Nov 2, 2014, 10:45:52 AM11/2/14
to meteo...@googlegroups.com
This covers all methods with collections and the predefined ones (see https://github.com/matteodem/meteor-easy-security/blob/master/lib/server.js#L75

Shawn Lim

unread,
Nov 2, 2014, 11:10:46 AM11/2/14
to meteo...@googlegroups.com
Wow.

Jon James

unread,
Nov 2, 2014, 2:14:03 PM11/2/14
to meteo...@googlegroups.com
Your example is not a DDOS. I'm not sure why nobody has clarified this yet.

Also, why are you trying to handle a DDOS with application logic? Isn't the whole point to take down your web server? Rate limiting is important but it's not going to keep your server up when a massive amount of connections at Nginx or Haproxy block all other friendly requests and ramp up your server bill.

tom1v...@gmail.com

unread,
Nov 2, 2014, 2:29:45 PM11/2/14
to meteo...@googlegroups.com
Jon
There's different scales of DDOS: distributed (more than one client) denial...

For some smaller-scale uses, I think Matteo's work is useful.

Jon James

unread,
Nov 2, 2014, 3:03:09 PM11/2/14
to meteo...@googlegroups.com
I do find Matteo's package to be useful and well-written. Apologies for being terse.

I was referring to the original example, as it's an infinite loop running in a single computer's browser console, but the title refers to a DDOS attack.

For more serious DDOS protection you can use iptables or fail2ban. There are a few useful examples of working with iptables here, however I haven't personally tested those examples.

Matteo De Micheli

unread,
Nov 2, 2014, 4:32:56 PM11/2/14
to meteo...@googlegroups.com
Yes you are obviously right, something like HaProxy should already block you before. It was about how the "app" itself can be secured against attacks, if I understood the original question right. I'll add a little hint in the README.md that it doesn't prevent (D)DOS attacks ;)
Reply all
Reply to author
Forward
0 new messages