Auth Request Headers during HTTP to HTTPS Redirects - security

Simple question. I would like to know when request headers are sent. Before or after an HTTP to HTTPS redirect? My security concern is our 3rd party vendors contacting our API with a auth-token request header if they carelessly make requests with HTTP.
Thanks for your expertise in this matter.

You cannot prevent that the your 3rd party vendors are sending a token over HTTP. Well, you should change the way you use the token. It shouldn't be necessary to even send it, encrypted or not.
Use the token as a pre-shared-secret. Then the authentication works as follows:
3rd party vendor sends request to server, provides username or something else which identifies him to the server
The server sends a challenge. This is usually the application of a one-way function - a hash-function. So, the server asks the client to send a SHA1-Hash of auth-token.
The client solves the challenge by calculating the SHA1-Hash of auth-token. Then he sends the result back to the server.
The server checks the result by calculating the same SHA1-Hash of the auth-token.
Supposing that you're using a secure hash-function an attacker has no chance of stealing the token as it is only transmitted as a hash-value.
Further reading:
https://blog.restcase.com/restful-api-authentication-basics/

Related

How to distinguish between HTTP requests sent by my client application and other requests from the Internet

Suppose I have an client/server application working over HTTP. The server provides a RESTy API and client calls the server over HTTP using regular HTTP GET requests.
The server requires no authentication. Anyone on the Internet can send a GET HTTP request to my server. It's Ok. I just wonder how I can distinguish between the requests from my client and other requests from the Internet.
Suppose my client sent a request X. A user recorded this request (including the agent, headers, cookies, etc.) and send it again with wget for example. I would like to distinguish between these two requests in the server-side.
There is no exact solution rather then authentication. On the other hand, you do not need to implement username & password authentication for this basic requirement. You could simply identify a random string for your "client" and send it to api over custom http header variable like ;
GET /api/ HTTP/1.1
Host: www.backend.com
My-Custom-Token-Dude: a717sfa618e89a7a7d17dgasad
...
You could distinguish the requests by this custom header variable and it's values existence and validity. But I'm saying "Security through obscurity" is not a solution.
You cannot know for sure if it is your application or not. Anything in the request can be made up.
But, you can make sure that nobody is using your application inadvertently. For example somebody may create a javascript application and point to your REST API. The browser sends the Origin header (draft) indicating in which application was the request generated. You can use this header to filter calls from applications that are not yours.
However, that somebody may use his own web server as proxy to your application, allowing him then to craft HTTP requests with more detail. In this case, at some point you would be able of pin point his IP address and block it.
But the best solution would be to put some degree of authorization. For example, the UI part can ask for authentication via login/password, or just a captcha to ensure the caller is a person, then generate a token and associate that token with the use session. From that point the calls to the API have to provide such token, otherwise you must reject them.

Send Cookie on every request to identify user?

I'm not getting my head around the whole session-management thing.
I've now implemented this to take care for the login process and also this example to protect my services from XSRF attacks.
But now that I'm having it I wonder:
If I turn on SSL, is the cookie sent before a secure connection is built up? So is this session ID (the cookie) ever secure?
Is it save to send the cookie on each request to identify the user? E.g. if a user wants to view his/her settings, to make sure it's not a fake request that tries to retrieve the settings from another user. Is it clear what I mean by that? I would send the session ID on each request, compare it to the session ID in my database and if the request-token (XSRF securiy) is fine I execute the request - or is that too much overhead?
I'm still not quite confident if what I'm doing here is 100% correct and I want to make sure that I don't unnecessarily break any security measures I've spent time implementing.
SSL or TLS connections are established before the HTTP request is sent over the wire, so data in the request is encrypted.
I'm not sure I understand your second question, but a lot of web applications use cookie based authentication to identify the user. As cookies are automatically sent to the website, you have to protect yourself against CSRF attacks.

are nodejs https 3rd party api requests encrypted?

I'm sorry if this is a daft question.
I'm developing an application that uses oauth2 to integrate with a 3rd party api via a server-side flow in node.
The one thing I'd like to confirm is that when I make the final post request to the 3rd party api to retrieve the access token using the node https module is whether or not the connection is encrypted.
From what I gather, when an https request is made from a browser, the browser handles encrypting the data on the client side. Does node encrypt the data in a similar way, or is this something that I need to implement myself?
If there is some background info that I've somehow overlooked in this regard, please let me know.
Thanks
To answer your question: if the OAuth API service you're querying is served over HTTPS, then your HTTP library (most likely request) is already handling encryption transparently for you. Any time you make a request to an HTTPS endpoint, your request WILL FAIL if the client is not handling encryption properly.

