How technique can i use in making my server accept request from a game i built in unity? - api

I am creating a unity game where users can post their high scores after a successful match, my problem is that some users can post directly to the api, without playing a match. How do i curb such an issue. I have read some articles about using native mobile encryption to help. but i do not know how this can be applied to Unity since it is a layer above native. what techniques can i use ?

Encryption will only solve a part of the problem, when users send fake requests to your API. But if I were you, I would perform server-side validation based on the parameters sent by the client.
How: Send one request to the server when a match starts, along with necessary details such as the user name. When the match is finished, send another request to the server, check the score against some heuristics based on how long the match took, and whether the score makes sense given the user's specific setup (levels and equipment, etc.) if you keep that information on the server.
Why: There's no reliable way to control what the user does on his client: he can change the values in memory, send forged requests, and so on. If the user meddles with the memory to give himself "100x damage dealt", your client may not know, and will dutifully record the (now tampered) score and send it to the web API. Encryption will not help you here since the request is just like the real thing except it contained a fake score to start with.

Related

Finding out authentication method of web API (websocket) to login with my own script (I have the login data)

My parents own a wallbox for charging a electric car. The wallbox is controllable with an app which uses an authenticated API. I already did a MITM attack to get that traffic. I also have the login data, as it is the wallbox of my parents and they agreed that I do this. (If you are interested: I try to automate that the car is always charging when there is enough power from the photovoltaic but at the same time the car should never run low if there is not enough sun.)
I want to write a small Python script which controls the wallbox, but the only problem is, that I don‘t know how the authentication works.
Is there any way to find that out, without decompiling the app (which I found hard because it apparently uses React Native with the Hermes engine from Facebook which can‘t be decompiled as nicely as other Android apps)?
Is it realistic to find the used authentication method by just looking at the example I show below?
Or is the only way to understand the authentication with the decompiled app? I pasted an example of what I sniffed below.
If there is an easy solution to my problem, I am happy to take that, but if you say that I should look more into these and that, then I am also good with that, as I am kinda stuck at the moment.
Thank you very much!
Two messages from the API
They come automatically after opening the websocket connection.
{
"type":"hello",
"message":"Hello app",
"serial":"3215XXXX",
"devicetype":"deviceName",
"manufacturer":"companyName",
"protocol":2
}
The first token stays the same for multiple hours, even if you make multiple requests to the API.
{
"type":"authRequired",
"token1":"0dtOJ1LkCrMgaz5ri8MZmgHBcXXXXXXX",
"token2":"Ij10ETYSo2GJSVMJlDNzMGW9TXXXXXXX"
}
From the app
{
"type":"auth",
"token3":"b4eb9e8baae62429c577216aaXXXXXXX",
"hash":"cbc3d99391db59e59174ddb01073157581afb2ad1e392433c9107477eXXXXXXX"
}
Answer from the API
{
"type":"authSuccess",
"message":"Successfully authenticated"
}
It's not super-realistic to assess the auth method from that data, however, you can get some idea.
There could be multiple reasons why the server provides two tokens (rather than just one), but I'm going to give a "best estimation" example scenario. The auth method is possibly something fairly similar to this. It's possible that one of the two tokens is authenticating the server to the client.
One of the two tokens the server provides is likely some sort of challenge for the client: it may be a hash of current time or day, or a hash of a client-specific identifier, or just some random data used to prevent replay attacks.
The client response to the server is probably some hashed or encrypted combination of one of the tokens from the server and the client secret (your password, or username:password, or username:password:productID or something like that.)
The hash may be a protection against replay attacks by hashing the current time along with the client secret info, or possibly an authentication sequence number along with client secret info.
So as you can probably tell there are many, many possibilities here. It's possible the whole protocol is custom designed by the charging station manufacturer.
You might try sniffing some data again, and within the first token timeframe try to replay what your client sent. It will most likely not auth you, but It's possible you'll be presented with some error information that is useful and can give you more clues about what's going on.
Otherwise, the disassembler is probably going to be the way to go, and may be tedious, but should give you a much clearer picture of the correct auth protocol.

How to properly secure post requests with Django RF apis?

