How to distinguish between ntlm & ntlmv2 authentication - ntlm

I'm viewing some legacy code and attempting to determine if the application is using ntlm or ntlmv2.
Viewing the source the response header set to "WWW-Authenticate", "NTLM".
But I'm not sure if this is an indication of the authentication type.
How to distinguish between ntlm & ntlmv2 authentication ?

You can't unless you dissect the messages.

Related

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.

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.

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.

Windows Authentication Headers without .NET. Possible?

I was wondering if anyone knew of a way to use Windows Authentication without hosting on an ASP site. It's an intranet w/ access to LDAP, so I'm wondering if there's a way to force the client to provide me the data as if it was coming from an ASP site. I just need the login domain and username and I can run from there. Using Node.js on Ubuntu. Anyone have any experience with this?
Update: There's now a module that implements Windows-integrated authentication.
In your 401 response, you need to provide a WWW-Authenticate header with a value of NTLM, which informs browsers that they need to send Windows credentials.
response.writeHead(401, {
'WWW-Authenticate': 'NTLM',
});
You then have the fun of implementing NTLM authentication. Quoting from this document about the NTLM authentication protocol:
The client requests a protected resource from the server:
GET /index.html HTTP/1.1
The server responds with a 401 status, indicating that the client must authenticate. NTLM is presented as a supported authentication mechanism via the WWW-Authenticate header. Typically, the server closes the connection at this time:
HTTP/1.1 401 Unauthorized
WWW-Authenticate: NTLM
Connection: close
Note that Internet Explorer will only select NTLM if it is the first mechanism offered; this is at odds with RFC 2616, which states that the client must select the strongest supported authentication scheme.
The client resubmits the request with an Authorization header containing a Type 1 message parameter. The Type 1 message is Base-64 encoded for transmission. From this point forward, the connection is kept open; closing the connection requires reauthentication of subsequent requests. This implies that the server and client must support persistent connections, via either the HTTP 1.0-style "Keep-Alive" header or HTTP 1.1 (in which persistent connections are employed by default). The relevant request headers appear as follows:
GET /index.html HTTP/1.1
Authorization: NTLM TlRMTVNTUAABAAAABzIAAAYABgArAAAACwALACAAAABXT1JLU1RBVElPTkRPTUFJTg==
The server replies with a 401 status containing a Type 2 message in the WWW-Authenticate header (again, Base-64 encoded). This is shown below.
HTTP/1.1 401 Unauthorized
WWW-Authenticate: NTLM TlRMTVNTUAACAAAADAAMADAAAAABAoEAASNFZ4mrze8AAAAAAAAAAGIAYgA8AAAARABPAE0AQQBJAE4AAgAMAEQATwBNAEEASQBOAAEADABTAEUAUgBWAEUAUgAEABQAZABvAG0AYQBpAG4ALgBjAG8AbQADACIAcwBlAHIAdgBlAHIALgBkAG8AbQBhAGkAbgAuAGMAbwBtAAAAAAA=
The client responds to the Type 2 message by resubmitting the request with an Authorization header containing a Base-64 encoded Type 3 message:
GET /index.html HTTP/1.1
Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGoAAAAYABgAggAAAAwADABAAAAACAAIAEwAAAAWABYAVAAAAAAAAACaAAAAAQIAAEQATwBNAEEASQBOAHUAcwBlAHIAVwBPAFIASwBTAFQAQQBUAEkATwBOAMM3zVy9RPyXgqZnr21CfG3mfCDC0+d8ViWpjBwx6BhHRmspst9GgPOZWPuMITqcxg==
Finally, the server validates the responses in the client's Type 3 message and allows access to the resource.
HTTP/1.1 200 OK
It should be easy enough to get the user's username – it's sent as plain text in the Type 3 message. Actually validating that they've supplied the correct password is another matter entirely. Implementing all of this is left as an exercise for the reader.
Try Apache mod_ntlm or mod_auth_ntlm_winbind.
In Ubuntu:
root#eruditorum.org:~# apt-cache search ntlm apache
libapache2-authenntlm-perl - Perform Microsoft NTLM and Basic User Authentication
root#eruditorum.org:~# apt-cache show libapache2-authenntlm-perl
Package: libapache2-authenntlm-perl
Priority: optional
Section: universe/perl
Installed-Size: 192
Maintainer: Ubuntu MOTU Developers <ubuntu-motu#lists.ubuntu.com>
Original-Maintainer: Debian Perl Group <pkg-perl-maintainers#lists.alioth.debian.org>
Architecture: amd64
Version: 0.02-5
Depends: libapache2-mod-perl2, libc6 (>= 2.4), perl (>= 5.10.0-9), perlapi-5.10.0
Conflicts: libauthen-smb-perl (<= 0.96)
Filename: pool/universe/liba/libapache2-authenntlm-perl/libapache2-authenntlm-perl_0.02-5_amd64.deb
Size: 51418
MD5sum: 46f74ac156f7006d8d71ddbf00097e46
SHA1: 133aebf896156929d364950c2772c3e1344b9c9b
SHA256: 0688b38ab145f888a4d111aad12cb7f201dcd6e12ed969af697d3fec4a55c428
Description: Perform Microsoft NTLM and Basic User Authentication
The purpose of this module is to perform a user authentication via Microsoft's
NTLM protocol. This protocol is supported by all versions of the Internet
Explorer and is mainly useful for intranets. Depending on your preferences
setting IE will supply your windows logon credentials to the web server
when the server asks for NTLM authentication. This saves the user to type in
his/her password again.
.
The NTLM protocol performs a challenge/response to exchange a random number
(nonce) and get back a md4 hash, which is built from the user's password
and the nonce. This makes sure that no password goes over the wire in plain
text.
.
The main advantage of the Perl implementation is, that it can be easily
extended to verify the user/password against other sources than a windows
domain controller.
.
The default implementation is to go to the domain controller for the given
domain and verify the user. If you want to verify the user against another
source, you can inherit from Apache2::AuthenNTLM and override it's methods.
Homepage: http://search.cpan.org/dist/Apache2-AuthenNTLM
Bugs: https://bugs.launchpad.net/ubuntu/+filebug
Origin: Ubuntu
You can use an NTLM module in Apache, or you can setup a script under IIS to capture the login information and POST it over to your node.js site.
If you are using Ubuntu, do a
sudo apt-get ntlmaps or download 'ntlmaps-xx-xx.deb'
and configure your proxy which would ask you for your domain, username and password.
Then run ntlmaps as your proxy. Ntlmaps will authenticate using your username and password. You write any program ntlmaps will authenticate your program automatically using your given configuration details. However there are few things you need to configure as well after installing ntlmaps. First let me know if is this something you are looking for?

Resources