Why do I see plaintext credentials in wireshark using basic auth over http? - base64

I am using Wireshark to analyse network traffic and basic auth on a local server which I set up in my network.
When authenticating with basic auth I can see the passwort and username in the "Authorization" header of my http request in Wireshark. I know that it is not secure to use basic auth over http (and maybe not even over https) but since the credentials get base64 encoded I did not expect to see them in plaintext.
Does wireshark automatically decode the base64 encoding on the credentials or did I get something wrong with how the encoding process works?

Your assumption is correct, Wireshark has decoded the Authorization header for you. You should see both the base64 string, and the decoded results.
Wireshark does more than just show raw packets, it dissects them. That's what makes the tool so convenient and powerful (or scary from a point of view).

Related

Decode a JWT token automatically in Charles Proxy

I've been using Charles to debug the communication between a mobile app and an API.
We are now changing both the client (app) and the server to use JSON Web Tokens (JWT).
Is there a way to configure Charles so that the JWT is decoded when browsing the requests ?
Basically, the request (from mobile app to server) will consist of a single header (Authorization) containing the JWT, and when I click on that request in Charles, I'd like to see:
- the original token
- the decoded header
- the decoded payload
Looking at Charles' documentation, I found the following:
- Rewrite tool: could replace the token with the decoded data, but it doesn't seem like functions (base64decode) are supported, only plain text or and regexp replacement.
- Map Remote tool: seems like it could do the job, by calling a script on a server which takes in the original request as an argument, and returns the new request with the decoded data. The documentation describes a use for replacing specific sources (when browsing a website), so I'm having a hard time seeing how it could be applied to this case (client to API communication). Doesn't seem like it can pass the original request as an argument (just replaces it).
I know that I could always copy paste the token in a tool that decodes JWT, but that's a small step that I will be repeating a hundred/thousands of times, so I'd like to avoid it.
Or is there another way to debug HTTP requests between mobile and server that are encoded in JWT format ?
Since Charles Proxy doesn't support JWT Decode feature, you can try out Proxyman, which automatically decode JWT and display in a nice place.
If you need to manipulate it, you can take a look at JWT Decode Addon . The Scripting feature allows you to write JS code to achieve the same result.
Disclaimer: I'm a creator of Proxyman. Hope this answer could help you.

Sending cookies between servers vs sending headers

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.

Can i include symbols in a password intended for HTTP basic auth

I'm using basic auth over SSL for CouchDB, and I was wondering, if there are symbols in my password, how do I get it working, and not colliding with the url in general?
For example: https://username:p#$$word#couchdb.domain.com/db
Any help would rock!
Basic auth uses the Authorization header in the HTTP request to pass your user name and password, not the URL. The URL you have posted is a shortcut supported by some browsers (in which the browser converts the username/password in the URL into the appropriate headers). The URL format is not actually part of the basic auth spec (see the RFC for more complete details: https://www.ietf.org/rfc/rfc2617.txt).
With that out of the way, yes, basic auth supports symbols and you should not need to worry about whether or not those symbols have special meaning in a URL. However, the basic auth spec is ambiguous when it comes to charsets and contains no way to specify which charset is being used to encode the user name and password. As a result, any character outside the 7 bit ASCII range may cause issues dependent upon the server side implementation.
According to the Basic Authentication RFC:
To receive authorization, the client sends the userid and password, separated by a single colon (":") character, within a base64 encoded string in the credentials.
I don't understand why you feel you must send your credentials in clear-text as part of the URL, when the official Couch DB documentation clearly suggests a more standard way of authentication.

Cookie security when passed over SSL

Am I correct in thinking that if you pass a session cookie over an SSL encrypted request that the cookie could only be read by an attacker who had direct access to the computer that the cookie had been sent to, or the server it has been sent from, provided they are unable to crack the encryption?
SSL encrypts all traffic, including the header (which contains the cookie value).
On the other hand, the cookie can be accessed via Javascript on the client machine, unless you have marked it as HttpOnly. A hacker could potentially get this script to run via an XSS attack.
In addition, there are ways to hijack the cookie with a carefully crafted email or web page. This is known as session riding or CSRF.
Finally, cookies are visible on the wire for any network connection beyond the point of SSL termination, e.g. if you data center uses SSL offloading and/or deep packet inspection.
Oh, and one more thing. If SSL isn't configured correctly it is easily vulnerable to MITM attack, e.g. your server is configured to accept a null protocol. In this case a hacker can of course read the cookie plain as day.
I think that's it. That should be enough to keep you up at night.
To add to #John Wu's answer you can also protect against another type of MITM attack by setting the Secure Flag. This will make sure that the cookie is only transmitted by the browser when the request is sent encrypted over HTTPS.
Even though the cookie can only be set by your site, you should still encode if it is output to guard against XSS. See my other answer here for more details: https://security.stackexchange.com/a/44976/8340
Correct, SSL encrypts all HTTP on the wire.

Safe to send login credentials using HTTP and not HTTPS?

Is it safe to submit an HTTP POST whose body contains plaintext username and password, or is HTTPS completely necessary?
HTTPS is required. All HTTP traffic can be sniffed.
No, HTTP alone does not give you any security at all. If someone is able to read the network traffic, they would be able to read the credentials too.
The network traffic might also be protected separately, but you can’t control the network. But you can control your application. So HTTPS ist a must.
It's never safe to send an unencrypted, plaintext username and password over a wire others have access to.
While it's safe to send encrypted data over HTTP, HTTPS does this for you, giving you the added benefit of TLS. Given how well it stands up theoretically and in practice, it's far more compelling to use than inventing your own algorithm.

Resources