I am currently learning to make DRF APIs for something I am working on. I was wondering how exactly I would secure the API POST requests I send via the client side?
For example, let's say I have a log in form where the user can enter their information, this information needs to be send to (or POST-ed to) my API for verification. I do not want just anyone sending requests to the server and so, I would want to use an API key but since this is being done on a website, anyone could see the API key if they wanted to, and then exploit the server by sending a ton of requests.
My current idea is to use serializes in DRF to check if the API POST request has everything it needs but I am fairly certain this can be easily found by checking what sort of JSON my code sends to the server, so how exactly do I go about securing this such that I can send the information to the bare domain (like http://127.0.0.1:8000) and then have code which can accept that information?
I apologize for any confusion, if it is confusing. Let me know if you need any clarification.
If you are creating API any one can send request to server. same goes for website and webpage. Their is no way you can avoid this. But their are ways to handle possible misuse.
like using CAPTCHA for login form which can be filled by one on the web. though wrong CAPTCHA text can be send by anyone you must check it on server for their correctness. or use google reCAPTCHA like services for outsourcing this task.
API key should be given after login NOT before login. and if it is given after successful login then the key is obtained by legitimate user which can obviously do whatever he is allowed to do on website. their should not be problem in that.
further explanation to the question will lead to details of denial-of-service i.e DOS attack. you should consult expert on that field if your application requires to handle DOS attack.

API security: Real date of the user

Situation:
I'm creating inner API for my website (Node.js + Express). But I completely don't know how to secure it.
I have payments in my application, and I need to know when user makes it. I use XHR requests for transferring data between server and frontend.
Questions:
Is it secure to transfer user's time to a server (can I trust this information?). If no, how can I get it securely? I thought about transferring user's location, and then with help of mement.js get his time, but it's also not secure if a hacker can replace it with his data.
Can hacker make XHR request from developer's console to my server? If yes, how can I get his real time?
I'll be happy if you answer at least some of my questions.
First of all, I would suggest not writing the code yourself if you are not confident enough about it. Storing payment details is a big responsibility, and can get you in legal trouble if anything gets compromised. I would suggest using services like Paypal to handle the payment.
That said, I am going to answer your question:
You cannot trust ANY information you receive from the user. The time and location can be spoofed/altered very easily.
Yes, it is possible to make (modify) a request from the console (maybe some add-ons and technical knowledge will be required, but it is doable). It is not possible to know the real time of the user. It is only possible to know the session timeout of the server, and estimate the time of the user, relative to the time of the server, based on that. It is also possible to know the IP of the user and estimate the time-zone, but using a VPN or Tor, it is trivial for a user to alter it.
EDIT: Using Paypal would increase the security, compared to writing it yourself. Here is the API reference: https://developer.paypal.com/
EDIT 2: Here is a brief explanation of why you should never trust user input: https://www.enisa.europa.eu/publications/info-notes/the-dangers-of-trusting-user-input

API authentication with mobile app (by SMS)

We are currently tasked with implementing a (preferably simple) authentication system for a mobile application communication with a RESTful API. The backend has user-specific data, identified by the user's phone number. I am trying to understand more about security in general, the different methods there are and why they work the way they work.
I thought of a simple authentication system:
The client sends a verification request to the api which includes their phone number and a generated guid.
The server sends an SMS message to the phone number with a verification code.
The client verifies their device by sending their unique guid, phone number and verification code.
The server responds with some kind of access token which the client can use for further requests.
I have the following questions:
Are there any major flaws in this approach?
Assuming we use HTTPS, is it secure enough to send the data otherwise unencrypted?
Can access tokens be stored on mobile devices safely so that only our app can read them?
Anything else we haven't thought of?
We already figured that when the mobile phone is stolen or otherwise compromised, the data is no longer secure, but that is a risk that is hard to overcome. Access tokens could be valid temporarily to minimize this risk.
I am assuming this approach is way to simple and there is a huge flaw somewhere :) Can you enlighten me?
There is a flaw. The system is susceptible to a brute-force attack.
Suppose I am an attacker. I will generate a guid for myself and send it along with some arbitrary phone number.
Next, I will just bruteforce my way through the possible SMS codes - if it's 6 digits, there's only 10^6 combinations. The bruteforce will be a matter of seconds - and then I will gain acess to the data of the person having this phone.
Also, as was pointed out in the comment by Filou, one can force you to send you arbitrary number of SMS, effectively making you sustain a financial loss at no cost.
There's also no valid defense from this attack:
If there is limited amount (N) of attempts for a given UID, I will
re-generate the guid every N attempts.
If there's a limit of requests per phone per amount of time, I can execute a DoS/DDoS attack by flooding every possible number with fake requests - hence, noone will be able to perform any requests.
A login/password or certificate authenication is mandatory before an SMS. Also:
Never use things like GUID in cryptography/security protocols. GUIDs are deterministic (i.e., knowing one value, you can predict future ones). Use crypto-libraries built-in functions for generating random streams
Never try to design security protocols yourself. Never. There's an awful lot of caveats even SSL 1.0 creators fell to - and they were sharp guys, mind you. Better copy common and proven schemes (Google's auth is a great example).
The approach you mentioned will works fine. Client will initiate a request with the phone number and a random id, server returns a verification token to the device. The token is one time use only with a set expiry. Then client will send the phone number, the random token used before and the validation token, which the server verifies. If valid, server sends a session token (or auth token) or similar which can be used for authentication. The session token can have a time out set from the server.
You did not mention if it's a web app or not. If it's a web app, you can set a https only session cookie from the server. Otherwise, you can store it locally in the app's local store. In usual case, apps cannot read private data belonging to other apps.
All communications must take place using HTTPS. Otherwise the whole scheme can get compromised via sniffing for traffic, because in the end you are using the auth token.

