Authorizing users by downloading file from external SharePoint portal - php

I have an open question about my idea. Here's some background:
I'm developing a PHP application for the company I work in. It's meant to be used only by its employees. Every employee has access to our SharePoint portal. Basically the app has to be accessible only for people, that have access to our SharePoint.
I've got an idea to use SP to authorize users in my app. Authorization would be based on downloading a secured file from SP (one for all users), using CURL. If the file is correctly downloaded you're logged in. If it isn't, you're not allowed to access the app (there would be exception handling of course).
So, each person, who has access to SP, would have access to the app. The app and SP are located at different servers.
What do you think about that idea? Will it be safe? Is it a good idea at all?
I've listed some pros and cons that came to my mind...
Pros:
easy to develop
access control is held by SharePoint
users don't have to learn new logins and passwords
IMO it should be safe, because no passwords would be stored in the app's database
Cons / vulnerabilities:
possibility that the file will be accidentally deleted
Cheers,
Zibi

This is not a good idea. You are basically trusting the client to authenticate itself, which is very bad. You must assume that the client code is completely compromised and has been modified by an attacker to bypass your controls.
Generally speaking, "roll-your-own" security is a recipe for disaster. You should take advantage of PHP's built in session tracking mechanism. You can find a good tutorial here if you don't know how to use it yet. Your user's will have to authenticate again, but unfortunately that is necessary for proper security.
Also keep in mind that with your suggested solution there could be no access controls beyond "employee." This is severely limiting in the future if you ever need to provide the ability to restrict users access to resources based on user ID, roles or groups. You'll be much happier in the future if you do it properly at this point in the game.

Related

How to protect a rest api for android app [duplicate]

