Sending cookies between servers vs sending headers - node.js

I'm a bit naive about how to send cookie data between servers. I am aware that in the HTTP request you use Set-Cookie.
Right now, I am sending a header between the servers, for authorization purposes, so that one server is authorized with the other. But I am wondering if there is some advantage to using cookies, if cookies act differently than headers in this case. From what I have read, cookies and headers are one and the same for most purposes?
Using two Node.js servers, one being the web server, the other being the API server, is there any reason why sending a cookie vs a regular non-cookie header is better?

The "cookie" represents shared state between the client and the server. As was mentioned, the way to set cookie values, is to use the Set-Cookie header. And the way to communicate values that have already been set is to use the Cookie header.
Cookies are typically associated with web browsers, as tool to track and identify existing users. I've never seen cookies used for server to server communication.
The Authorization header is good for passing encoded or encrypted strings.
So for example you might see:
Authorization: "Basic dXNlcm5hbWU6cGFzc3dvcmQ="
The value in this case is the base64 encoded string of "username:password"
I wouldn't worry too much about what header you use. You can make up your own x-my-awesome-auth-header: Its conventional to prefix a custom header with an "x".
An important thing to consider, is what the header value contains. If you are communicating over plain http make sure you encrypt.
Also consider using open source standards for passing encrypted data such as JWT
Edit: To answer your question, is there any reason why sending a cookie is better? When it comes to server to server communication, its actually much worse to use Cookies, because those servers have to maintain state with other servers. eg. When A talks to B, A has to remember what B said when they talk again. You typically what server to server communication to be stateless, meaning you can throw away data pertaining to authorization and permission after each transaction. Each transaction has to go through the full authorization and permission resolution process. Its much easier to code, and there is no penalty in terms of security as long as your are protected via encryption

Yes, "cookies" is just jargon for the Cookie: HTTP header and corresponding Set-Cookie: header. So they are ultimately the same basic thing. Many APIs use the slightly more semantic Authorization: header, so that would be a good place to start.

Related

Is there a way to make HTTP request headers immutable?

There are various ways the web applications can be attacked using the vectors in HTTP request itself. Attacks like the HTTP response splitting make use of modifying the request headers itself to exploit the vulnerable applications. Apart from input validation and sanitization at the server side, the question came to my mind if one can make the request headers immutable.
Is it possible to make it immutable?
Request headers are sent from the client to the server.
The browser itself constructs an HTTP request to send. A user with control over the client can of course change the HTTP request, including headers to anything that they want.
Therefore, making them immutable is impossible. Remember, as a general rule, anything on the client-side is up for grabs.
You can prevent headers from being altered during transit. That is, while the HTTP request is on the wire from the client to the server. For this, a technology called TLS is used (used to be called SSL, and most of the time it still is). This encrypts and authenticates the connection, making it immutable.
You can see if TLS/SSL is being used because the browser address bar will display HTTPS at the very beginning of the URL.

Standard Token place - header or payload

I want to secure my application using access token while communicating to the server.I am using nginx server which logs all the headers which are present in the request. It is a security threat if we are logging the header. If somebody can access the logs file. They can easily manipulate the data. Then why people use token in header?
In this case can we consider payload as the right choice?
What is the best place(or standard way) to put access token : Header or in payload?
What are the pros and cons of both?
IMHO, it is mainly a matter of taste, and of tools you use for testing ...
If you use elaborated tools, that allows you to set custom headers, header is nice, because it does not clutter the payload. But if you want to be able to test with a simple browser, if is easier to add a request parameter than a header ...
You can even accept both, first looking in the header, and then in payload if you could not find the token in header.

Are security concerns sending a password using a GET request over https valid?

