I'm currently working on an app sending request on a server for a voting system. The problem is that people can vote without registration but I don't want them to vote multiple time and I don't know how to secure this. I thought about a key system (generated in the app and verified on the server), but I'm not sure that this is the best solution.
What should I do ?
There are two possible solutions to this.
1) Handle the code that detects the duplicate vote on the server
For each vote cast the server stores the device id against the identifier of the vote. The server ignores any duplicate votes cast for that topic and sends back a "failure" response. This is handled by the device.
Pros: Centralized voting logic. Change it once on the server and all versions of apps in the wild conform.
Cons: You have to build the server logic. If you're more comfortable with ObjectiveC this may be an issue. You have to maintain the database of voting topics and devices that have voted.
2) Handle the code that detects the duplicate vote on the device
The device downloads a list of all the voting topics then filters them by the topics that have already been voted on. When a user votes on a topic then the device adds the id of that topic to the filter list.
Pros: No database maintenance beyond having a list of voting topics.
Cons: Users could remove the app, reinstall and vote again. If you want to change the voting logic (e.g. you want people to be able to vote twice on a topic) you have to update all the existing apps.
Admittedly putting the voting logic in the app makes the app more complex. However that added complexity has to be absorbed somewhere - either in the app or on the server.
Related
I'm trying to build an Instant Messaging functionality in my app as part a bigger project.
Chats can have more than 2 participants (group chats)
If participant A delete a message, it still should be visible to participant B (that's why I used the Message Participants table)
Same applies to Conversation.
By same logic, if all participants delete the conversation/message, it should be erased from DB.
Questions :
I'm afraid that this schema is too cumbersome, meaning that the queries will be too slow once the app gets certain traffic mark (1k active users ? I'm guessing)
Message Participants will have multiple records for each message - one for each participants in the chat. Instant Messaging means it will involve those writes with very tight timings. Wouldn't that be a problem?
Should I add a layer of Redis DB, to manage a chat's active session's messaging? it will store the recent messages, and actively sync the PostgreSQL db with those messages (perhaps with Async transactions functionality that postgresql has?)
UPDATED schema :
I would also gladly hear ideas for having a "read" status functionality. I'm assuming it's much more complex with Group chats, so at least offering that for 1:1 chats would be nice.
I am a little confused by your diagram. Shouldn't the Conversation Participants be linked to the Conversations instead of the Message? The FKs look all right, just the lines appear wrong.
I wouldn't be worried about performance yet. The Premature Optimization Anti-Pattern warns us not to give up a clean design for performance reasons until we know whether we are going to have a performance problem. You anticipate 1000 users - that's not much for a modern information system. Even if they are all active at the same time and enter a message every 10 seconds, this will just mean 100 transactions per second, which is nothing to be afraid of. Of course, I don't know the platform on which you are going to run this. But it should be an easy task to set up those tables and write a simple test program that inserts those records as fast as possible.
Your second question makes me wonder how "instant" you expect your message passing to be. Shall all viewers of a message receive each keystroke of the text within a millisecond? Or do they just need to see each message appear right after it was posted? Anyway, the limiting factor for user responsiveness will probably be the network, not the database.
Maybe this is not mainly a database design issue. Let's assume you will have a tremendous rate of postings and viewings. But not all conversations will be busy all the time. If the need arises - but not earlier - it might be necessary to hold the currently busy conversations in memory and using the database just as a backup for future times when they aren't busy any more.
Concerning your additional comments:
100k users: This is a topic not for this forum, but concerning business development of a startup. Many founders of startup companies imagine huge masses of users being attracted to their site, while in reality most startups just fail or only reach very few. So beware of investments (in money, but also in design and implementation effort) that will only pay in the highly improbable case that your company will be the next Whatsapp.
In case you don't really anticipate such masses of users but just want to imagine this as a programming exercise, you still have a difficult task. You won't have the platform to simulate the traffic, so there is no way to make measurements on where you actually have a performance problem to solve. That's one of the reasons for the Premature Optimization warning: Unless you know positively where you have a bottleneck, you - and all of us - will be just guessing and probably make the wrong decisions.
Marking a message as read is easy: Introduce a boolean attribute read at Message Participants, and set it to true as soon as, well, the user has read the message. It's up to your business requirements in which cases and to whom you show this.
I have some concerns about using Firestore directly from mobile clients. I saw that with Firestore, mobile app is controls to db directly. There is only db side control is rules. However I am not yet understand how can I resolve my concerns. I worrying because with decompiling app or any other ways maybe someone can access maliciously.
To resolve my concerns and improve the security I want to:
Limit access per time for user. For example if some one writes or
reads db 30 second ago I want to block their access until 1 minute.
Especially it is important for writing.
I want to have the only document owner write their documents and
block others to write. For do this I don't want to store owner id in
same document because if I put this information to there, readers can
receive this information and maybe some way they can write request
with this information.
In summary, I want to prevent malicious and excessive requests exceeding limits. I want to avoid the risks in db side. How can I resolve my concerns in the two above matter?
Scenerio:
Think that there is harmful someone with name X. X knows how to
decompile mobile app or maybe knows how to request my application's
firebase Firestore account (maybe watched communication I don't know).
X wants to harm my application. First X watching communication and if
we give owner userid in document X receives needed information so
sending request with changing his/her userid or auth.uuid. Secondly X wants to
disable firebase of my application. For do this X sends too much
requests. The limit is overs due to too many requests. Note that: I am
using Firestore directly with mobile application. There is no web
service to communicate.
How can avoid this scenario?
We are generating the Primary Keys from(GUID) from client side and passing to server.
From some of the articles and blogs we came to know that Azure client sdk pushes the records in random order.
We have created a 2 tables with relations and tested this in offline mode and it works well. So we would like to confirm if the latest client side sdk has done some code fix to send the records in some order.
I wonder why can't they create a queue so that it will push the first in first out manner.
Since we have foriegn key relations in server side we need to push the inserts in an orderly manner, is there any mechanism to make this pushes to server in a specified order?
is there any mechanism to make this pushes to server in a specified order?
We could get the answer from this book-chapter3/relationships/.
The former is generally handled for you. If you InsertAsync a tag in offline mode, it will be placed into the operations queue prior to anything that uses it. Since the operations queue is processed in order, the tag will be sent to the backend prior to any record updates that would use it.
Note: Prefer handling tables individually and handling relationship management on the mobile client manually. This causes more code on the mobile client but makes the server much simpler by avoiding most of the complexity of relationships.
I'm designing an iPhone app that communicates with a server over HTTP.
I only want the app, not arbitrary HTTP clients, to be able to POST to certain URL's on the server. So I'll set up the server to only validate POSTs that include a secret token, and set up the app to include that secret token. All requests that include this token will be sent only over an HTTPS connection, so that it cannot be sniffed.
Do you see any flaws with this reasoning? For example, would it be possible to read the token out of the compiled app using "strings", a hex editor, etc? I wouldn't be storing this token in a .plist or other plain-text format, of course.
Suggestions for an alternate design are welcome.
In general, assuming that a determined attacker can't discover a key that is embedded in application on a device under his physical control (and, probably, that he owns anyway) is unwarranted. Look at all of the broken DRM schemes that relied on this assumption.
What really matters is who's trying to get the key, and what their incentive is. Sell a product aimed at a demographic that isn't eager to steal. Price your product so that it's cheaper to buy it than it is to discover the key. Provide good service to your customers. These are all marketing and legal issues, rather than technological.
If you do embed a key, use a method that requires each client to discover the key themselves, like requiring a different key for each client. You don't want a situation where one attacker can discover the key and publish it, granting everyone access.
The iPhone does provide the "KeyChain" API, which can help the application hide secrets from the device owner, for better or worse. But, anything is breakable.
The way I understand it, yes, the key could be retrieved from the app one way or another. It's almost impossible to hide something in the Objective-C runtime due to the very nature of it. To the best of my knowledge, only Omni have managed it with their serial numbers, apparently by keeping the critical code in C (Cocoa Insecurity).
It might be a lot of work (I've no idea how complex it is to implement), but you might want to consider using the push notifications to send an authentication key with a validity of one hour to the program every hour. This would largely offload the problem of verifying that it's your app to Apple.
I suggest to add some checksum (md5/sha1) based on the sent data and a secret key that your app and the server knows.
Applications can be disassembled so that they could find your key.
More information is needed to determine whether the approach is sound. It may be sound for one asset being protected and unsound for another, all based on the value of the asset and the cost if the asset is revealed.
Several earlier posters have alluded to the fact that anything on the device can be revealed by a determined attacker. So, the best you can do is determine valuable the asset is and put enough hurdles in the way of the attacker that the cost of the attack exceeds the value of the asset.
One could add to your scheme client-side certificates for the SSL. One could bury that cert and the key for the token deep in some obfuscated code. One could probably craft a scheme using public/private key cryptography to further obscure the token. One could implement a challenge/response protocol that has a time boxed response time wherein the server challenges the app and the app has X milliseconds to respond before it's disconnected.
The number and complexity of the hurdles all depend on the value of the asset.
Jack
You should look into the Entrust Technologies (www.entrust.com) product line for two-factor authentication tied to all sorts of specifics (e.g., device, IMEI, application serial number, user ID, etc.)
I'd like to have something in my app that is just like Twitter but not Twitter. Basically it will be a place people can submit messages and do not need an account. They only way they can submit is through the app. I want other app users to see the submitted messages nearly immediate. I believe push notification can do that sort of work but do I need push notification for this? How does Twitter do it?
-- EDIT --
After reading some of the responses, push might be what I need. People will be submitting messages to my server often. If someone is watching the feed, they might see one new message per minute depending on the query they are using. I'm thinking to go with a MySQL database, (which allows switching to cheaper non Windows servers w/o much hassle) and push notification. Are there any reasons those won't work for my scenario?
You only need push notification if you want the app to be able to receive new messages while closed.
Here's a rough description of one way to do this:
Your app sends a message via HTTP Post to your server.
Your server stores the message in a database, using the iPhones unique ID as an identifier.
Your app connects to the server frequently, asking for new messages.
If there are any new ones, the server hands the message to the app, which displays it.
This is approximately what twitter/iphone twitter apps do.
Your choices are fairly binary:
Use push notification
Use Polling
With Push Notification:
You control when you contact your users... Heavy Load means you can slow updates down to avoid taxing your infrastructure
Contrariwise, you have to push to clients that may not even be there anymore (And thus may need some sort of register model), high load may mean that clients don't get immediate update
You can leverage things like Amazon's EC2 to give you more processing power
Unless you're out of capacity, users are almost certain to be receiving updates as they happen
To pick up messages missed while offline, the SERVER needs to know what message was last successfully received, store older messages and forward many all at once
If you choose to use polling:
You must have a stable address to be polled
You need the ability to have lots of quick query connections checking for new data, then returning that data if required.
If your application becomes popular enough you may find you don't have enough resources
If your resources are taxed your application will go down, rather then just slow down
You don't need to register clients and keep track of their on/offline state
Parallelizing on the fly is a bit trickier
To pick up older messages, the CLIENT needs to know when they last received a message and then request the server send any message since that time
Both can be fast, but they come with different bandwidth and processing profiles. I prefer push for everything that's real-time.
Might want to take a look at XMPP.
Twitter doesn't really push events out to the iPhone in realtime. It's more like polling by the various clients.
If you really want instantaneous for the last mile you'll want to use push.
Twitter uses lots of servers and raid arrays to handle the load of millions of people posting 140 character messages. Twitter clients log in and request a list of updates for all of the people the user is following within a certain time frame.
Push wouldn't be a good candidate for this because it does not persist the "tweets". It is simply a notification mechanism. There is a text messaging app on the App Store (called Ping!) that relies completely on push notification for sending text messages. This seems to work fine, but if the developers are keeping track of the messages, it is all done on their servers. In their case push makes sense as you want to alert the user of a new message. In the case of a twitter clone, however, it would probably just annoy users if they got a new notification every time someone tweeted.
In the end you're better off just implementing it server side and then developing an iPhone client that logs in and retrieves the latest tweets for the people the user is following.