From a general glimpse of it, it seems that source code for Meteor app is open to the clients due to 'Write one Javascript file, run it on client and server at once' theme.
If server side source code of particular app open to client sides, wouldn't it be easy for random person to copy them and create very look alike app?
Wouldn't it be easy for person with evil purpose to find security holes in the app, because its server side code is open to the public?
For instance, in Meteor 0.5.0 's new example of parties app, model.js file seems to be sent to the client side as well.
Am I misunderstanding something here?
Edit
Here is the part that I do not understand.
According to http://docs.meteor.com/#structuringyourapp,
Files outside the client and server subdirectories are loaded on both the client and the server! That's the place for model definitions and other functions
I really do not understand it. If every model implementation, (including DB interaction) is sent to client, wouldn't app be less secure and easily copied by other developers?
Any code in the server/ folder will not get sent to the client (see http://docs.meteor.com/#structuringyourapp)
EDIT
Regarding the second part:
Any code not in client/ or server/ is code you want to run both client and server side. So obviously it must be sent to the client.
The reason that you would place model code in there is because of latency compensation. If you want to make updates to your data, it's best to do it immediately client-side and then run the same code server side to 'commit' it for real. There are many examples where this would make sense.
If there is 'secret' model code that you don't want to run client side, you can certainly have a second server/models.js file.
The best way to secure a client-server app is by writing explicit security checks on the server, rather than hiding the database update logic from the client.
For a longer explanation of the security model, see https://stackoverflow.com/a/13334986/791538.
Related
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 have a Flex based application which is using Flash Media Server (FMS) server (version 4.0) for live video streaming between two users (i.e. a one to one teleconferencing service). This streaming is one-to-one, as defined by business rules, so that no third person can join a teleconference. Either person can start the video stream via a browser-based Flex client and communication gets established once the second user joins. Validation for connecting the streams of the two users is implemented on the FMS server (as server side scripting defined in main.asc). I am facing three critical problems with our teleconferencing solution.
1.Often times, full communication can not be established between the two users. One user can not usually see or hear the other user. There is a client side 'refresh' button that when clicked, attempts to establish a connection via the server side script. This sometimes works. Before implementing our current server side script, I tried establishing a stream by using methods found here: http://forums.adobe.com/thread/905613
I think the method below may work as it would give me an array of subscribers to the stream.
getLiveStreamStats(appInst:String, stream:String) : Object
But the problem is that server returns the following:
<level>error</level>
<code>Admin.API.MethodNotAllowed</code>
<description>getlivestreams - Method not allowed!</description>
<timestamp>8/7/2012 10:05:38 AM</timestamp>
Question - Do I need to do anything different with the client or is it a server setting that needs modification?
You didn't specify if you were making the remote calls using HTTP or RMTP. If you're using RMTP you shouldn't have to do anything. If you're using HTTP you will need to modify the following files:
{Flash/Adobe Media Server Root}\conf\AMS.ini (or FMS.ini if you're on an older version)
{Flash/Adobe Media Server Root}\conf\Users.xml
In the first, you will need to set the USERS.HTTPCOMMAND_ALLOW option to true. In my version of the AMS.ini file it is at the very bottom of the configuration page.
In the Users.xml file, you will need to locate the block. In my version, this is also located towards the bottom of the page. The default install of Adobe Media Server 5 (in my case anyways) only allowed the "ping" method and all other methods were disallowed. You will either need to update that block to reflect a comma-delimited list of the methods you want to make accessible via HTTP (white listing) or allow all and deny none (I wouldn't recommend that).
Don't rely on a soft restart of the Adobe/Flash Media Server via the web based Administration Console. This did not work for me. I needed to restart the AMS service from within the Windows Services panel in order for the changes made in the configuration files to take effect.
I hope that this helps!
Rick
I'm working on a solution to intercept changes to the data from our node.js server and validate/alter them before they are stored/synced to other clients.
Any strategies or suggestions on how to solve this with the current code base?
Currently, it seems like the only option is to rewrite it post-sync operation. That would mean each client would probably receive the sync (including the server), then the server would rewrite the data and trigger a second sync.
To help understand the context of the question, here's what seems like an ideal strategy for my needs:
server gets a special token/key not available to clients (when security comes about)
server registers a dependency injection like firebase.child('widgets').beforeSync(myCallback)
client syncs data
server callback is notified
server modifies or validates the data
if valid, it returns it to firebase for sync ops
if invalid, aborts the sync with an error which is returned to the client
Thanks for sharing your ideas!
We've considered this type of approach. You can actually simulate this sort of behavior by structuring your data so that there is an "unvalidated" tree and a "validated" tree.
The "unvalidated" tree would be writeable by the client and the server would monitor it for changes. When a change occurs it would validate the data, and if it passes it would copy it into the "validated" tree which is only writeable by the server. You could pass errors back to the client through Firebase data as well when the validation fails.
This behavior could be packaged into a library that provides the behavior you describe. We may add this as core functionality as well, but we're still researching a variety of options.
Say, for example, you are caching data within your ASP.NET web app that isn't often updated. You have another process running outside of the app which ocassionally updates this data, when you do this you would like the cached data to be cleared immediately so that the next request picks up the new data straight away.
The caching service is running in the context of your web app and not externally - what is a good method of calling into the web app to get it to update the cache?
You could of course, just hack a page or web service together called ClearTheCache that does it. This can then be called by your other process. Of course you don't want this process to be externally useable or visible on your web app, so perhaps you could then check that incoming requests to this page are calling localhost, if not throw a 404. Is this acceptable? Could this be spoofed at all (for instance if you used HttpApplication.Request.Url.Host)?
I can think of many different ways to go about this, mainly revolving around creating a page or web service and limiting requests to it somehow, but I'm not sure any are particularly elegant. Neither do I like the idea of the web app routinely polling out to another service to check if it needs to execute something, I'd really like a PUSH solution.
Note: The caching scenario is just an example, I could use out-of-process caching here if needed. The question is really concentrating on invoking code, for any given reason, within a web app externally but in a controlled context.
Don't worry about the limiting to localhost, you may want to push from a different server in future. Instead share a key (asymmetrical or symmetrical doesn't really matter) between the two, have the PUSH service encrypt a block of data (control data for example) and have the receiver decrypt. If the block decrypts correctly and the data is readable you can safely assume that only the service that was supposed to call you has and you can perform the required actions! Not the neatest solution, but allows you to scale beyond a single server.
EDIT
Having said that an asymmetrical key would be better, have the PUSH service hold the private part and the website the public part.
EDIT 2
Have the PUSH service put the date/time it generated the cipher text into the data block, then the client can be sure that a replay attack hasn't taken place by ensuring the date/time is within an acceptable time period (say a minute).
Consider an external caching mechanism like EL's caching block, which would be available to both the web and the service, or a file to cache data to.
HTH.
The closest example I can think of is iTunes. I'm thinking about a system where a server stores loads of files, and each user only has access to those they have paid for. Using a desktop app, they can download these to their local PC where they are stored as regular files.
How might one approach this? I can see a couple of possible options, and have some initial thoughts, but would welcome feedback on these or other ideas. If you post your preferred design, people can vote on them!
1)Use HTTP requests, and the response is the file data. Then a simple servlet (or similar) can act as a control on which files are downloaded.
PROs: easy to do
CONs: seems a little hacky, how would you display a progress bar?
2)Use sockets, and a custom server app which pipes data to the server
PROs: Perhaps more performant (?), can send data in nice sized chunks
CONs: A little more work on the client side, quite a bit more to write a custom server-side app that runs 24/7
Thanks in advance. Someone please edit my tags, I can't think of the right ones!
Use HTTP requests, and the response is the file data. Then a simple servlet (or similar) can act as a control on which files are downloaded. PROs: easy to do CONs: seems a little hacky, how would you display a progress bar?
I don't see why this is hacky? Your App would authenticate using the user's user name and password (if you want it to work like iTunes) and fetch files according to permission level. A progress bar is easy to do because you will get the content-length header in the response. It's a more flexible approach than FTP - but if FTP already does everything you need, go for that.
As said, FTP is what you need. To control per user, per file permissions you can create one system user and then you can apply filesystem level ACLs. Then, a FTP server like PureFTPd will let you login with system accounts with the specified permissions.