In my way learning Meteor the past weeks, trying to build a simple crud with some validation I stumbled upon something.
Until today, I've been trying to keep my Collection Schema on server's side, and had some difficulties rendering Schemas server validation on the client, so I added aldeed:autoform.
When I started playing with autoform, after a few errors, I was surprised to realize that a Collection's Schema HAD to be defined on client side in order to work properly.
Doesn't that seems a bit dangerous? Should the schema of your Collections be published on the client?
It is maybe a stupid question, im not sure. I'll apologize in advance :D
You'll need to define the schema so that it is accessible by both the client and the server code. This is because, the form validation is done once at the client side (which should be always treated as insecure as it's made available in the browser console like below) and once on the server side. The server side validation is always considered secure. So even if you manage to manipulate the form from the browser by whatever means, if the validation does not fall in line with the schema, it gets filtered out on the server side so long as the schema is attached to the collection. I believe this way it's secure.
Meteor autoform page suggests you to remove insecure and add allow/deny rules.
Be sure to define proper insert security for untrusted code if you've
removed the insecure package. Call allow/deny or use
ongoworks:security.
Steps I follow to keep things secure (please be aware that there may be better ways, since I'm also fairly new to meteor universe)
Remove autopublish and insecure.
Define schema with allow/deny rules.
Use meteor server methods to insert / update.
Whether you use the schema attached to a collection or a schema to just validate a form and not really want it to be attached to a collection, make sure you call [check()][4] on the server code so that the once the form is submitted at the client end to the server, the server further explicitly checks if the data is still in accordance with the schema and nothing has been injected / tampered with by someone or something untrusted. If it is manipulated, the server side validation automatically filters out the extra additions on to the data passed to it.
This is what happens if someone adds extra data into which does not exist / conform to the schema definition:
Related
I have a head-scratcher here. Over a year ago, I wrote a website feature/form where I could submit SQL Code that is not executed but stored in a table. This feature worked when I created it, as I was able to upload several scripts into the database. I have not needed to use this feature for several months, and recent upgrades to my website had me re-checking features. The feature stopped working ... and after some research, it was determined that our company firewall was now blocking the form from submitting due to a detection of "SQL Injection".
They swear that no changes were made to the firewall, however, this seems unlikely since this feature previously functioned. Regardless ... the confusion I have is that I know many websites, like this one, that allow people to post "code" using a web form interface without being flagged as SQL Injection. I am sure websites (like this one) have firewalls protecting them as well.
Is there something that needs to be done when transmitting code on a page submit/postback to clear a firewall's SQL Injection checks?
For clarification ...
There is a form, with a LargeTextArea control, where a SQL Script is entered. This SQL code is transmitted via postback to the server, and server-side code handles the saving of the script into a table. Very similar to what this website (StackOverflow) does I would assume. We can post code here, without it being intercepted and blocked by a firewall. The code we post here in our messages is eventually stored in a database on the server. That is the same behavior that I am performing.
Because of the firewall intervening between the client browser and the web server, the postback is never completed. Therefore, the server never receives the postback data to perform any processing. The client browser simply receives a "connection-reset" error.
I always thought of SQL Injection as something that should be handled server-side ... the responsibility of the programmer to ensure it is not abused. Having a firewall interfere prior to arriving at the server and having code execute to even check for SQL Injections ... feels wrong to me. Even if you have code that prevents SQL Injection, it would not matter if the firewall is intercepting and intervening prior to any server-side logic. Am I wrong?
Your firewall rules for SQL injection are blocking parameters that "look like" SQL injection - and that can lead to false positives for code that is not executed.
The correct way to get around this is to modify the firewall rule. See this answer for a way to that in ModSecurity.
Since this doesn't seem to be an option for you, you might consider bypassing the rule with obfuscation. For example - encrypting with a simple fixed key before putting it in the database (and decrypting on display) would hide this code from the firewall. And also provide some guardrails against it being executed in the future.
With bypassing security checks you are taking on a great responsibility. You should be very careful to ensure (and warn in comments) that this code is never executed. This includes executing it to check that it is correct SQL - which could also be abused for SQL injection.
I have a Meteor game of heads or tails that keeps the stats of a user in their profile. The stats eg. wins and loses are changed using Meteor methods like incrementWins and incrementLoses.
Is there a way to prevent the users from calling these methods on the console?
I didn't find any precise answer to the question so I'll add one.
Is there a way to prevent the users from calling these methods on the console?
The short answer is no.
As long as you have the Meteor variable available on the client, it's not possible to restrict a user to use if from browser console. Meteor allows the client side to use Meteor.call function in any conditions, therefore even if you restrict its usage somehow, it will affect your whole application, not just browser console.
You can, however, make your methods more secure. As you know, you can make your code run either on client side, server side, or both. If you put your methods on the server side, the client side will never know what exactly happens as the methods are executed, nor would it be able to influence it or intercept control anyhow.
On the other hand, if you put your methods in the lib/ or both/ folder (or simply root folder of your app), the methods will run both on client and on server. Insecure part of the code (like bulk removing collection items or manipulating Meteor.users collection) won't be executed on the client side. But you may want to put something that would change UI state or show any messages, ironically, on the browser console. Think twice before applying this practice.
I personally think you exaggerate the meaning of ability to run something on the browser console. First, only a small group of users actually do that (but if they do, expect smallest holes in your app to be exploited). Second, Meteor is well secured in this part, it doesn't allow a user to run insecure code (unless insecure package is added, which is by default as you create a new app). And third, most of the time, as your methods get executed, the data will be updated reactively, this is what Meteor takes care of out of the box, so you don't need to worry about refreshing UI after app state change, etc.
Every newly created Meteor project has the insecure package added by default. This is the package that allows us to edit the database from the client. It's useful when prototyping, To remove this package, go to your app directory and run:
meteor remove insecure
I'm learning Meteor and fundamentally enjoy how fast I can build data driven applications however as I went through the Creating Posts chapter in the Discover Meteor book I learned about using server side Methods. Specifically the primary reason (and there are a number of very valid reasons to use these) was because of the timestamp. You wouldn't want to rely on the client date/time, you'd want to use the server date/time.
Makes sense except that in almost every application I've ever built we store date/time of row create/update in a column. Effectively every single create or update to the database records date/time which in Meteor now looks like I would need to use server side Methods to ensure data integrity.
If I'm understanding correctly that pretty much eliminates the ease of use and real-time nature of a client side Collection because I'll need to use Methods for almost every single update and create to our databases.
Just wanted to check and see how everyone else is doing this in the real world. Are you just querying a server side Method that just returns the date/time and then using client side Collection or something else?
Thanks!
The short answer to this question is that yes, every operation that affects the server's database will go through a server-side method. The only difference is whether you are defining this method explicitly or not.
When you are just getting started with Meteor, you will probably do insert/update/remove operations directly on client collections using validators, which check for whether the operation is allowed. This usage is actually calling predefined methods on both the server and client: (for a collection named foo the you have /foo/insert, for example) which simply checks the specified validators before doing the operation. As you become more familiar with Meteor you will probably override these default methods, for reasons you described (among others.)
When using your own methods, you will typically want to define a method both on the server and the client, just as the default collection functions do for you. This is because of Meteor's latency compensation, which allows most client operations to be reflected immediately in the browser without any noticeable lag, as long as they are permitted. Meteor does this by first simulating the effect of a method call in the client, updating the client's cached data temporarily, then sending the actual method call to the server. If the server's method causes a different set of changes than the client's simulation, the client's cache will be updated to reflect this when the server method returns. This also means that if the client's method would have done the same as the server, we've basically allowed for an instant operation from the perspective of the client.
By defining your own methods on the server and client, you can extend this to fill your own needs. For example, if you want to insert timestamps on updates, have the client insert whatever timestamp in the simulation method. The server will insert an authoritative timestamp, which will replace the client's timestamp when the method returns. From the client's perspective, the insert operation will be instant, except for an update to the timestamp if the client's time happens to be way off. (By the way, you may want to check out my timesync package for displaying relative server time accurately on the client.)
A final note: it's good to understand what scope you are doing collection operations in, as this was one of the this that originally confused me about Meteor. For example, if you have a collection instance in the client Foo, Foo.insert() in normal client code will call the default pair of client/server methods. However, Foo.insert() in a client method will run only in a simulation and will never call server code - so you will need to define the same method on the server and make sure you do Foo.insert() there as well, for the method to work properly.
A good rule of thumb for moving forward is to replace groups of validated collection operations with your own methods that do the same operations, and then adding specific extra features on the server and client respectively.
In short— yes!
Publications exist to send out a 'live', and dynamic, subset of the database to the client, sending DDP added messages for existing records, followed by a ready, and then added, changed, and deleted messages to keep the client's cache consistent.
Methods exist to- directly, or indirectly— cause Mongo Updates, and like it was mentioned by Andrew, they are always in use.
But truly, because of Meteor's publication architecture, any edits to collections that are currently being published to at least one client, will be published via DDP - regardless of the source of the change to Mongo - even an outside process.
I went through this tutorial and I'm trying to figure out how authorization works:
https://www.openshift.com/blogs/day-15-meteor-building-a-web-app-from-scratch-in-meteor
I see that client-side code is well written and that it handles privileges for logged in users through calls to
if(Meteor.userId())
but as far as I can tell nothing is handling client authorization in the server-side code in epollserver.js.
I tried to create a script that likes questions in a for loop but failed :) So I'm wondering if I'm missing something about the blog, something about the way metamagics work in meteor or if the tutorial actually results with unsafe code?
Meteor has a built in accounts functionality, so it has a login package called accounts-base that handles this for you.
The code is in the background and not in your main project files. You can view the package's contents here: https://github.com/meteor/meteor/tree/devel/packages/accounts-base.
Meteor is slightly different in the way security is handled. The tutorial you're using doesn't mention it much, perhaps this is why the question comes about.
Its slightly mentioned with the insecure package. In meteor you can't just update fields as you please in the database without corresponding .allow rules (docs: http://docs.meteor.com/#allow).
If you keep the insecure package in, installed by default, you can edit collections as you please. This is why the tutorial recommends removing it.
Allow rules and Publish
You can specify a rule that tells meteor that only certain users are allowed to alter the database.
Likewise when it comes to autopublish, you can control what database data is sent down from the server to the client.
Combined, these two are what make meteor secure in the same way as conventional web applications. You have a browser which can see html and js, but when it comes to what data it can see or what data it can update it is controlled in a secure fashion.
On client-side, you can use Meteor.userId() to manage display fo logged user or anonymous.
In fact you can think it's not secure, but in fact it's enough, if you think well your server-side code. Let's me explain :
In meteor Js, you manage collection through publish/subscribe and direct network call through Meteor.call. So you have to secure both, on server-side.
For the first one you have to remove insecure and autopublish.
Then use allow/deny on your collections to manage who can insert/update/remove data.
Then in your publish functions, that are only on server-side, you have to add :
if (!this.userId) return this.error(new Meteor.Error(403, 'unauthorized access'));
For the second one (Meteor.call) you just have to add in all required Meteor.methods (on server-side) :
if (!Meteor.userId()) throw new Meteor.Error(403, 'unauthorized access');
With those thing your application is "secure". Yes a user can hack your client code to try to display templates that should be available only for logged user, but in fact, this user will not be able to retreive any data, so yes it is secure !
Also don't forget to split your server and client code in different folder (server and client) or all the code will be downloaded by the client. And this is not secure !
Hope it helps you understand Meteor Js.
Actually, the tutorial does result with unsafe code since I managed to add a question through the JS console without being logged in, my initial hunch that the code lacks server-side checks was correct
I suspect three more if(Meteor.userId()) in epollserver.js would fix the issue, it's a basic authorization coding failure of not observing the mantra "protect from the server first, then from the client if necessary"
I'm working on the following scenario:
I have a console up that populates a SQL Server database with some data. I have one more web app that reads the same database and displays the data on a front-end. Both of the applications use Entity Framework to communicate with the database (they have the same connection string).
I wonder how can the web app be notified for any changes that have occurred to the database. Bear in mind that the two applications are not referenced, whatsoever.
Is there event provided by EF that fires when some has changes. In essence, I would like to know when a change has happened, as well as, the nature of that change
I had a similar requirement and I solved it using the EF function:
[context].Database.CompatibleWithModel(throwIfNoMetadata: true)
It will return if your model matches the underlying database structure using the metadata table.
Note that I was using a Code First approach.
The msdn definition is below:
http://msdn.microsoft.com/en-us/library/system.data.entity.database.compatiblewithmodel(v=vs.103).aspx
Edit:
Just found an amazing article with a demonstration:
http://blog.oneunicorn.com/2011/04/08/code-first-what-is-that-edmmetadata-table/
This is not something that is related to EF at all. EF is just a library that makes SQL calls and maps them to objects. It has no inside knowledge of the database. As such, when data changes in one application, another application doesn't know unless they query to see if that data changes (and you're not going to be constantly running queries to know that, it's too impractical).
There are, potentially some ways to do this, such as adding triggers to the database, which then call extended stored procs to send messages to the app, but this is a lot of work to go through, and it can possibly compromise the robustness of the database.
There used to be something called Notification Services, but that was deprecated. There's now something called SqlDependency objects, which may help you in some cases.. but it all depends on what you're trying to do exactly.
In any event, it's usually easier to find a different way to do what you want. This is complex topic, and really requires a lot of sql server knowledge.