how to encrypt the request headers in REST calls without using SSL - rest

I am using Bearer Token Authentication. when i send in my credentials in the form. I can easily grab my password through Fiddler. I can also see the token along with its claim in fiddler.
I can copy this token and use fiddler to make API calls.
This seems to be a huge loophole in my system. How can i prevent a hacker from not using the token and not seeing the credentials in fiddler.
Is there a way to encrypt the request headers in API calls. Is there a way to encrypt the response headers in API ?
Is it possible to do this without using SSL ?
Please help me understand this

It is possible to do without SSL, but you will have to pretty much replicate most of the SSL, that is trust, key exchange, encryption.
Technically can be done using private/public key as well, but this really complicates the issue as well.
so, use SSL

RFC 6749:
The authorization server MUST require the use of TLS as described in Section 1.6 when sending requests using password authentication.

Related

API Token Authentication - Security issue

For token based authentication for any service, first we have to send username/password in the request. Doesn't this cause security issue? How can we overcome this security issue of passing username/password?
The initial request which contains the username and password is no more or less secure than subsequent requests which would instead be bearing some sort of token. The solution to this problem, really to sending any type of information across the network, is to use two way SSL/HTTPS. With HTTPS, information being sent gets encrypted on the client machine, and then (in theory) only the server would be able to read what is contained. So, sending the plain text username and password might seem insecure, but if using HTTPS, then in fact it is secure.

do I have to use https when relying on cookies or tokens

I am going through various javascript/auth tutorials -- I understand salting password and storing it in the DB, using Passport, generating the token and storing it in the request header, etc. Overall, I got the whole flow going -- for signing up and signing in. But I am not sure why the following is not being mentioned in any of the tutorials: if I can view http traffic on the network, cant I steal someone else's token and "impersonate" that user? I wont be able to decrypt the token since I dont have the "secret phrase" used to generate the token, but I can surely take it "as is"?
So, do tokens and https go together? Is my understanding about user impersonation via a token correct? Thank you
As somebody who intercepts a JWT you ...
... are able to "decrypt" the JWT since it is not encrypted. It is only Base 64 encoded,
... can validate the signature if an asymmetric scheme is used and you know the public key,
... can use the JWT to impersonate the user,
... can not change the claims made in the JWT since then the signature would no longer be valid which would be noticed by the server.
So, yes, use HTTPS.
Also on the server side don't rely on the JWT alone. Check that ...
... it is not on the blacklist of revoked tokens (you have such a list, don't you?),
... the request is coming from a network address that is a claim in the JWT (you include the network address for which the JWT was issued, don't you?.

PHP REST API get authorization data

I'm writing REST API in PHP and recently I faced with authorization problem. I read a lot about basic authorization, about using private and public keys to create request signature. It is said that using request signature is more secure. But then I have a question:
-How should user will pass public key and generated signature?
I'm thinking about several options:
1) Create custom http header like X-Key, X-Signature
2) Use authorization header with custom scheme, like
AUTHORIZATION: SIGNATURE key='123' signature='abc'
3) Send this values as parameters. But I don't know if it acceptable for methods DELETE and PUT
What would you advice?
p.s. I don't want to implement oAuth
What are the desired properties of authentication scheme? Is this a publicly accessible or an intranet service? Are user accounts linked to something outside of scope of your API (linked 3rd party accounts etc). How are you going to distribute user credentials?
I would probably stick with plain old basic authorization, but encrypt everything at the transport level, making use of HTTPS mandatory. Rolling out your own cryptographic scheme is generally not a good idea. It's easier to fall victim to timing or replay attack than it seems. If you insist on client using a key pair for authentication, you can use HTTPS client certificates (though this is not widely used and maybe somewhat cumbersome solution).
There are a few security concerns about plain-text authentication over TLS. First, if someone implements MITM with forged certificate using either well known CA (maybe a government agency) or CA the client is forced to trust (big evil corporate proxy), they will get credentials. But you can't protect the client from its own environment anyway. Second, basic authentication can be prone to CSRF because browser knows how to do it and can remember credentials if you presented challenge and user filled the form. That's not a big problem if you adhere to REST principles and never allow state-changing GET requests. Also, if you are using JSON, never return arrays.

.NET Web API. Authenticate clients with username and password without using Basic Authentication

I need your help please.
I developed some REST services with .NET Web API.
These sevices must authenticate the clients with username and password.
The solution I find out in Internet is "Basic Authentication".
The BIG problem is that I can't use SSL for secure the comunication. I don't have HTTPS.
Using basic authentication without SSL is not a good solution.
I'm not able searching on Internet to find out a solution that can authenticate the clients over http using username and password.
Please can you help me?
Summarizing I need to authenticate the user in a Web.API using username and password. I can't use SSL. My comunication is on HTTP.
Thanks!!!
You could use the ASP.NET membership provider:
http://msdn.microsoft.com/en-us/library/yh26yfzy(v=vs.100).aspx
Basically - you can't do that.
Sure there are scheme that don't transfer credentials in clear text over the wire - but it is not only about the credentials. All the data is going over the wire in the clear as well, you have no authentication of the server, no confidentiality, no integrity protection, no replay protection etc…
If you don't care about all these features - why bother with (secure) authentication at all?
The only other common approach for username + password authentication I am aware of is digest access authentication. There is a blog here showing an example for WebApi.
This will give you some protection without SSL as it uses hashes; however, I wouldn't really advocate it until all the disadvantages of this approach a fully read and understood.
Without SSL, basic is not secure but digest is also not secure due to man-on-the-middle attacks. I would recommend you to use some public/private key based approaches like HMAC or encrypting as paul said with hash + salt.

