I'm designing a webhook receiver to work with a third party (over whom I have no control). The third party sends events (HTTPS) on behalf of our users that are represented in our own database. It's difficult to tell from the event payload which user the event corresponds to, but the third party does have a system for specifying a username and password, and sending that information in the webhook event via Basic Auth. So we'd generate username/password, somehow convey that to our users, and ask them to set the username/password in the third party software. Note that this information would only be used for the webhook (which receives somewhat sensitive information, but does not return anything).
I'm wondering how best to handle authentication/authorization here. The third party has very limited retry capability, so my thinking has been:
instead of parsing the event data and saving the complex business entities to the database in the request, enqueue each event onto a message bus and handle in a worker
try to deploy the webhook receiver so that its only dependency is the message queue (SQS in my case).
However, I can't quite figure out how best to handle auth here. The simplest thing would be to just pass the Basic Auth headers over the queue with the event payload, and check them in the worker. Sending in plaintext seems kinda like bad practice, but on the other hand the consequences of leaking this don't really seem serious - there's very little incentive for an attacker to want to send malicious data to our webhook.
Another alternative would be to hash the username/password in the receiver, and save the hashed values in the database, and check they match in the worker. I'm a little reluctant to do this because our users are not very technically comfortable and I'd prefer to be able to read them out the password over the phone.
Would appreciate any advice here!
Related
I have developed an app for Android/iOS which calculates a value based on the users input. If an event occurs, this calculated value will be sent to my Backend as normal HTTPS payload. My question is now, how can I make sure, that this value is really only calculated by the source code of my app? Is there a way to handle such a problem?
To make it clear: I want to avoid, that somebody is rooting his phone, extract the Auth-Token from the private storage of my app and sends a valid HTTPS-Payload to my Backend with fictitious payload, manually or by manipulating the source code.
From the view of the backend, it's difficult to evaluate the payload based on its values if it is valid or not.
Any suggestions appreciated!
----------EDIT-----------
For the sake of completeness: apart from the answers here, the following are also very interesting:
Where to keep static information securely in Android app?
How to secure an API REST for mobile app? (if sniffing requests gives you the "key")
You can’t trust data coming from the client. Period.
You should consider moving the calculation logic to the server and just sending the raw values needed to perform the calculation. You can easily get sub-second response times sending the data to the server, so the user won’t notice a lag.
If you need offline connectivity, then you’ll need to duplicate the business logic on both the client and the server.
Short of doing everything on the backend, you can't very easily.
I'd recommend some reading around CSRF (Plenty of articles floating around) as that's at least a good mitigation against bots outside of your app domain hitting your backend. The upshot is that your application requests a unique, random, identifier from your backend (which ideally would be tied to the user's auth token) before submitting any data. This data is then submitted with your app's data to perform the calculation on the backend. The backend would then check this against the random identifier it sent for that user earlier and if it doesn't match, then reject it with a 400 (Bad Request), or 404 if you're paranoid about information leakage.
I have a couple of questions about the OneSignal notification service. I have been reading the documentation and there are couple of things that bother me security-wise or I'm missing something.
As I understand the process Javascript client uses the Web Push SDK to communicate with the OneSignal API. To instantiate the communication it needs appId parameter, which is available to client.
After that the client can call getExternalId, getEmail, getTags methods to potentially gather user sensitive data. Once in possession of that data on some other device methods setExternalId and setTags can be called with gathered data to impersonate other user and receive notifications directed to them (at least those that get routed using the set parameters).
Does OneSignal presume that device (endpoint) is not compromised?
OneSignal doesnt see setExternalId misuse as a security concern, as notifications shouldn't include sensitive information, as stated in their webpush SDK github.
Only recommendations they do about external_id are its uniqueness, and complexity.
Clients can only call getTags, getEmail, getExternalId, and other methods if they know the subscriber's OneSignal player_id. Since the player_id is only known by the client, it is not possible to impersonate the user or to get this data.
Even so, OneSignal recommends against storing sensitive data in tags or other fields.
I'm making an angular app that has users log in, make progress, then they are awarded levels/experience points. I'm using a nodejs/express API and I want to be able to make a call from my app to award them exp. I'm using a JWT and server signing with a private key to auth requests, but realized that a user could just pull their token and give themselves experience. My question would be is there anyway to protect my route from that or is that a fundamental flaw in design?
I don't believe this is something you can do specifically with JWT. As commenters have already said, JWT just provides access rights for the given token. As you say yourself, it would be simple enough to just read the traffic and send their own requests to jack up their exp.
While your basic authentication/authorisation mechanism can't solve this, you can handle it in some other fashion within, for example, the request payload itself.
You could encrypt and/or sign your payloads - given that the app would need to know or receive key(s) to use, it's possible that with enough investigation that this is eventually found and duplicated as well. But it's another step someone would have to go through and replicate.
You could employ additional checks and measures - have your requests for [exp increase] be a two-step process; the server responds to the initial request with some minor task to be solved that is then attached to the follow-up request. Assuming the task is done properly, you can be reasonably sure that it came from your app as your app knows how to solve the problems issued (or someone with a serious lack of hobbies outside of deconstructing your entire application).
You could limit the amount of exp that should be reasonably achievable by your users. If you know that people should, at most, be able to gain xyz exp per minute/hour/day/etc, then by monitoring exp growth, you can flag and/or block additional gains past this point.
I am building some kind of social app with the concept of 'friends' where friends can do actions regarding one or more of their friends,
I would rather not ask the DB if the friendship does exist every time someone sends any kind of request for an action.
An idea I came up with is after a friendship is approved a digital signature will be sent to each user which can be checked in the server for each request which should cost less than asking the db.
Then I can maybe change the async key everyday or so and force the user to ask for a new digital signature in which case I do approach the db to test friendship (it's good for security but also a must if users want to cancel friendships).
What I ask is if this is a terrible idea? Maybe I'm not seeing something. Or just any link to any information about these kind of scenarios would be great.
The idea of handing out a digital signature can be done, though I am not sure if it would actually be any faster then querying the database, seeing as databases are meant to be incredibly fast.
Lets move on with the idea that it is indeed a good idea. You would need a token of sorts that has the information about who is your friends and it has to have been validated by the server. This, to me, seems like something you could use a JSON Webtoken (JWT) for.
Here is the basics on JWTs.
JWTs have three parts to them: Header, payload and signature. The header defines how long the token will be valid for and the payload can contain the list of friends (or IDs of friends). The signature is a hash of the entire thing, signed with the private key of the server, thus verifying that the server has approved this token as valid until time X. The entire thing is encoded before sending.
You would then send the JWT in a HTTP header of some sort, probably the Authorization header. The server could then quickly decode the JWT (there are libraries for this in a lot of languages, JWTs are a pretty good standard) and thus not need to query the database. The size of the JWT does need to be send though, and thus I am not sure you will actually gain any speed from this.
I have a SOA which makes heavy use of nonces (i.e, one-time one-use security tokens).
My app takes a nonce from a client, verifies it, then sends a new nonce back to said client as part of every reply. Also included in each reply are the results of business logic operations that executed right after the nonce was authenticated.
The nonce verification and generation are operationally coupled with the business logic, since both occur in response to every client request. However I don't want the two to be coupled in code. What's the right way to partition them in accordance with SOA principles? Is it too much to break the security and business logic into two separate services, with one calling the other as part of each reply to each client request?
Yes it makes sense to separate them. But I don't think they should have awareness of each other at all (Call each other directly).
I'll dive into a specific example and technology of how something similar is implemented.
In the web frame work Struts2 all incoming requests pass through a stack of operations(called interceptors) before arriving at a user defined object (called an action). The action then will access the business tier.
When submitting a web form there is the issue of double submission. So one way to protect against this is with a token that is sent along with the form submission. So we need to create a unique token place it as a hidden field, and then when we receive the request only process it if the token is good. This prevent users from doing something like accidentally buying something more than once.
In Struts2 there is a special server side token tag which creates the hidden field for us. So there is something that needs to be done for each form. The token interceptor if active will enforce that this value always exists and is good when receiving the form and will redirect responses that do not somewhere else.
The idea of implementing a nonces interceptor/filter that checks that the incoming nonce value is good and for responses adds the correct nonces value to the response should be completely independent of the business logic.
The example here is with html forms but adding an interceptor(or whatever you call "that which handles cross cutting concerns at the request/response level" for your appropriate technology) which adds such a value to json or xml messages should be pretty easy and likely produce the most elegant result.
The following is a link to struts2 interceptor reference (it might clarify the idea better):
http://struts.apache.org/2.2.1.1/docs/interceptors.html
The following two links are both interceptors which manage tokens:
http://struts.apache.org/2.2.1.1/docs/token-interceptor.html
http://struts.apache.org/2.2.1.1/docs/token-session-interceptor.html
I expect only the first few paragraphs of each link will be useful but something like it for your technology should be nice.
I think what you outlined above would be in keeping with SOA principles. You're keeping two distinct sets of operations separated - once service has the business logic, the other has the security logic.
This would be especially true if you have (or the potential of having) other services that would rely on nonces.