Item1029: TemplateLogin provides incorrect status for Authentication requests & failures.

pencil
Priority: Normal
Current State: Closed
Released In: 1.0.10, 1.1.0
Target Release: patch
Applies To: Engine
Component: TemplateLogin
Branches:
Reported By: EugenMayer
Waiting For:
Last Change By: KennethLavrsen
When you dont provide a username, the template login returns the login form with status 200. I changed that to 400. As this cant break anything but provides proper status, i check it in for the trunk ( 1.0.1 )

Addition

In addition i strongly proposal security wise, to change the response when the login is not valid. I know 403 is the correct one, but it provides the information, that you tried to check the pair. I would generalize the all errors on logins with 400 to give no informations on what could be wrong ( for the attacker ).

  • this is of course a task for after 1.0.1 and after the branching.
  • Becuase this can break form which use this 403


According to HTTP Status Code Definitions:

10.4.1 400 Bad Request

The request could not be understood by the server due to malformed syntax. The client SHOULD NOT repeat the request without modifications.

It should be used when the client sends a malformed HTTP request. This is not the case here, so should not be used.

403 code signals that there is no permission to access the requested resource, so it's also wrong to use it on login failure.

401 is related to authentication, but this code tells the client to send WWW-Authenticate header, that is not used by TemplateLogin.

Notice that, from the HTTP point of view, TemplateLogin is not different from any other page, so the status 200 (Success) should be used, even if there was a login error (the new login page with "Bad Login" warning was successfully accessed).

Add a custom X- response header, if you want to know the login result only by examining http headers, but be aware that the header will not be present with ApacheLogin (your code should work regardless the authentication mechanism).

Please, revert that change.

-- GilmarSantosJr - 08 Feb 2009

We had a little IRC discussion on how the RFCs should be interpreted.
  • Option a) status codes reflect the status of the http protocol/connection/whatever or
  • Option b) status codes may also be used for the application level

I think, we need a consensus on this issue within our community.

-- OliverKrueger - 08 Feb 2009

I spent a lot of time reading and thinking about this situation since I wrote the above comment. Now I'm convinced I was wrong. HTTP status code refer to resources. If a user request a resource and get a login screen instead, it's clear that the response was not successful (the "correct" status should be 401, but this would make the browser prompt credentials, so it's better to use 403, as the code is).

The 400 code added is also right, since it is returned when the user doesn't provide credentials (the user was requested to provide credentials, but didn't, so "Bad Request").

I disagree from Eugen in the generalization to 400. I don't like the generalization idea, but if we adopt it, then 403 seems better (IMHO).

-- GilmarSantosJr - 09 Feb 2009

blimey. given the feedback, this should never have made it into a release. 400 is wrong in this context, as the request is quite valid, and even desired.

for eg, a relatively simple laymans' summary from http://www.checkupdown.com/status/E400.html :

The Web server (running the Web site) thinks that the data stream sent by the client (e.g. your Web browser or our CheckUpDown robot) was 'malformed' i.e. did not respect the HTTP protocol completely. So the Web server was unable to understand the request and process it.

as an eg, WWW::Mechanise pretty much bombs out at 400,

basically, its like asking doing the following
telnet some.web.server 80
GET some_bananas(count=>4, quality=>good);

whereas GET /bin/login/System is a valid foswiki request, and even a desired one which we link to.

This reversion needs to go into 1.0.10 too.

I've set it to 200 - I'm willing to accept that something else might be better, but 400 don't request this again is not the right answer.