Is it a security risk to allow CSRF token to be sent in body OR header?

Most CSRF solutions seem to insist that the CSRF token is sent as part of the POST data.
In my situation the data being sent is json, and I don't control what is sent (and I don't want to start messing with the json). So, I'm thinking of sending the CSRF token as a header. However, there are legacy parts of my application that would still need to be able to send the token in the body (e.g. submits from html forms).
So my CSRF protection would have to allow the request if a valid CSRF token appeared in the body OR a header. Is this a security risk, compared with insisting that the token is in the body?
CSRF is about make a unsuspicious user post data to a server where the attacker believes the user is logged in.
The idea behind the protection, is that the server associate a token to your session, and sends it to you as a cookie and as payload requirement. Then when posting something you send the token in the payload, and as cookie. Therefore the attacker cannot guess what token is in the cookie or the session. If the server receives a post with two different tokens, it will be rejected.
I think it would be fine to put the payload token in a header, as long it is not "Cookie" or any other header that is "remembered" and sent automatically by the browser.
There won't be any security risk if you send a CSRF token in header. Just make sure that the value of this header changes everytime the client requests a page i.e it should be a random number. Also, your web application on client side should send this header back to the server, so that the server can match the value of header sent to the client with the value of the same header received from the client's response.
Sending CSRF in request header is more secure.
CORS doesn't check same-origin policy for the form tag requests, which means if somebody managed to get the CSRF token then he can send the post request by using form tag from different domain (origin)
but in case of sending the CSRF in request header, the form tag cannot send request header, he has to use javascript (fetch() or XmlHttpRequest()), in this case the CORS will prevent him because he is sending from different domain (origin).
This defense relies on the same-origin policy (SOP) restriction that only JavaScript can be used to add a custom header, and only within its origin. By default, browsers do not allow JavaScript to make cross origin requests with custom headers.
below, is quoted from https://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html#use-of-custom-request-headers
If this is the case for your system, you can simply verify the presence of this header and value on all your server side AJAX endpoints in order to protect against CSRF attacks. This approach has the double advantage of usually requiring no UI changes and not introducing any server side state, which is particularly attractive to REST services. You can always add your own custom header and value if that is preferred.
This technique obviously works for AJAX calls, but you still need to protect form tags with approaches described in this document such as tokens. Also, CORS configuration should also be robust to make this solution work effectively (as custom headers for requests coming from other domains trigger a pre-flight CORS check).

understanding basic authentication with a 401

I'm a little confused about Basic authentication in regards to web browsers. I had thought that the web browser would only send an Authorization header after having received an HTTP 401 status in the previous response. However, it appears that Chrome sends the Authorization header with every request thereafter. It has the data that I entered once upon a time in response to a 401 from my website and sends it with every message (according to the developer tools that ship with Chrome and my webserver). Is that expected behavior? Is there some header I should use with my 401 to infer that the Authorization stuff should not be cached? I'm using WWW-Authenticate header currently.
This is the expected behavior of the browser as defined in RFC 2617 (Section 2):
A client SHOULD assume that all paths at or deeper than the depth of
the last symbolic element in the path field of the Request-URI also
are within the protection space specified by the Basic realm value of
the current challenge. A client MAY preemptively send the
corresponding Authorization header with requests for resources in
that space without receipt of another challenge from the server.
Similarly, when a client sends a request to a proxy, it may reuse a
userid and password in the Proxy-Authorization header field without
receiving another challenge from the proxy server. See section 4 for
security considerations associated with Basic authentication.
to my knowledge, Basic HTTP authentication has no ability to perform a logout / re-authentication. This along with the lack of security of HTTP Basic authentication is why most websites now use forms and cookies for auth solutions.
From RFC 2617:
If a prior request has been authorized, the
same credentials MAY be reused for all other requests within that
protection space for a period of time determined by the
authentication scheme, parameters, and/or user preference.
From my experience it is quite common to see browsers automatically sending the Basic credentials for subsequent requests. It prevents having to do an extra round trip for additional resources.

Resources