We have webpage which uses the sapui5-framework to build a spa. The communication between the browser and the server uses https. The interaction to log into the page is the following:
The user opens the website by entering https://myserver.com in the browser
A login dialogue with two form fields for unsername and password is shown.
After entering username and password and pressing the login-button
an ajax-request is send using GET to the URL: https://myusername:myPassword#myserver.com/foo/bar/metadata
According to my understanding using GET to send sensitive data is never a good idea. But this answer to HTTPS is the url string secure says the following
HTTPS Establishes an underlying SSL conenction before any HTTP data is
transferred. This ensures that all URL data (with the exception of
hostname, which is used to establish the connection) is carried solely
within this encrypted connection and is protected from
man-in-the-middle attacks in the same way that any HTTPS data is.
An in another answer in the same thread:
These fields [for example form field, query strings] are stripped off
of the URL when creating the routing information in the https packaging
process by the browser and are included in the encrypted data block.
The page data (form, text, and query string) are passed in the
encrypted block after the encryption methods are determined and the
handshake completes.
But it seems that there still might be security concerns using get:
the URL is stored in the logs on the server and in the same thread
leakage through browser history
Is this the case for URLs like?
https://myusername:myPassword#myserver.com/foo/bar/metadata
// or
https://myserver.com/?user=myUsername&pass=MyPasswort
Additional questions on this topic:
Is passsing get variables over ssl secure
Is sending a password in json over https considered secure
How to send securely passwords via GET/POST?
On security.stackexchange are additional informations:
can urls be sniffed when using ssl
ssl with get and post
But in my opinion a few aspects are still not answered
Question
In my opinion the mentioned points are valid objections to not use get. Is the case; is using get for sending passwords a bad idea?
Are these the attack options, are there more?
browser history
server logs (assuming that the url is stored in the logs unencrypted or encrypted)
referer information (if this is really the case)
Which attack options do exist when sending sensitive data (password) over https using get?
Thanks
Sending any kind of sensitive data over GET is dangerous, even if it is HTTPS. These data might end up in log files at the server and will be included in the Referer header in links to or includes from other sides. They will also be saved in the history of the browser so an attacker might try to guess and verify the original contents of the link with an attack against the history.
Apart from that you better ask that kind of questions at security.stackexchange.com.
These two approaches are fundamentally different:
https://myusername:myPassword#myserver.com/foo/bar/metadata
https://myserver.com/?user=myUsername&pass=MyPasswort
myusername:myPassword# is the "User Information" (this form is actually deprecated in the latest URI RFC), whereas ?user=myUsername&pass=MyPasswort is part of the query.
If you look at this example from RFC 3986:
foo://example.com:8042/over/there?name=ferret#nose
\_/ \______________/\_________/ \_________/ \__/
| | | | |
scheme authority path query fragment
| _____________________|__
/ \ / \
urn:example:animal:ferret:nose
myusername:myPassword# is part of the authority. In practice, use HTTP (Basic) authentication headers will generally be used to convey this information. On the server side, headers are generally not logged (and if they are, whether the client entered them into their location bar or via an input dialog would make no difference). In general (although it's implementation dependent), browsers don't store it in the location bar, or at least they remove the password. It appears that Firefox keeps the userinfo in the browser history, while Chrome doesn't (and IE doesn't really support them without workaround)
In contrast, ?user=myUsername&pass=MyPasswort is the query, a much more integral part of the URI, and it is send as the HTTP Request-URI. This will be in the browser's history and the server's logs. This will also be passed in the referrer.
To put it simply, myusername:myPassword# is clearly designed to convey information that is potentially sensitive, and browsers are generally designed to handle this appropriately, whereas browsers can't guess which part of which queries are sensitive and which are not: expect information leakage there.
The referrer information will also generally not leak to third parties, since the Referer header coming from an HTTPS page is normally only sent with other request on HTTPS to the same host. (Of course, if you have used https://myserver.com/?user=myUsername&pass=MyPasswort, this will be in the logs of that same host, but you're not making it much worth since it stays on the same server logs.)
This is specified in the HTTP specification (Section 15.1.3):
Clients SHOULD NOT include a Referer header field in a (non-secure) HTTP request if the referring page was transferred with a secure protocol.
Although it is just a "SHOULD NOT", Internet Explorer, Chrome and Firefox seem to implement it this way. Whether this applies to HTTPS requests from one host to another depends on the browser and its version.
It is now possible to override this behaviour, as described in this question and this draft specification, using a <meta> header, but you wouldn't do that on a sensitive page that uses ?user=myUsername&pass=MyPasswort anyway.
Note that the rest of HTTP specification (Section 15.1.3) is also relevant:
Authors of services which use the HTTP protocol SHOULD NOT use GET based forms for the submission of sensitive data, because this will cause this data to be encoded in the Request-URI. Many existing servers, proxies, and user agents will log the request URI in some place where it might be visible to third parties. Servers can use POST-based form submission instead
Using ?user=myUsername&pass=MyPasswort is exactly like using a GET based form and, while the Referer issue can be contained, the problems regarding logs and history remain.
Let assume that user clicked a button and following request generated by client browser.
https://www.site.com/?username=alice&password=b0b123!
HTTPS
First thing first. HTTPS is not related with this topic. Because using POST or GET does not matter from attacker perspective. Attackers can easily grab sensitive data from query string or directly POST request body when traffic is HTTP. Therefor it does not make any difference.
Server Logs
We know that Apache, Nginx or other services logging every single HTTP request into log file. Which means query string ( ?username=alice&password=b0b123! ) gonna be written into log files. This can be dangerous because of your system administrator can access this data too and grab all user credentials. Also another case could be happen when your application server compromise. I believe you are storing password as hashed. If you use powerful hashing algorithm like SHA256, your client's password will be more secure against hackers. But hackers can access log files directly get passwords as a plain-text with very basic shell scripts.
Referer Information
We assumed that client opened above link. When client browser get html content and try to parse it, it will see image tag. This images can be hosted at out of your domain ( postimage or similar services, or directly a domain that under the hacker's control ) . Browser make a HTTP request in order to get image. But current url is https://www.site.com/?username=alice&password=b0b123! which is going to be referer information!
That means alice and her password will be passed to another domain and can be accessible directly from web logs. This is really important security issue.
This topic reminds me to Session Fixation Vulnerabilities. Please read following OWASP article for almost same security flaw with sessions. ( https://www.owasp.org/index.php/Session_fixation ) It's worth to read it.
The community has provided a broad view on the considerations, the above stands with respect to the question. However, GET requests may, in general, need authentication. As observed above, sending user name/password as part of the URL is never correct, however, that is typically not the way authentication information is usually handled. When a request for a resource is sent to the server, the server generally responds with a 401 and Authentication header in the response, against which the client sends an Authorization header with the authentication information (in the Basic scheme). Now, this second request from client can be a POST or a GET request, nothing prevents that. So, generally, it is not the request type but the mode of communicating the information is in question.
Refer http://en.wikipedia.org/wiki/Basic_access_authentication
Consider this:
https://www.example.com/login
Javascript within login page:
$.getJSON("/login?user=joeblow&pass=securepassword123");
What would the referer be now?
If you're concerned about security, an extra layer could be:
var a = Base64.encode(user.':'.pass);
$.getJSON("/login?a="+a);
Although not encrypted, at least the data is obscured from plain sight.

HTTP Referer for Single Sign On

As part of a project with a partner, we are required to provide single-sign-on service on our app. Basically, people will log in through our partner's website, then they are redirected to ours. The redirected request will have the user's data in the HTTP header fields.
Here's where it gets "iffy". The process of authenticating if this request is valid or not is dependent on the value of the HTTP Referer field. Our partner tells us to check this field to see that the source is a legitimate one.
Now I know (and I'm glad to be proven wrong) that this field is easy enough to forge, and since no other method of authentication is given to us, a malicious user could easily construct a false HTTP request and gain access to our web app.
I'm a programmer first, and admittedly know very little about the intricacies of HTTP. So are my concerns real? Would using SSL (somehow) void this concern?
Remember that rule number one is never trust client input. Like any other client input, the Referer header is trivial to forge. SSL does nothing for you because you still rely on client input. Also, note that browsers SHOULD NOT send Referer to http pages when referred by https pages.
Additionally, consider that many privacy-conscious people and proxies (that individuals may not have any control over) might strip Referer headers from their requests, breaking your scheme.
To do this properly, you need to use something like OAuth or OpenID, where the protocols have been designed to be secure.
The HTTP Referrer header is unreliable: depending on the browser used it may not be sent.
Does http-equiv="refresh" keep referrer info and metadata?
Yes - It is forgeable.
No - A client can just as easily send a (fake) HTTPS request as a (fake) HTTP request. The only difference is the connection is encrypted. It says nothing about the data transmitted.
That being said, it is another precaution that can be used. It should not be relied upon for security, however.
I would look at Microsoft Federation -- it's likely overkill, but it shows one way to implement SSO securely.

Securing rest service

I’m designing a REST service that needs to be well secured against unauthorized access. I’m thinking about requiring a security digest that’s generated by hashing all request parameters plus a secret key with sha-256 and making the service only available over https. Can anyone tell me if this is sufficient security?
First of all, make sure you are using en HMAC, not a plain SHA-256 to generate the "security digest".
Next, what are you going to put into the input of this digest? You'll want to have at least the method, the URI, the payload, and very possibly most of the headers of the request (there are many headers that affect the meaning of an HTTP request that are important in a REST context). That might be difficult depending on what HTTP client you are using because the client might set or change headers in a way that you do not directly control.
Finally, where are you going to put this digest? A custom header (e.g. X-Request-Authenticator) seems sensible, or maybe a cookie if the client is running in a web browser.
I would recommend using existing tools if you can, instead of creating something yourself. Using SSL already gives you message integrity protection so start with that. Then, if you just need simple access control, HTTP basic auth will work just fine with a REST request. Or you could have the client present a certificate and verify it.

Resources