Is it OK to trust all IP addresses?

Hi,

I have an iOS app which communicates with a web app; both are made from me. The iOS app is meant to be used by a few persons (less than 10) so I don’t need to have giant security checks (there’s no user name nor password, merely an identifier to differentiate the persons).

My initial thought was to restrict by IP addresses, in order to prevent hackers from manipulating my web apps (e.g. by figuring out the URL scheme and sending commands). I tried so, but since users are supposed to access the iOS app by phone, the GSM address isn’t fixed and I can’t make a white list (unless I figure out all addresses that are valid in my country, but I doubt).
So I’m thinking of simply not checking the IP address and assume the URL scheme can’t be discovered by hackers (HTTPS should not disclose such data, right?); the fact that an identifier is needed (the server refuses to handle the request otherwise) makes me guessing it’s enough, but is it? The identifier is passed as a parameter in the URL.

Advices welcome.

Yeah, Don’t do that. Hackers will always find your server using up address scans. And then scan for responses on ports.

2 Likes

Thanks.
What alternative would you recommend, keeping in mind that it’s for friends, and I’d like to avoid hassling them with complex log-in methods? (actually, they just enter the identifier at first use and won’t have to remember this later).

If you block IP ranges, the hacker will try through various proxy servers in various countries to see if they come through.
And users are disappointed if they can’t use the app while on vacation.

it may be good to have something to prevent someone to capture the request and replay it.

Good points.
I have to say, networking security isn’t my cup of tea. I have notions learnt here and there, but not close to get an idea.

What does the app do? If it handles data that is even remotely sensitive, your friends will appreciate the fact that you require some authentication, no matter how minimal.

2 Likes

Well, it’s just a checklist (to-do list). Nothing confidential. Knowing my friends, several don’t want to be bothered by authentication.
Thinking deeper, I realise I’m more concerned about hackers possibly corrupting (e.g. taking control of) my server/app rather than confidentiality.
Thanks.

Your app could save the credentials on the device so they would only have to enter them once.

I just can’t see a way around authentication if you are at all concerned with security.

2 Likes

Yes, I already do this. But the credentials must be sent to the server to be validated; it’s where I’m fearing a hacker could monitor the connection, see the URL and reuse it later (even if I encrypt the credentials, the hacker can just use the encrypted string).

Authentication is fine; I’m just not sure if accepting all IP addresses isn’t a big breach (I guess).
Thank you.

You’ve got this all turned around in your head. A basic, secure channel system would look like this:

Connection between client and host is established over a secure channel such as HTTPS. Nothing inside a HTTPS connection can be observed by a hacker – the URL is encrypted, as is all GET and POST data.

The client authenticates with the server. If the authentication fails, no further communication is permitted.

If authentication succeeds, the server issues a token to the client that it can reuse for further communications to identify itself to the server. HTTP is a stateless protocol, which means that the HTTP server doesn’t have any way to keep track of clients - that is handled one step higher on the stack (in this case, your client and server software). The token is usually a random A-Z0-9 string of arbitrary length that is not derived from the username or password.

The client makes more requests, each one including the authentication token. Because all requests are made via HTTPS, the tokens can’t be observed by any other actor. The token helps the server identify the client and maintain any necessary state.

When the client is done, it “returns” the token to the server by making a final request to the server which logs it off and destroys the token. This prevents token reuse.

There are more sophisticated ways of doing this, but for your average client-server situation, this will be sufficient.

3 Likes

Just a minor correction here, it only looks like a random string of alphanumeric characters, but it should not be. Tokens can a wide variety of things, most often a random string of bytes generated from a CSPRNG, or could be a UUID, or maybe a JavaScript web token. The random bytes need to be encoded somehow, which is usually Base64, which uses the whole alphanumeric range plus a few other characters.

My point in all this is that just picking random characters with System.Random isn’t actually considered secure. System.Random is predictable. If you manage to know the seed, you know the order of numbers being chosen. (Side note, this is how replays in games like Super Smash Brothers work. They store the RNG seed and the player inputs, then just rerun the match.)

I’m pretty confident Eric didn’t intend to imply that just picking random characters is sufficient. I just wanted to add some clarification so that nobody gets the wrong idea.

1 Like

Thanks. Yes, I should have said “apparently random” or “non-human-readable”. :grin: What I was trying to get at is that the token is not a sequential number, or a username, or a recognizable phrase of any kind - it has meaning only in that it uniquely identifies the authenticated client. For security purposes, it should not relate to any other data.

That is a reassuring statement.

Currently, I’m passing the authentication data with each request rather than creating a token. This allows the possibility for the app to be used on demand (and not used for a long time as well; there’s no log off feature). Bad idea?
(in other words, the token is already the authentication data)

This is interesting. What could be done by hackers if it’s related?
(given the simplicity of this app, I’d like to make the “minimum” security checks).

Well, if they realized that the token was a mangled version of the user’s password, for example, they might try to find a way to unmangle it and get the password. Or if it is a sequential number, they could simply try using the next number. That’s why it should be truly random data, as noted in the other comment.

The token would be encrypted by the HTTPS protocol, wouldn’t it?

You also want to mindful of replay attacks. An attacker could intercept legitimate requests, encrypted or not, and replay them by sending them to your server. It’s best if you use nonces or session tokens and timestamps to ensure that the requests are unique.

Yes, that’s true… but there are sophisticated hacks that could still occur. The user’s device itself might be compromised, for example.

It’s just not a good idea to repeatedly transmit credentials - each time you do, you increase the opportunity for bad things to happen. I agree that HTTPS provides some protection here, and maybe for your simple scenario it might be sufficient. I just don’t want this to seem like a good idea for other people who might be looking for advice on the subject.

Good argument. For my specific application, I don’t think it matters a lot, though. I’m not concerned about data manipulation (these are to-do or shopping lists and sending the data a second time would just fail because the data has already changed; the server just issues an HTTP status code).

What I was especially worried about is hackers taking control of the server by finding software breaches. But various answers have recently convinced me it’s unlikely.

Yet another good point.

The problem I’m seeing with using token instead of credentials for every request is that tokens are meant to expire at a certain time, so I’d need to implement some kind of log out mechanism. That’s against what I’d like to implement in this case (some targeted users among the few to use it just hate remembering and entering passwords, and I know they would like my app less in such case).

That’s a key point. I’m not making an app for a big audience; merely brothers & sisters (and possibly a few more). I don’t expect to see big security issues in that context, but that’s an edge case.

Thanks for your answers.

Implement password storage in the Keychain. They can enter their credentials once and forget about it.

1 Like