Security of REST authentication schemes

Background:
I'm designing the authentication scheme for a REST web service. This doesn't "really" need to be secure (it's more of a personal project) but I want to make it as secure as possible as an exercise/learning experience. I don't want to use SSL since I don't want the hassle and, mostly, the expense of setting it up.
These SO questions were especially useful to get me started:
RESTful Authentication
Best Practices for securing a REST API / web service
Examples of the best SOAP/REST/RPC web APIs? And why do you like them? And what’s wrong with them?
I'm thinking of using a simplified version of Amazon S3's authentication (I like OAuth but it seems too complicated for my needs). I'm adding a randomly generated nonce, supplied by the server, to the request, to prevent replay attacks.
To get to the question:
Both S3 and OAuth rely on signing the request URL along with a few selected headers. Neither of them sign the request body for POST or PUT requests. Isn't this vulnerable to a man-in-the-middle attack, which keeps the url and headers and replaces the request body with any data the attacker wants?
It seems like I can guard against this by including a hash of the request body in the string that gets signed. Is this secure?
A previous answer only mentioned SSL in the context of data transfer and didn't actually cover authentication.
You're really asking about securely authenticating REST API clients. Unless you're using TLS client authentication, SSL alone is NOT a viable authentication mechanism for a REST API. SSL without client authc only authenticates the server, which is irrelevant for most REST APIs because you really want to authenticate the client.
If you don't use TLS client authentication, you'll need to use something like a digest-based authentication scheme (like Amazon Web Service's custom scheme) or OAuth 1.0a or even HTTP Basic authentication (but over SSL only).
These schemes authenticate that the request was sent by someone expected. TLS (SSL) (without client authentication) ensures that the data sent over the wire remains untampered. They are separate - but complementary - concerns.
For those interested, I've expanded on an SO question about HTTP Authentication Schemes and how they work.
REST means working with the standards of the web, and the standard for "secure" transfer on the web is SSL. Anything else is going to be kind of funky and require extra deployment effort for clients, which will have to have encryption libraries available.
Once you commit to SSL, there's really nothing fancy required for authentication in principle. You can again go with web standards and use HTTP Basic auth (username and secret token sent along with each request) as it's much simpler than an elaborate signing protocol, and still effective in the context of a secure connection. You just need to be sure the password never goes over plain text; so if the password is ever received over a plain text connection, you might even disable the password and mail the developer. You should also ensure the credentials aren't logged anywhere upon receipt, just as you wouldn't log a regular password.
HTTP Digest is a safer approach as it prevents the secret token being passed along; instead, it's a hash the server can verify on the other end. Though it may be overkill for less sensitive applications if you've taken the precautions mentioned above. After all, the user's password is already transmitted in plain-text when they log in (unless you're doing some fancy JavaScript encryption in the browser), and likewise their cookies on each request.
Note that with APIs, it's better for the client to be passing tokens - randomly generated strings - instead of the password the developer logs into the website with. So the developer should be able to log into your site and generate new tokens that can be used for API verification.
The main reason to use a token is that it can be replaced if it's compromised, whereas if the password is compromised, the owner could log into the developer's account and do anything they want with it. A further advantage of tokens is you can issue multiple tokens to the same developers. Perhaps because they have multiple apps or because they want tokens with different access levels.
(Updated to cover implications of making the connection SSL-only.)
Or you could use the known solution to this problem and use SSL. Self-signed certs are free and its a personal project right?
If you require the hash of the body as one of the parameters in the URL and that URL is signed via a private key, then a man-in-the-middle attack would only be able to replace the body with content that would generate the same hash. Easy to do with MD5 hash values now at least and when SHA-1 is broken, well, you get the picture.
To secure the body from tampering, you would need to require a signature of the body, which a man-in-the-middle attack would be less likely to be able to break since they wouldn't know the private key that generates the signature.
In fact, the original S3 auth does allow for the content to be signed, albeit with a weak MD5 signature. You can simply enforce their optional practice of including a Content-MD5 header in the HMAC (string to be signed).
http://s3.amazonaws.com/doc/s3-developer-guide/RESTAuthentication.html
Their new v4 authentication scheme is more secure.
http://docs.aws.amazon.com/general/latest/gr/signature-version-4.html
Remember that your suggestions makes it difficult for clients to communicate with the server. They need to understand your innovative solution and encrypt the data accordingly, this model is not so good for public API (unless you are amazon\yahoo\google..).
Anyways, if you must encrypt the body content I would suggest you to check out existing standards and solutions like:
XML encryption (W3C standard)
XML Security