I'm building a financial services web application and my company wants to incorporate facebook authentication into it. Because we're in the finance world, security is paramount. I'm using the facebook PHP SDK for integration, but I'm really concerned about session hijacking. In my college days I would session hijack the crap out of everyone around me (which was great fun), but I'm trying to find a way to prevent this with my application.
My company wants the authentication process as streamlined as possible, so that means something like two-factor authentication is not desirable. But prompting the user for another piece of information AFTER facebook login seems to be the most secure way of doing it. I'm wondering if any of you clever people can come up with some other way of securing this while keeping the entire process simple and quick?
Another piece of information is only useful if P(attacker-has-extra-info | attacker-hijacked-session) is low.
If you can use a complicated second factor the first time they interact (or interact in a security sensitive way) with you and then remember the machine from which they connect to skip the second factor on subsequent visits, then you can get streamlined interaction in general.
Asking for something like their balance on their last statement to authenticate a device for the first time might be a good second factor -- it would prove that they already know something that is presumably privileged related to that account.
Alternatively, sending a text with a random number to a mobile device associated with the account can act as a second factor assuming they are not connecting from that device.
Related
We are building a very small API that receives winning contest entries for prize fulfillment. The data we are receiving is:
account ID (members know their account IDs)
prize ID
address
consent
date
Here is the problem... If someone dissects the mobile app they could theoretically locate prize IDs, their account ID, and submit fictitious winning entries to our API.
The submissions are coming from a mobile app. So we can't restrict the API to a specific IP address or anything.
I am not developing the actual app, just the API. The API will likely be programmed using PHP.
Is there a way to prevent someone from submitting fictitious contest entries?
Notes:
I found similar questions asked, but they mostly don't have a solid answer or they are were asked years ago. I'm wondering if anything has changed since they were answered.
We have one solution, but it requires a second API call coming from the app's server. I'm hoping there is a more simple solution.
Edit 1: Users are logged into their app, but the only piece of data we are receiving is their member ID.
Edit 2: I don't actually know what is determining the winner. I am not developing this part of the app. I hope it's not being done client side.
No matter what you do, it will always be falsifiable. All you can do is authentication of your users with email and password, but as far as I understand this is the registration process and anyone can register. All you can do is adding a captcha, so they will register manually instead of automatically at least. Your can add an API key to the app, but it will be easy to steal from the HTTP request. You can add a private key to the app to sign each request and some protection against replay attacks, and it will be somewhat harder to steal the private key, but it will be possible by dissecting the app. So you can make it a little harder, but this is a security, not a technical problem, and there is no good solution. You need to check the risks, what happens when they do it, what are the consequences, is there an alternative way to detect it, is there a workaround e.g. personal registration, or registration with FB account only, etc.
Your Problem
If someone dissects the mobile app they could theoretically locate prize IDs, their account ID, and submit fictitious winning entries to our API.
Reverse engineering a mobile app isn't hard because nowadays a lot of open source tools exist to automate this for us to the point that even non developers can do it. You can see how easy it is by following the example on an article I wrote to show How to Extract an API key from a Mobile App with Static Binary Analysis:
The range of open source tools available for reverse engineering is huge, and we really can't scratch the surface of this topic in this article, but instead we will focus in using the Mobile Security Framework(MobSF) to demonstrate how to reverse engineer the APK of our mobile app. MobSF is a collection of open source tools that present their results in an attractive dashboard, but the same tools used under the hood within MobSF and elsewhere can be used individually to achieve the same results.
During this article we will use the Android Hide Secrets research repository that is a dummy mobile app with API keys hidden using several different techniques.
With all the prize ids identified from reverse engineering the mobile app with MobSF framework its time to perform a MitM attack to learn how the API requests are made. MitM attacks are also easy to perform and you learn how to do one from reading my article that show how to Steal that Api Key with a Man in the Middle Attack:
In order to help to demonstrate how to steal an API key, I have built and released in Github the Currency Converter Demo app for Android, which uses the same JNI/NDK technique we used in the earlier Android Hide Secrets app to hide the API key.
So, in this article you will learn how to setup and run a MitM attack to intercept https traffic in a mobile device under your control, so that you can steal the API key. Finally, you will see at a high level how MitM attacks can be mitigated.
Now that you know the prize ids, how the mobile app does the API requests and how the responses look like it will be easy to replicate and automate such requests with a script. In fact the mitmproxy and all other tools allow you to save the API requests to later replicate them.
User authentication alone will not be enough to solve your problem of preventing the submission of fictitious winning entries to your API backend, because it only tells who is in the request made to your API backend, but your backend also needs to have a very high degree of confidence that what is doing the API request is indeed a genuine and unmodified instance of the mobile app uploaded to the app store of Android and iOS. In the article Why Does Your Mobile App Need An Api Key? you can read in more detail the difference between who and what is accessing your API server:
The what is the thing making the request to the API server. Is it really a genuine instance of your mobile app, or is it a bot, an automated script or an attacker manually poking around your API server with a tool like Postman?
The who is the user of the mobile app that we can authenticate, authorize and identify in several ways, like using OpenID Connect or OAUTH2 flows.
So think about the who as the user your API server will be able to Authenticate and Authorize access to the data, and think about the what as the software making that request in behalf of the user.
After you understand this idea and it's ingrained in your mindset, you will look into mobile API security with another perspective, and you will be able to see attack surfaces that you never though they could exist.
Possible Solutions
Is there a way to prevent someone from submitting fictitious contest entries?
It's not easy, but its possible to achieve with a very high degree of confidence. The degree of success will depend on the solution(s) you decide to adopt from reading this answer I gave to the question How to secure an API REST for mobile app?, especially the sections Hardening and Shielding the Mobile App, Securing the API Server and A Possible Better Solution.
The Mobile App Attestation is the solution that will give the most high degree of confidence to your API server that the API request is from what it expects, a genuine and unmodified mobile app, one that is not under attack or have been tampered with.
I know you may not be in control off, but no matter what security solution(s) are adopted it would be wise to not have the mobile app deciding the prize winners, because anything that runs on the client side can be tampered with at runtime, including business logic. One of the best tools to tamper with a mobile app during runtime it's Frida:
Inject your own scripts into black box processes. Hook any function, spy on crypto APIs or trace private application code, no source code needed. Edit, hit save, and instantly see the results. All without compilation steps or program restarts.
Do You Want To Go The Extra Mile?
In any response to a security question I always like to reference the excellent work from the OWASP foundation.
For APIS
OWASP API Security Top 10
The OWASP API Security Project seeks to provide value to software developers and security assessors by underscoring the potential risks in insecure APIs, and illustrating how these risks may be mitigated. In order to facilitate this goal, the OWASP API Security Project will create and maintain a Top 10 API Security Risks document, as well as a documentation portal for best practices when creating or assessing APIs.
For Mobile Apps
OWASP Mobile Security Project - Top 10 risks
The OWASP Mobile Security Project is a centralized resource intended to give developers and security teams the resources they need to build and maintain secure mobile applications. Through the project, our goal is to classify mobile security risks and provide developmental controls to reduce their impact or likelihood of exploitation.
OWASP - Mobile Security Testing Guide:
The Mobile Security Testing Guide (MSTG) is a comprehensive manual for mobile app security development, testing and reverse engineering.
I've written an Android game and need to store the game state on my game server. I am pretty much a novice at is right for the above mentioned application. My current approach to network programming and security/technology:
RESTful web service written in PHP on the server.
Use of .htaccess to enable nice PUT / GET address commands.
MySQL database with user name, password, and data fields, e.g. in game purchased items, in game currency.
Salted & hashed passwords.
Is this approach is acceptable, i.e. is it secure? Or perhaps it's overkill; is there anything missing in general with respect to security?
Should I store id, username, and salted/hashed passwords in a users database, and then store user data, e.g. in app purchased items, in game currency, in a separate data database, which is indexed by the id in the user database?
I will be implementing HTTPS, so communication between client/server is secure, and authorization tokens, so that I know my server is communicating with whom it should be. (This seems a good tutorial.)
Using authorization tokens means I probably don't need to store/deal with username and passwords directly.
Security:
You have some elements of best practices, but there are some things missing.
Use HTTPS so that the traffic between the Android app and your PHP web server is encrypted. Otherwise anyone can "wiretap" and see what's in the packets going back and forth. Read https://blog.hartleybrody.com/https-certificates/ and https://www.digitalocean.com/community/tutorials/how-to-create-a-self-signed-ssl-certificate-for-apache-in-ubuntu-16-04
You only want people running your Android app to submit REST API requests. But anyone using a browser or running curl code can reach your REST server. You need to use authentication, so access to your REST API is restricted to legitimate clients. For example, see https://stormpath.com/blog/the-ultimate-guide-to-mobile-api-security
Please also read the book Essential PHP Security. Any web developer should learn proper security practices, in the same way that an electrician needs to learn how to do safe wiring to prevent accidental fires.
Database design:
You seem to be using the word "database" where I would expect you to say "table." Yes, you can and should have multiple tables on your MySQL server. The application I support has over 120 tables, and there are certainly many applications with many more tables. It depends on the complexity of the data you need to store.
Here's a good book to start with: Database Design for Mere Mortals
If you want to get more into the theory behind the practice, I enjoyed SQL and Relational Theory: How to Write Accurate SQL Code 3rd Edition.
And I have to plug my own book: SQL Antipatterns Volume 1: Avoiding the Pitfalls of Database Programming.
I am working on an Android app that deals with some slightly sensitive information (Names, Usernames, Passwords, Badge number, etc)... As far as code work goes, I know how to connect to a MySQL database with PHP and pull information from it via JSON. I am just worried about the security of doing this. I know there are plenty of Android and iPhone apps that currently implement login systems, but I was curious as to how secure those logins are.
Does anyone know where I can find some information on creating a secure connection to a database with PHP and MySQL for my login system through an Android app? I know nothing is completely impenetrable, but I want to make sure the security of my app is as tight as possible.
As always, I am still getting used to StackOverflow, so if I was not clear or this question has already been answered, let me know!
If you're rolling your own authentication code, it's really hard to say how secure it is. Often people get this horribly wrong and the code has the opposite effect: Instead of securing the site it exposes several severe holes that can be used to hijack it and download arbitrary data.
A development framework like Laravel comes with an authentication system built-in. If there's vulnerabilities in that code, which is reviewed by the community, there's usually an advisory posted so you'll know and can patch as necessary.
If you follow best practices, you should be fine. JSON via PHP or any other language is a good way to go if you want to keep things simple and secure.
Its really hard to gain 100% , but you can use some techniques like
SSL
Session for each user
something like verification code sent through SMS
Encryption data before sent over API calls etc
It is incredibly insecure to connect to a remote db from an app. Think of it like connecting to a database from javascript in your browser, because it is the same level of security.
As an important aside,
slightly sensitive information (Names, Usernames, Passwords, Badge number, etc).
Passwords are not slightly sensitive, they are critically sensitive. I'm not sure if you are implying that passwords are being stored in a reversible format, but they should be hashed.
Anyway, to your main question, instead of connecting directly to a database from the client-side device, you will want to create an API that provides limited access. You would write this in the form of a web service, using some server-side programming. From there, you'll simply use an API key/roles based on the current logged in user. This is the secure/proper way to design this system. You do not want to put db credentials in an app, unless they are for a local db on the phone.
To extend what Gray said, you can pass the JSON data through the URL that you're shipping to the web service that's providing the front end to your DB. There are a couple of other examples that you can find here to start. As pointed out, it's a really bad idea to have direct DB access. Even with a front end, you'll want to ensure that you're doing lots of data checking in the front end. Don't pass direct SQL queries! They're too easy to hack. SQL injection continues to be one of the most successful attacker techniques.
You might consider a Mobile Backend as a Service provider, like Kii, Kumulos, Kinvey, Kony (not sure why they all start with K...), or built.io. They'll cost you money, but save you headaches.
So I have a web application which is going to collect people's opinion (People have to choose option 1 or option 2). I don't want anyone to submit their opinion twice or more, which makes me think an opinion is more popular when it isn't, so I think of several ways, but they all have their disadvantage:
Check user's IP address: user can change their IP easily by using web proxy or something like that.
Check user's HWID like what I did on another desktop application: Seem like it's impossible with php
Can you suggest me a way which is the most effective for my web application's issue? The ideal solution is having only one vote per device, but I have no idea how to do it with PHP.
Edit: Please give me your advice on this: does cookie work with web proxy? If the application stored a cookie, then the user open the website with web proxy or simply use private browsing, is the cookie still there? If it is, a combination between IP address and cookie may works.
To prevent accidental multiple submissions, require a login and save the vote in a database, or create a random unique ID that is tied to the user's session, and save that one with the vote, rejecting votes whose IDs already exist, or save a flag in the session that the user already voted.
You could use ever-/super-cookies to make deliberately faking votes harder, but you cannot prevent them unless you have some means to verify an identity and ensure that no person can have multiple identities, e.g. ID cards issued by the government with functions for eCommerce and e(Whatever), social security numbers. However, you will have to interface with an institution performing the verification for you.
And ever-/super-cookies and browser fingerprinting are vulnerable to the use of multiple browsers and break when facing paranoid users.
If you want to prevent multiple deliberate votes with low security and reliability, you could establish an identity like on StackExchange / StackOverflow, i.e. reputation-based, and prevent votes until someone has gained some reputation level.
Or you could require phone-/account-/credit-card-/payments-based verification with low level of confidence (e.g. send SMS text message with verification code to phone number, Facebook, Google, Amazon, PayPal, Stripe...) - people can have multiple phones, accounts, credit/debit cards etc.
In the end, there is no easy-to-use system for identity verification that prevents multiple identities with high confidence (that I know of).
I want to build an API for users to build applications that easily interact with a site, and I was wondering what the best way to authenticate users would be.
Taking a look at other API's a lot of them have the user send the username and password as a GET parameter over a HTTPS connection. Is this the best way to go about it? Or are there other methods that I should look into or consider?
I've seen OAuth been tossed around and it looks like a good solution, but just for a simple API is it overkill?
You can use API key's. Generate a unique hash tied to an account upon request. Then check that the key is a valid key. As long as the API doesn't have any major security issues with someone using someone else's key then Authorization isn't needed. If there is a problem with someone using someone else's key then Authentication would be justified.
This is usually achieved with cookies.
The client sends their username and password with a POST request to your API (do not use GET, that's insecure). If the credentials are acceptable, then generate a random, unique session key, store it on your side and send it in a cookie back to the client (see setcookie()).
When the client now makes further requests, they send the session key cookie with the request. Check $_COOKIE for the session key if it matches a stored key on your side; if yes, that means the user authenticated.
Take note that this minimal example is vulnerable to brute-force attacks trying to guess valid session keys. You need to log invalid keys that clients send in their cookies and block their IP address for some period of time to prevent this.
Username / password in a GET isn't a great way to do this because you're potentially exposing the whole user account for hijacking even if the API has more limited functionality than logging into the site. So it's good practice to separate concerns between Web-site login and API access.
I'm not sure which case you're in but:
If the users are business customers of somekind who are embedding some type of widget or code in another website then it's probably best to use an API key which is scoped to the referrer domain (much like Google Maps does).
If they are end-users who won't know anything about the API but are going to be using Apps built by third parties then oAuth is likely to be your best bet, otherwise your users might literally be giving their usernames/passwords to unknown third parties. It's more complex but likely to be worth it in the long run.
To get a bunch of this stuff out of the box you can use something like 3scale (http://www.3scale.net) and it'll handle most of it for you (disclaimer, I work there so adjust for bias!) or there are open source libraries for oAuth in most languages (in PHP Zend-OAuth component might do the job for you).