Is there any way to restrict post requests to my REST API only to requests coming from my own mobile app binary? This app will be distributed on Google Play and the Apple App Store so it should be implied that someone will have access to its binary and try to reverse engineer it.
I was thinking something involving the app signatures, since every published app must be signed somehow, but I can't figure out how to do it in a secure way. Maybe a combination of getting the app signature, plus time-based hashes, plus app-generated key pairs and the good old security though obscurity?
I'm looking for something as fail proof as possible. The reason why is because I need to deliver data to the app based on data gathered by the phone sensors, and if people can pose as my own app and send data to my api that wasn't processed by my own algorithms, it defeats its purpose.
I'm open to any effective solution, no matter how complicated. Tin foil hat solutions are greatly appreciated.
Any credentials that are stored in the app can be exposed by the user. In the case of Android, they can completely decompile your app and easily retrieve them.
If the connection to the server does not utilize SSL, they can be easily sniffed off the network.
Seriously, anybody who wants the credentials will get them, so don't worry about concealing them. In essence, you have a public API.
There are some pitfalls and it takes extra time to manage a public API.
Many public APIs still track by IP address and implement tarpits to simply slow down requests from any IP address that seems to be abusing the system. This way, legitimate users from the same IP address can still carry on, albeit slower.
You have to be willing to shut off an IP address or IP address range despite the fact that you may be blocking innocent and upstanding users at the same time as the abusers. If your application is free, it may give you more freedom since there is no expected level of service and no contract, but you may want to guard yourself with a legal agreement.
In general, if your service is popular enough that someone wants to attack it, that's usually a good sign, so don't worry about it too much early on, but do stay ahead of it. You don't want the reason for your app's failure to be because users got tired of waiting on a slow server.
Your other option is to have the users register, so you can block by credentials rather than IP address when you spot abuse.
Yes, It's public
This app will be distributed on Google Play and the Apple App Store so it should be implied that someone will have access to its binary and try to reverse engineer it.
From the moment its on the stores it's public, therefore anything sensitive on the app binary must be considered as potentially compromised.
The Difference Between WHO and WHAT is Accessing the API Server
Before I dive into your problem I would like to first clear a misconception about who and what is accessing an API server. I wrote a series of articles around API and Mobile security, and in the article Why Does Your Mobile App Need An Api Key? you can read in detail the difference between who and what is accessing your API server, but I will extract here the main takes from it:
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.
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.
So if you are not using user authentication in the app, then you are left with trying to attest what is doing the request.
Mobile Apps should be as much dumb as possible
The reason why is because I need to deliver data to the app based on data gathered by the phone sensors, and if people can pose as my own app and send data to my api that wasn't processed by my own algorithms, it defeats its purpose.
It sounds to me that you are saying that you have algorithms running on the phone to process data from the device sensors and then send them to the API server. If so then you should reconsider this approach and instead just collect the sensor values and send them to the API server and have it running the algorithm.
As I said anything inside your app binary is public, because as yourself said, it can be reverse engineered:
should be implied that someone will have access to its binary and try to reverse engineer it.
Keeping the algorithms in the backend will allow you to not reveal your business logic, and at same time you may reject requests with sensor readings that do not make sense(if is possible to do). This also brings you the benefit of not having to release a new version of the app each time you tweak the algorithm or fix a bug in it.
Runtime attacks
I was thinking something involving the app signatures, since every published app must be signed somehow, but I can't figure out how to do it in a secure way.
Anything you do at runtime to protect the request you are about to send to your API can be reverse engineered with tools like 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.
Your Suggested Solutions
Security is all about layers of defense, thus you should add as many as you can afford and required by law(e.g GDPR in Europe), therefore any of your purposed solutions are one more layer the attacker needs to bypass, and depending on is skill-set and time is willing to spent on your mobile app it may prevent them to go any further, but in the end all of them can be bypassed.
Maybe a combination of getting the app signature, plus time-based hashes, plus app-generated key pairs and the good old security though obscurity?
Even when you use key pairs stored in the hardware trusted execution environment, all an attacker needs to do is to use an instrumentation framework to hook in the function of your code that uses the keys in order to extract or manipulate the parameters and return values of the function.
Android Hardware-backed Keystore
The availability of a trusted execution environment in a system on a chip (SoC) offers an opportunity for Android devices to provide hardware-backed, strong security services to the Android OS, to platform services, and even to third-party apps.
While it can be defeated I still recommend you to use it, because not all hackers have the skill set or are willing to spend the time on it, and I would recommend you to read this series of articles about Mobile API Security Techniques to learn about some complementary/similar techniques to the ones you described. This articles will teach you how API Keys, User Access Tokens, HMAC and TLS Pinning can be used to protect the API and how they can be bypassed.
Possible Better Solutions
Nowadays I see developers using Android SafetyNet to attest what is doing the request to the API server, but they fail to understand it's not intended to attest that the mobile app is what is doing the request, instead it's intended to attest the integrity of the device, and I go in more detail on my answer to the question Android equivalent of ios devicecheck. So should I use it? Yes you should, because it is one more layer of defense, that in this case tells you that your mobile app is not installed in a rooted device, unless SafetyNet has been bypassed.
Is there any way to restrict post requests to my REST API only to requests coming from my own mobile app binary?
You can allow the API server to have an high degree of confidence that is indeed accepting requests only from your genuine app binary by implementing the Mobile App Attestation concept, and I describe it in more detail on this answer I gave to the question How to secure an API REST for mobile app?, specially the sections Securing the API Server and A Possible Better Solution.
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.
No. You're publishing a service with a public interface and your app will presumably only communicate via this REST API. Anything that your app can send, anyone else can send also. This means that the only way to secure access would be to authenticate in some way, i.e. keep a secret. However, you are also publishing your apps. This means that any secret in your app is essentially being given out also. You can't have it both ways; you can't expect to both give out your secret and keep it secret.
Though this is an old post, I thought I should share the updates from Google in this regard.
You can actually ensure that your Android application is calling the API using the SafetyNet mobile attestation APIs. This adds a little overhead on the network calls and prevents your application from running in a rooted device.
I found nothing similar like SafetyNet for iOS. Hence in my case, I checked the device configuration first in my login API and took different measures for Android and iOS. In case of iOS, I decided to keep a shared secret key between the server and the application. As the iOS applications are a little bit difficult to reversed engineered, I think this extra key checking adds some protection.
Of course, in both cases, you need to communicate over HTTPS.
As the other answers and comments imply, you cant truly restrict API access to only your app but you can take different measures to reduce the attempts. I believe the best solution is to make requests to your API (from native code of course) with a custom header like "App-Version-Key" (this key will be decided at compile time) and make your server check for this key to decide if it should accept or reject. Also when using this method you SHOULD use HTTPS/SSL as this will reduce the risk of people seeing your key by viewing the request on the network.
Regarding Cordova/Phonegap apps, I will be creating a plugin to do the above mentioned method. I will update this comment when its complete.
there is nothing much you can do. cause when you let some one in they can call your APIs. the most you can do is as below:
since you want only and only your application (with a specific package name and signature) calls your APIs, you can get the signature key of your apk pragmatically and send is to sever in every API call and if thats ok you response to the request. (or you can have a token API that your app calls it every beginning of the app and then use that token for other APIs - though token must be invalidated after some hours of not working with)
then you need to proguard your code so no one sees what you are sending and how you encrypt them. if you do a good encrypt decompiling will be so hard to do.
even signature of apk can be mocked in some hard ways but its the best you can do.
Someone have looked at Firebase App Check ?
https://firebase.google.com/docs/app-check
Is there any way to restrict post requests to my REST API only to requests coming from my own mobile app binary?
I'm not sure if there is an absolute solution.
But, you can reduce unwanted requests.
Use an App Check:
The "Firebase App Check" can be used cross-platform (https://firebase.google.com/docs/app-check) - credit to #Xande-Rasta-Moura
iOS: https://developer.apple.com/documentation/devicecheck
Android: https://android-developers.googleblog.com/2013/01/verifying-back-end-calls-from-android.html
Use BasicAuth (for API requests)
Allow a user-agent header for mobile devices only (for API requests)
Use a robots.txt file to reduce bots
User-agent: *
Disallow: /

android enable access to application only to users who purchased the application

I have a html5 Web View Android application which uses php website . How do I enable the use of website only for people who have purchased the application .I was thinking of a combination of getting the users android device id in combination with php mysql generated id and preventing php site access by using a php library that checks if client is a mobile phone .Perhaps even Google application licensing - I don't know how easy is to get around this by recompiling of application ?Maybe even a good way to hide the url inside Android application.
Where do users purchase the application? How do they get access to your website?
If they purchase your app from Google Play, then you should use some form of authentication/authorization that forces them to sign into your website and establish credentials there and on the device.
Please don't use the device id. That's not particularly friendly, and it opens up a security hole. In addition, it's an inconvenience to users who upgrade (or lose) a device.
A username and password should be sufficient security for most situations. If it isn't in your case, then you could also consider establishing an encrypted key on the device after the user first logs into your site. The key could be based on various values that the user would have difficulty reproducing on a different device.
One must consider the tradeoff of securing against undesired access versus the effort involved. How likely is it that users will give away their username and passwords to allow others to use your site? If you secure something too much, nobody will use it.

Create secure API communication

I am looking to build an API that I can deploy on my servers to monitor system load.
It will report to a central manager server that runs a client to display the information.
The issue I am struggling with is best to secure the API.
What I want is for the client to be the only software that can access the server and retrieve this information but I am unsure how to achieve this using PHP.
I also want the possibility of distributing the API and client for others to use on their servers so I don't want people to be able to access other people data if they are using the API also.
The client is also written in PHP using MySql and has a secure login.
This sounds like you're trying to solve the wrong problem.
I also want the possibility of distributing the API and client for others to use on their servers so I don't want people to be able to access other people data if they are using the API also.
The only right answer to this is authentication. You need to protect your API by giving each user access credentials known only to them.
Your API must never reveal any data that the client isn't allowed to see as per their authentication credentials. Trying to work around this danger by trying to somehow protect the client from prying eyes is not safe - somebody who has access to the client and can observe it running will be able to reverse engineer any traffic between it and the server given enough effort.
If the API is properly secured, it won't matter to you which client tool is used to access it. The requirement to limit API access to a certain program will go away.
if you use SSL, along with authentication (i use 3rd party auth google, fb, etc), create data /reports on the fly and have the data saved in a subdirectory OUTSIDE your web folder (instead of /var/www, /var/myStorage/currentSessionId/), then you basically guarantee the security that you want.
your php will only access a subdir that is named for the session it is running under.

Authentication Across Sites

I have 2 sites:
SITE A - an asp.net site
SITE B - a php site
We have all the user information in an asp.net site (which is actually a Kentico site).
Now, there is a business requirement that users should be able to log-in with the same credentials in Site B. Ideally, we would need that users who log-in Site A, and navigate to Site B, the authentication would be automatic.
Is there a way to achieve this form of authentication. Or is it not possible?
This is not an authentication problem, but an authorization one. Once you have authenticated your user, in whichever way you want, with whichever technology you want, you probably will grant them some sort of token that you will then use to grant authorization to the different resources in your sites.
In your case you have two different technologies, which only means that you won't be able to use the out of the box asp.net or php session management, but all you need to do is have a common place to check that the session tokens are valid, they belong to a legitimate user and that user has permissions to access this resource.
If the above is trivial, sorry, maybe your question is more oriented to the sites being in two different domains, and therefore not being able to use a domain cookie to store the session information. is that the case?
The canonical solution to this is to use a protocol like OpenID. OpenID allows a website to ask a user to authenticate themselves using a different site, and then honour those credentials; using a protocol called "attribute Exchange", the authentication provider can provide additional data about the user.
OpenID is how StackExchange manages to log you in with your Google account (or whatever you're using), and how sites in the SO network recognize your identity without you logging in everywhere.
The benefit for OpenID is that it's a widely used protocol, so it's likely to be highly secure and well-tested; you don't risk weaving your own solution and accidentally exposing your users to security risks. It's well-documented, and widely supported.
There's an OpenID framework for .Net which allows you to create your own OpenID provider; it appears Kentico supports OpenID as an authentication mechanism. There are several OpenID libraries for PHP (Google is your friend here).
Exactly how you implement this depends on how your Kentico authentication works right now, but in principle it should be fairly easy to glue the Kentico user database to an OpenID provider you write; getting Kentico to use that for authentication appears to be a configuration setting. You'd have to re-write the PHP site to use OpenID; again, not clear how that currently works, but I can't imagine it would be harder than any other solution you might try.
I had a similar issue on a .net platform where I didn't have the option to put them on one subdomain. In that case you could pass the username and a token (that signified the user was already authenticated by site B) and perhaps the encrypted password to re-authenticate against an external DB, then redirect them to the site. In my case I needed to do this as I was redirecting to the corresponding site CMS for site admins.

How to create a centralized user database

My company creates a lot of applications that have very similar functionality, with a few differences between each one. For example, some sites have a group creation feature, others have user profile pages, and yet others allow users to accumulate achievement points and such.
Our clients want users to be able to log in to each application with the same username/password, since it doesn't really make sense for the user to have to register a different account for each site.
How do we design our database? Is it better to have a single central database for all of our applications, or separate them into individual databases and do JOINs across databases? Which is better performance-wise and design-wise?
Thanks for any insight!
Just go with OpenID. Simplest to just use Facebook Connect as a provider. They let you get to all of your user's data (like name etc.) so you can identify and data mine them if need be.
If you don't want to rely on an external provider to handle your user accounts, then become your own OpenID provider.
I would have a central server, which hosts a user db and web services to access that user db.
That way you can use the same DB, and perform logins over web services to that system from your front end.
This is also scalable and can grow in complexity with your applications.
I would take the other two answers and combines them to make a private OpenId Provider.
This way you can use the standard OpenId clients for your developments, and possibly even open your applications up for external OpenId providers if you developments need them.
This gives scalability and open standards for other applications within the organisations to use the same provider.
In a general way I would develop tables that would be Master Data, they will be single version of the truth application wide. Each and every application will access the same "clients base". In your case it seems that the concept of Master Data can be applied to your applications database.
If the applications are hosted within the company you can use active directory.
You can access active directory from php with the ldap functionality. You can than add users to groups in active directory to give them access to various functionality within the application.

Categories