AppEngine Channel API - Best way to check if a channel is still open (server side)

I have built a social network/dating type application on the AppEngine and am currently in the process of adding a chat built on top of the Channel API. However, the problem that I have is that users may reload or navigate to new pages while the chat is going on (as they can in Facebook). This means that the server doesn't easily know if it should generate a new channel ID token for a given client, or if a given client has already been assigned a channel token.
It would be extremely useful if there were a way to check (server side) if a particular client already has a channel open. For example, if I assign a client "Jack" a channel ID of "Jack-Jan-21-2010", then I would like to be able to check on the server side if there is already a channel open associated with the ID "Jack-Jan-21-2010". This can be (sort of) tracked on the client side by watching for an onerror() and onclose() callback, but I can't see anything server-side that allows me to just check if a channel associated with a given ID is already open.
Does anyone know an intelligent way to check (server side) if a channel has already been opened, while using the AppEngine Channel API?
Part 1: Solving your problem
See Part 2 below if you really need to track client connections, but I'm not sure from your question if what you're asking for will solve your problem.
Let me see if I can echo your problem back: you're writing a chat app, but it's for a site which isn't fully AJAX (in the way that, say, gmail is); the site contains page navigation where you may need to re-set up your channel after the user clicks on a link to another page. When the user navigates, the new page is rendered, and you want to avoid getting a new token at that point; you want to reuse the existing token and channel with the same client-id.
If that's correct, I have two alternate solutions, one easy but with not-great user experience, one trickier but with a much smoother end result.
Preserve the token in a cookie. When you re-render your page, just use the token from the cookie instead of calling channel.create_channel again. When the token expires you'll get an onerror callback just like if the user had stayed on the original page; at this point, call channel.create_channel again. The problem with this is that re-connection can be slow (up to 10 seconds or more in bad cases) because of the nature of Comet connections.
Wrap your entire site that's not chat-related in an iframe. Put your channel creation code and UI in the outer iframe. This way you don't have to re-connect every time the user navigates. This avoids the downtime on navigation. Note that orkut uses this technique, with floating divs, as a small amount of Firebug investigation will reveal.
Part 2: Your feature request
If it turns out I'm misunderstanding and you really do need to track client connections:
There's not a built-in way to check if a client is connected to a channel identified by a client-id now.
However, I am working right now on adding "presence" (in the chat sense) so that your app can register to get a post when a client connects to or disconnects from a channel created with a given client id. You also might be able to "probe" presence, to query whether a given client id is connected or not (still working on the details of this part).
Note that this won't be token-based, but rather client-id based.
I don't have a definite release date for this yet but as I said I'm actively working on it right now.
In the meantime, you could use a heartbeat HTTP request from your client back to your app that says, "hey, I'm still here" every minute or so. You'll need to have some sort of task that runs every, say, 2 minutes and marks any clients that haven't checked in as inactive, and you'll need to store this data someplace.