(I presume that I can't use Strikeone for login from WWW::Mechanize::Foswiki until this is fixed, as I need a successful request without loginname first)

-- SvenDowideit - 07 Feb 2010

doing a little reading from irc - i see Crawford agreeing to 401

CDot: it definitely should not be a 200, when a 401 is indicated. Let's get these status codes right. which somehow got implemented as 400?

Eugen went on to claim that 400 was used by all the web2.0 sites - but i can't find any references supporting this.

it seems a little surprising that the irc log contains opinions about interpretation - I would have expected that basic auth is well documented, and that a html replacement use exactly the same interpretation of the response codes. find reference

small research

I thought I'd see what other sites have done..

so far I have not found even one site that returns anything other than 200 both for unfilled in UI and even for failed login.

I hope someone can actually point to some examples where a real site, with needs to scale (ie, proxys, distributed sessions and stuff more complex than just one server) does anything as dubious as re-interpreting the RFC.

-- SvenDowideit - 07 Feb 2010

Yahoo gives 200 OK for:
  • Login prompt
  • Login success
  • Login failed

gmail gives 200 OK for:
  • Login prompt
  • Login success
  • Login failed (200 OK on the login POST. Then there are a couple of GETs that follow, one of which holds something like ?glxu=[username], which is a 204 - no content)

-- PaulHarvey - 07 Feb 2010

The change to return 200 breaks BuildContrib. Build.pm checks for 400, and reports failed to retrieve the login form if 400 is not returned. Filed Item8490 to fix BuildContrib.

-- GeorgeClark - 10 Feb 2010

I followed the thread on the list, and I now understand one strange thing that I had noticed when browsing a Foswiki with lynx (the console based browser) when selecting "Log In" with Lynx, the browser briefly reports

"Alert! : HTTP/1.1 400 Bad Request"

this appears in a scary red color in the status line, before the page finally shows up smile

Please note that this "Alert!" appears just by selecting "Log In" from the home page in the "Log In or Register" left bar, i.e. not doing anything else than trying to access the Log In page.

I guess this "Alert!" message will vanish from that browser once the status code is changed to 200.

I guess also that any 4xx code would probably throw a red Alert! message in Lynx too.

-- RaulFRodriguez - 12 Feb 2010


I believe there is more wrong here with what we are doing. I've run some wireshark traces of our bin/login panel.

  • GET bin/login returns 400. This really is wrong. The request was understood, and the empty login panel was returned. 200 should be the expected response.

10.4.1 400 Bad Request

The request could not be understood by the server due to malformed syntax. The client SHOULD NOT repeat the request without modifications.

The Perl CGI programming book has some additional information: http://docstore.mik.ua/orelly/linux/cgi/ch03_03.htm

400 is a general error indicating that the browser sent an invalid request due to bad syntax. Examples include an invalid Host header field or a request with content but without a Content-type header. You should not have to return a 400 status because the web server should recognize these problems and reply with this error status code for you instead of calling your CGI script.

  • POST bin/login returns 403 for invalid password. This is also wrong. The statements "Authorization will not help" and "SHOULD NOT be repeated" are not correct.

10.4.4 403 Forbidden

The server understood the request, but is refusing to fulfill it. Authorization will not help and the request SHOULD NOT be repeated. ...

What ORiley says on this code:
403 indicates that the client is not allowed to access the requested resource for some reason other than needing a valid HTTP login. Remember ... that CGI scripts must have the correct permissions set up in order to run? Your browser will receive a 403 status if you attempt to run CGI scripts that do not have the correct execute permissions.

You might return this status code for certain protected CGI scripts if the user fails to meet some criteria such as having a particular IP address, a particular browser cookie, etc.

So the only place we would be using 403 would be for example when an authenticated user tried to run bin/attach or bin/edit and did not have authority to run those scripts.

Another way to look at our template login would be to consider any other template form. When I call up the form it is presented as a 200. When I POST a response, say it's a database form with a letters in a numeric field. It would be rejected, but the response would still be a 200. The Template login is a simple application form, it's not HTTP authentication.
Having re-read the RFCs, the discussion here and some discussions on IRC, I'm of the following opinion:
  • There is nothing wrong in an application using status codes that are part of the HTTP as long as it implements the whole protocol
    • The means it has to implement WW-Authenticate and Authorization headers, and any other related headers, and use the correct status codes in all interactions.
  • If you do not implement the whole protocol then you should not use the status codes.
This means that the 200 response code was correct, insofar as we do not attempt to implement the whole HTTP.

Note that in the case of an RPC (REST) call demanding authentication, the headers returned must include WWW-Authenticate with a 401. We have insufficient support in Foswiki::Func for building correct returns.

-- CrawfordCurrie - 12 Feb 2010

much more discussion on the foswiki-svn mailing list, showing that 200 is the only option


CDot: hi, when using foswiki with blackberry, i always get an error 400 before being able to navigate to the next site - is this a known issue?
Just a short testimony to confirm that code 400 keeps Google Search Appliance from crawling our Intranet (release 1.0.7). The Google Search Appliance uses an automated scenario to obtain and store cookie credentials from Foswiki before crawling a protected location (identified by URL patterns). When it comes to obtain the cookie from Foswiki, if the login screen returns a 400 code at some point, Google stops further attempts and will never ask again for a cookie. No cookie... no crawling.

-- CyrilBousquet - 16 Feb 2010

From what I see, 200 is okay - even for a login screen. The fact that this is a login screen is not relevant on the HTTP layer. Of course, authentication can also happen on the HTTP layer. But that is a totally different thing one should not mix up.

For REST calls, a HTTP 200 containing a login screen is a problem, and will always be. Redirecting a REST call to a login screen is fundamentally wrong. Sure, one could think of an application layer based on JSON-REST to perform authentication, but this most probably is overkill. And if done wrong, it becomes a disaster.

Basically, securing REST calls means authenticating using HTTP basic auth over SSL. That's supported universaly by all frameworks. So remaining problem is how to have a "mixed" login scheme, part of which is TemplateLogin, while any RPC call is covered by HTTP basic auth.

-- MichaelDaum - 30 Apr 2010

Is this issue ongoing? I think an HTTP 400 response is causing all kinds of hell in IIS 6, causing it to hang horribly (i'm not sure why). I created topic Support.Question551, and only afterwards found this task.

I have edited my local copy of TemplateLogin.pm to remove the one outstanding "status 400" line (outer "else" clause at line 189 in Foswiki v 1.0.9) and login finally works in IIS6 with TemplateLogin!!

Not knowing when this will be addressed, I am adding a note to the instructions at FoswikiOnWindowsIISAndPerl.

-- TaoKlerks - 07 Jun 2010

Tao, I changed your comment on FoswikiOnWindowsIISAndPerl from "It looks like it might be addressed in Foswiki 1.0.10" to "It is corrected in the code of Foswiki versions subsequent to 1.0.9", since this change has been done in the SVN server in the development code for branch 1.0.x as well as the development code for 1.1.0. At the moment, it is not foreseen that a 1.0.10 will come up, since the development effort is on having the 1.1.0 out. But in either cases, the correction is there since April, done by SvenDowideit and GeorgeClark.

Sven, George, shouldn't the status of this task be changed to "Waiting for release" since it appears this is fixed ?

Also, I think the "ReleasedIn" field contains a mistake, and should mention 1.0.10 and 1.1.0 instead of 1.0.1 and 1.0.10. Since you have fixed this, I will let you change that too.

-- RaulFRodriguez - 17 Jun 2010

very good point - yes, we we have fixed it for the next release :/ clearly we need to make it happen asap.

-- SvenDowideit - 18 Jun 2010

ItemTemplate edit

Summary TemplateLogin provides incorrect status for Authentication requests & failures.
ReportedBy EugenMayer
Codebase 1.0.9, 1.0.8, 1.0.7, 1.0.6, 1.0.5, 1.0.4, 1.0.3, 1.0.2, trunk
SVN Range Foswiki-1.0.0, Thu, 08 Jan 2009, build 1878
AppliesTo Engine
Component TemplateLogin
Priority Normal
CurrentState Closed
WaitingFor
Checkins distro:6e2362b5e8fd distro:c620e0884d5f distro:0380d8c8d480 distro:bfe1b084bffb
TargetRelease patch
ReleasedIn 1.0.10, 1.1.0
Topic revision: r32 - 08 Sep 2010, KennethLavrsen
The copyright of the content on this website is held by the contributing authors, except where stated elsewhere. See Copyright Statement. Creative Commons License    Legal Imprint    Privacy Policy