Do some browsers encode cookies? - encoding

This is sort of a follow-up to Why are my cookies containing JSON occasionally malformed, which we have resolved.
I have a 3-value cookie, and we're url encoding the main value. The other two values are a timestamp and a hash. It looks like this in our response header:
foo=d=634027688530013385&v=%7b%22HasDog%22%3afalse%2c%22Greeting%22%3anull%2c%22RecentRecipes%22%3a%5b%5d%2c%22Remember%22%3afalse%7d&h=ARv5QGf4Cnftc4tFaPoy/VH8Pbo=; path=/; HttpOnly
In our logs, we see cases where we can't parse the three values correctly because the entire cookie is now encoded:
Cookie looks mangled: d%3D634027653097874122%26v%3D%7B%22HasAcceptedTerms%22%3Afalse%2C%22RecipeBoxCount%22%3A0%2C%22Remember%22%3Afalse%7D%26h%3DR85mJ%2FTdA6yrVe5pVCVpfG2jumM%3D
Unfortunately, we're not capturing the user agent to see if this is related to a specific browser.
I have several options to fix this. I just think the behavior is odd enough to warrant a question.

This may not be an answer but....
This is interesting and warrants a deeper look.
I would like to see a public facing test page that shows red or green with the cookie in bold text and then run it through http://browsercam.com.
I did this when I thought I had found a bug in mozilla's native json support. turns out I was right.
Get your testpage working for sure for sure before you fill out the form for a free trial (200 shots), set the resolution to 640/480 and select all browsers/platform, 182 distinct combinations, set a delay to allow the redirection to set the cookie and track down the culprit.
Or take the time and get on http://testswarm.com/.
Please do follow up on this.

Related

Url's containing authentication secrets and app ID's

We received a request to create a REST api. I was a little confused in the example of provided by our client. As you can see below, they've identified the app_id and secret in the URL before the #. The remainder of the URI looks like what I would expect.
Is this valid? I thought maybe this is some weird cURL format I haven't seen before.
https://{application_id}:{api_secret}#api.example.com/entity/{entity_id}/
https://{application_id}:{api_secret}#api.example.com/entity/{entity_id}/entity_locations/{locations_id}/
Just seeing if anyone has seen this format before?
A URI is made up of various parts, one of them being the authority part, which can feature optional username:password element.
The full scheme is:
scheme://username:password#domain:port/path?query_string#fragment_id
This way your REST api remains stateless [not relying on previous app states like storing stuff in session]. But I advice you not to explicitly go with the username:password#stuff route, but to rely on Basic HTTP Auth, so the credentials are sent encoded in Base64 at least.
EDIT: a brief note about BasicAuth now you're asking - things go like this:
you make a request to http://johndoe:12345#service/api/foo/bar;
are credentials good? Ok, you get a 200 OK response with proper body;
are they not? You get a 401 Unauthorized response.
In the latter case, it's the browser [or any other program / script performing the request] that should prompt the user with the login popup.
Usually browsers ask you to cache credentials not to ask them every time, but this does not mean that they are not sent - it's just that every request to protected resources are featured with such header:
Authorization Basic base64encode(username:password)
Where base64encode is your custom way to encode the username:password string.

Preventing CSRF?

I already seen some question from here (stackoverflow) and THIS post, but I still have some questions...
Using hidden value in the post form and check it when post reach the server.
The hidden value can easy be copied and send exactly like the real one, "hard to guess" (like md5) will not help. (right?)
Setting a cookie when you reach the form and send the cookie value as a hidden value.
You can easily change a cookie value or send a custom cookie exactly like the real one using the same real hidden value. (right?)
Using 'timeout', the POST values cannot reach too late.
So, if you're slow you will fail when you try to set everything up with the hidden value. If you're fast it gonna work. (right?)
I want to be protected about CSRF...but how exactly I do it?
The easiest way I found to prevent CSRF issues is:
On the server side, assign an HttpOnly cookie to the client with a random (unguessable) token
Place a hidden field on the form with that cookie value
Upon form submit, ensure the hidden field value equals the cookie value (on the server side of things)
If you make the following changes then I think you're safe
no data updates should be allowed through GET (or better POST as well) (since both can be used through HTML forms)
disable CORS on your server (or at least on endpoints that are critical and/or make changes to data)
allow JSON-only APIs (ie. only accept input through JSON on critical endpoints at least)
Just to add to above: Do not use method overrides and do not support old browsers.

Problems with Phototobucket oAuth

Seems like a lot of people have problems getting oAuth to work with Photobucket and now I'm one of them, I keep getting:
"Authentication failed signature check failed"
When trying to get a request token, here is the header info I send along:
OAuth realm=""
oauth_consumer_key="XXXXXXXXX"
oauth_signature_method="HMAC-SHA1"
oauth_signature="BHHJ4o7zXOlfln4Xpik5rPtjZv8%3D"
oauth_timestamp="1323470655"
oauth_nonce="2FEC3150-8AB9-4BBC-BC4B-FA5AE7EC8046"
oauth_version="1.0"
and my BASE string used to generate the signature:
POST&http%3A%2F%2Fapi.photobucket.com%2Flogin%2Frequest&format%3Djson%26oauth_consumer_key%3DXXXXXXXXX%26oauth_nonce%3D2FEC3150-8AB9-4BBC-BC4B-FA5AE7EC8046%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1323470655%26oauth_version%3D1.0
Everything seems on the up and up and I'm using the same library that I've been using for several other photo/video sharing sites with no problems, this is on iOS...
Thanks
Turns out that even though photobucket causes your requests to sometimes go to api####.photobucket.com (your special load balancing URL) you still have to specify your base string as api.photobucket.com which makes no sense and TOTALLY BREAKS oAuth since you're now setting your base string to a different url than where you're making the request :p
So, be vigilant and always make sure your base string is api.photobucket.com
sigh

problem with multiple cookies and HTTP::Headers

i'm having problems with the HTTP:Cookies extract_cookies() method, i have a HTTP::Header object with multiple cookies in it under a single field name and the method is only extracting a single cookie. The solution is possibly to have each cookie under a separate 'Set-Cookie" field, but from which i can see HTTP::Headers does not allow you to have more than 1 field with the same name. Ideas?
How does this come about? A browser should never send multiple cookies with the same name (at least for the same domain/host and path).
Update: sorry, I misunderstood. It does appear that multiple Netscape cookies are only expected in multiple Set-Cookie headers (but new-style cookies are all expected in the same Set-Cookie2 header). HTTP::Headers should work fine with multiple headers with the same name; what are you seeing?

in what situation does the HTTP_REFERER not work?

I have used referrer before in foo.php to decide whether the page iframing foo.php is of a particular URL. (using $_SERVER['HTTP_REFERER'])
It turned out that most of the time, it worked (about 98% of the time), but it also seemed like some users arrived the page and $_SERVER['HTTP_REFERER'] was not set in foo.php and therefore broke the code. [update: These user claimed that they followed the usual page flow and didn't use the URL of foo.php all by itself on the browser (that they let it be an iframe) and the users never altered their browser settings.]
I wonder what the reasons are that it could happen?
The HTTP/1.1 RFC does not make it mandatory to send an HTTP referer header. You can't make any assumptions about its presence when writing robust code; perfectly conforment browsers may not include it.
Moreoever, the RFC advises that "The Referer field MUST NOT be sent if the Request-URI was obtained from a source that does not have its own URI, such as input from the user keyboard", and "We suggest, though do not require, that a convenient toggle interface be provided for the user to enable or disable the sending of From and Referer information".
The later is not very common (though some browsers have a "Private" mode that fulfils the requirements). More likely for your 2% is that people Bookmarked the URL, which fulfils the first criteria (URI obtained from a source without a URI), and so the browser sends no referer.
Not by default AFAIK, but it's easy to turn it off (for privacy) e.g. in Firefox via about:config, and surely some users could be using browsers distributed to them (e.g. by their IT department) with such kinds of setting. So you should try to avoid relying on REFERER for any important functionality (also because it's mis-spelled, of course;-).