1

We are working on a redirecting page for our mobile apps.

Users would go to a page like:

https://mobileredirect.our-app.com?target=https://clientdomain.com/some_resource

Mobile apps on iOS and Adroid can intercept the "mobileredirect.our-app.com" domain, when installed. If not installed, the browser will open, and redirect the browser to the client domain.

This is contains an obvious problem. Anyone can put any domain in the scheme and this becomes an attack vector. I would like to be able to verify if the URL is actually coming from a trusted source. We need to do it this way, as we don't control which domains could use our mobile app.

Ideally I'd like to do this in the browser, without the need for a server.

I was thinking of using a library like simple-crypt, using the Asymmetric operation. Trusted servers would have the private key, they would encrypt the URL end it would end up like this:

https://mobileredirect.our-app.com?target=ENCRYPTED_URL.

The clients (mobile apps, and the website) would contain the public key to decrypt the URL. This does mean that the public key will be visible to everyone.

Now my question: Is this a good idea? How can this be broken? Is it overkill? Are there easier ways (e.g.: use some type of checksum algorithm)?

This is a repost from Stack Overflow.

8
  • You cannot decrypt with a public key. You can however, check the signature of a file with the public key which has been signed by a private key. So server signs the URL with private key and client checks signature with public. Commented Jul 4, 2017 at 8:44
  • put a domain whitelist on the page served at mobileredirect.our-app.com that conditionally redirects or displays an error. you can do that in js, or with a server/db to edit the list instead of hard-coding scripts. there's no need for encryption, just validate the input on the client (weird, right?)
    – dandavis
    Commented Jul 4, 2017 at 8:46
  • 3
    SilverlightFox Actually you can decrypt with public key if the data was encrypted with the private one. One if the inverse of the other
    – Mr. E
    Commented Jul 4, 2017 at 16:13
  • Why do you need this redirect page?
    – Noir
    Commented Jul 4, 2017 at 22:04
  • 1
    @dandavis A whitelist is not possible, as I said, we do not control which domains are in use. Commented Jul 5, 2017 at 12:44

2 Answers 2

1

It's good that you do want to keep the private key private and only hand it to trusted servers, not to the clients itself.

While you propose a scheme that will (probably) be (reasonably) safe, I have a slightly different approach for you to consider which is less of an abuse of asymmetric cryptography and allows for better transparency as to what's happening to the user receiving one of those links:

If you add a path element to the URL that contains the signed hash of the url to send the user to, like this:

http://a.tgt/?target=sign(privKey, h(https://b.tgt/bla))|https://b.tgt/bla

where sign() signs a message with a private key and h() hashes a string, you have

  • a better chance of detecting tampering,
  • solid authentication and
  • do not hide the actual forward target from the user.

By concatenation of the signature and the target URL as pointed out in the comments you reduce the chance of the payload being processed without processing the signature as well.

Please also note that encryption with the private key is usually called signing :)

2
  • Funny, I implemented almost exactly this just yesterday. Although, in my implementation, the sig is part of target= separated by a separator rather than as separate sig= field. This has the advantage of forcing all existing and future code to pass the redirect url to the unsign-and-validate method, so you can't forget to validate the url before using it.
    – Lie Ryan
    Commented Nov 3, 2017 at 12:10
  • @LieRyan Good Point! I will incorportate that into my answer:)
    – Tobi Nary
    Commented Nov 3, 2017 at 12:45
0

Looks like you've faced with simple Open Redirect, I cannot point you the implementation itself, but it seems your are looking for Content Security Policy (CSP), implementation depends on the platform you are using. In a few words this technology allows (or not) resources which are used by your application.

From penetration tester perspective it is an headache while facing with CSP. Also, you should look basic recommendation for your case here OWASP Unvalidated Redirects and Forwards Cheat Sheet

1
  • This is exactly what I'm trying to do "If user input can’t be avoided, ensure that the supplied value is valid". In my case I can't validate based on the target domain, as we do not control these. Further more, the links should work from inside emails; which means that a "GET" request is unavoidable. I know I can implement something with a shared secret, and a server based redirect, but that's what i'm trying to avoid. Commented Jul 6, 2017 at 12:03

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .