Send password. Urlencoded or multipart? - forms

I have set up TLS to transfer passwords securely. Now I wonder if it is overkill to use form (POST) with enctype = "urlencoded" as also a layer of "protection"? (I know anyone can decode this). The other option is POST with enctype = "multipart" which is transparent / readable directly.
Appreciate all points of view

Encoding in this case is not a security feature (ie. it has nothing to do with security). It doesn't matter how you encode the password, the only purpose of such encoding is to be able to transmit it in a valid HTTP request, considering all the special characters it may have and so on. Security (encryption, server authentication, etc) is provided by TLS under HTTP.

Related

JSON API and CSRF

I'm developing a web API. authentication is through cookies. All endpoints receive parameters through JSON in the request body.
Do I need to implement a CSRF token to protect them?
How can this be exploitable? Is it possible to send JSON through a normal <form> element?
Is it possible for an attacker to have something like this?
<form type="application/json" method="POST">
<input name="json" value="{ my json code here }">
<input type="submit">Send</input>
<form>
Firstly, you have to secure your API to avoid HTML/JavaScript injections that can cause CSRF attacks on OTHER sites. To do it:
use HTTPS for all communications to avoid MITM attacks
sanitize all income data to prevent HTML/JavaScript/SQL/LDAP/Command/... injections. You can also use web application firewall or WAF that prevents different types of attacks.
Use HTTP headers:
X-XSS-Protection "1; mode=block" - this header enables the Cross-site scripting (XSS) filter built into most recent web browsers.
Content-Security-Policy - this header tells the browser that it can only communicate with the domains you explicitly allow.
In case your API provides any sensitive information than use CSRF token to avoid CSRF attacks on YOUR API. The CSRF attack to your API can be done for example by injected JavaScript to another website. In this case the injection can make correct AJAX request.
CSRF Token is a must, maybe you can add some hash based on the value and match it later, and you might be want to consider using ajax to send the value rather than put it inside an input, since JSON often have double quotes lie value="{name:""}" and that will make the HTML become invalid.
there's no attribute named type for HTML forms. The closest attribute is enctype, and you can find it's reference here. The only valid values for the attribute are:
-application/x-www-form-urlencoded, the default. All characters are encoded before sent (spaces are converted to "+" symbols, and special characters are converted to ASCII HEX values)
-multipart/form-data, No characters are encoded. This value is required when you are using forms that have a file upload control.
-text/plain Spaces are converted to "+" symbols, but no special characters are encoded.
Therefore a simple form can not submit a valid JSON payload.

Hotmail can not properly read email with ! in url

I have a single page app, which has URLs like http://example.com/#!something/something/. The problem is that when I send email containing link to such url, hotmail users get them wrong (I have noticed it only in hotmail, everyone else is good).
The ! is encoded to %21 which makes the url wrong: http://example.com/#%21something/something/
Any ideas what can be done except rewriting my app :-). I am using swiftmailer to send email, but I highly doubt that this is relevant.
According to RFC3986, the "!" character is valid in the fragment (#...) component of URIs, so it should not get encoded using percent-encoding. In this sense, this seems to be an outlook.com bug.
One workaround is to use plain-text emails: based on my tests, outlook.com encodes !'s HTML email links only and plain-text emails are safe.
The real solution, however, is to do your own normalization in the client-side code. URL cracking and normalization is a really tricky business, so I'd expect issues with other email clients, too. Running JavaScript decodeUriComponent() against window.location.hash should give you the unencoded "#!/something/something" version regardless whether the exclamation mark was encoded or not. I understand this calls for modifying the web application that you wanted to avoid, but to my best knowledge this is the way to go.

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.

Customer email header that doesn't get stripped

We need to pass some data in emails that can be used for tracking and correlation, we were looking at using a custom header or a token in the subject/body.
Does anyone know of an email header that can be used that will not be removed by email servers? I know you can add X- headers to specify custom content but it seems you can never be sure they won't survive either the server stripping them or being removed when the email is forwarded.
The token option also doesn't seem ideal as it can easily be removed by the user, are there any other better techniques?
Thanks for your time
A server should not be stripping X- headers (as long as they are correctly formatted, anyway), unless perhaps you happen to pick a name for that X- header that the server uses for its own purposes. But there is no header that cannot be stripped or altered by a server or user. A proper forward operation should preserve the headers, and an improper forward isn't guaranteed to retain any headers.
A header is probably the best method, both because most users won't be aware that headers besides "From", "To", and "Subject" even exist and because that's really the place for such metadata. Encoding it in the Message-Id header might be slightly more robust than in an X- header. Or if it's very short, you could encode it in the subject line as a "ticket number" or the like.

ASIHTTPRequest: Basic Authentication with Base64 encoding?

Does ASIHTTPRequest uses Base64 encoding for username and password? On the webpage I only found out that the username/password is in plain text if SSL is not used.
Basic authentication always uses base64 encoding, and hence ASIHTTPRequest using base64 for basic authentication.
This is often described as passing the username/password in "plain text" as base64 is trivial to decode.
If you use basic authentication over https, then the base64 part containing the username/password is passed over the encrypted https connection, so is no longer in "plain text".
ASIHTTPRequest uses encoding, if you have not specified anything default will be NSISOLatin1StringEncoding.
I am sure it supports NSUTF8StringEncoding.