Thursday, August 15, 2013

public static string ReverseWords(string s)
{
 var sb = new StringBuilder(s);
 Reverse(sb, 0, sb.Length - 1);
 int start = 0;
 int end = 0;
 for (int i = 1; i < sb.Length; i++)
 {
  if (sb[i - 1] != ' ')
  {
   end++;
   if (sb[i] != ' ')
   {
    continue;
   }
  }
  else
  {
    start = i;
    end = i;
  }
  Reverse(sb, start, end - 1);
  start = i;
  end = i;
 }
 Reverse(sb, start, end);
 return sb.ToString();
}

private static void Reverse(StringBuilder sb, int start, int end)
{
 while (start < end)
 {
  var c = sb[end];
  sb[end] = sb[start];
  sb[start] = c;
  end--;
  start++;
 }
}

Some sample test cases:
string s = "The quick brown fox jumped over the trot";Debug.Assert(s == ReverseWords(ReverseWords(s))) ;Debug.Assert("" == ReverseWords(ReverseWords("")));Debug.Assert("abc" == ReverseWords(ReverseWords("abc")));Debug.Assert("ab bc" == ReverseWords(ReverseWords("ab bc")));Debug.Assert(" ab " == ReverseWords(ReverseWords(" ab ")));Debug.Assert("ab " == ReverseWords(ReverseWords("ab ")));Debug.Assert(" ab" == ReverseWords(ReverseWords(" ab")));

Wednesday, August 14, 2013

testing oauth

Lessons learned today.
OAuth has two core concepts - user and client
user is the one who is identified by the user name and password on the registration site.
client is any application that wants to access users data.
user has to permit a client to do so.

Therefore OAuth is all about mapping users and clients. Testing OAuth is about testing this mapping.
Implementations  represent the users with their ID - usually a GUID.
Similarly clients are represented by their ID - also a GUID.

When user permits a client, the client gets a token. This token is the final result of OAuth authentication and authorization. It manifests the privilege granted by the user to the client. This privilege is quite detailed and scoped as we will see in a moment but it displays as a generated hash that has no meaning. It cannot be guessed or generated by third party.

When the user grants access to a data to a client, the token is generated by the authorizing endpoint which the client then uses to make calls to retrieve the data. The token has an expiry typically set to an hour so that the client can make more than one calls without having to repeat the handshake for every call. The expiry forces the client to request another so that it cannot be misused later and the issuer doesn't have to keep track of the granted privilege or require the client to revoke it.

The token is also granted for a certain scope of the user's data. Not all data may be accessible by the token. In fact the issuer of the token wants the user to scope down the privilege to only the minimum required so that the client can have access to just as much data and no more.  The scope is transparent to the client. This means that the string representing the scope is made up of parts that are understood by the client and defined by the issuer.

The token is responded with a certain state. The state is opaque to the issuer. It is mainly used by the client to keep track of the calls and the callbacks associated with the calls. Since the client sets the state, the client will know if there was a cross site request forgery when the state is tampered.

As we have seen the token issued for the client on behalf of the user, is associated with a privilege for a scope and with with an expiry period.  Testing focuses on this mapping and the result of the OAuth handshake.

Native applications in the OAuth RFC

This post I'm making so that I read up on what the spec says. Its easy to get confused in the labyrinth of terms and use cases so I will focus on select cases.
Implicit client credential grant
The RFC for OAuth calls implicit grant a simplified authorization flow because it issues a client token directly instead of an intermediate authorization code. The client is issued an access token directly because the resource owner is authenticated. When issuing an access token to the client, the client Id is not verfiied.  This is different from what I mentioned in the previous post. The redirect_uri in the token grant is intended to deliver the token to the client. The token may be exposed to the resource owner or other applications with access to the resource owner's user-agent. The access token security says that tokens can be generated or guessed by unauthorized parties and that its delivery should be over the TLS. Further the scope of the token should be as minimal as possible. The authorization server should though not a must verify the client identity.
there is no provisioning to verify that the token presented by a client was indeed issued by the server.
The RFC calls out a section for the native applications.
Native applications are clients installed and executed on the device used by the resource owner. The authorization endpoint requires interaction between the client and the resource owners' user agent. Native applications can invoke an external user-agent or embed a user-agent within the application.
If an external user agent is involved, the application can capture the response from the authorization server using a redirection URI and a callback for the JSON response from the server or manually copy and paste of the credentials or running a local web server or installing a user-agent extension to identify a server hosted resource which in turn makes the response available to the native application
If the user agent is embeded, the native application obtains the response with the redirect_uri and the token by directly communicating with the embedded user-agent such as resource load or cookies.
An external user-agent reassures the user to enter his password since this is going to the same site where he or she has been doing so and may even rely on features that come with the site.  It also offloads the session persistence and sign-on/sign-off from multiple devices for the user. Thi shsould be preferred.
An embedded user-agent removes the need to switch context or open new windows and the client can directly communicate with the user agent over the local device. But it leads to security vulnerabilities such as phising attacks.
When choosing between an implicit grant type and the authorization code grant type, native applications should request the code without the client credentials beacuse the native application cannot keep the client credentials confidential. This is why client id and client secret should not be hardcoded in the application and made avialable in the binary of the installation.
In the implicit grant type, there is no refresh token so on token expiry the authorization process is repated.

Tuesday, August 13, 2013

Password vs implicit grant on OAuth as I understand it

The OAuth implementations need not provide both password and implicit grant methods on the same endpoint. Hence there can be more than one endpoints available to the user agent. In this discussion we will use the following definitions:
User : this is the resource owner. She should have access to her profile via the APIs
User Agent : this is the browser. The mobile phone or an iPhone App can be a user agent as well.
Client : this is the application registered with Mashery. It can make service requests on behalf of the user.
Service: A service is the resource provider and holds all data.
Authorization server: this issues tokens
Note authentication and authorization are two separate parts of the login process. Authentication is assumed to be taken care of by web site using username and password such as in the case of starbucks.com with starbucks.com username and password. If the Starbucks application is official and branded, it has no problems taking the username and password from the user and together with its client id, retrieving a token from the authorization endpoint.
However implicit is required for unofficial developer applications because a user may not be comfortable providing his/her username or password to third party iPhone applications. Here the client inside the user agent will need to redirect the user to the login website along with the client id. The authentication website will redirect back to the user agent with the token so the user agent is only aware of the token and can make use of this token to make subsequent API calls.
We need this website that can accept requests from different clients and enables the user to grant access to these clients. Note that the website needs to be hosted by Starbucks.User Id may not be retrieved and certainly not passed to the client or user agent. The tokens last for 3600 seconds so they can be used across calls. However the token needs to be retrieved with the user context and the client context by the web site.
UserId translation is not required anywhere unless the implicit needs to be supported. In which case, they could be available off the request header. Note that Implicit is not a token provider because it would require userId or the alias me which is not supported by authorization endpoints because there is no way to tie the userId to the sender sending the userId even if the senders are all authenticated. This is the hurdle that needs to be overcome for implicit to work per the specification. The specification does not bar userId based token retrieval however implementations have to secure a lot more in order to fully implement implicit. This doesn't mean it cannot be done, just that there is a lot of difference between a password and a user Id. Besides a userId can be treated as internal to the system. In such cases implicit is never available to a mobile application. A mobile application has a well known route to send its client id over to the authentication website and expect a token back to facilitate further calls on behalf of the user.

REST API callback

A callback is something that you wrap the response of an API call with such as a javascript function. This is typically supported by GET API calls only.
To make a REST call from a web browser across domains, we can use JSONP.
JSONP or JSON with padding provides a method to request data from a server in a different domain. This was previously prohibhited to ensure same origin policy but has since been addressed with Cross-Origin resource sharing (CORS). The same origin policy was overridable with the script tag in HTML5. Some pages use the script tag to retrieve Javascript code that operates on dynamically generated JSON from different origin.
So you can have a script like so:
<script src="your_api_call?callback=printResponse" /> This is the cross domain access supported by JSONP.
Each new JSONP request comes with its own script element or reuses an existing one. In the former case, when the script element is newly added to the document object model, it is referred to as the script element injection.  The current mime type supported by JSONP is "application/javascript". There has been discussion to make it more strict with "application/JSON-P"
Cross site request forgery or xsrf attack is often considered a vulnerability in making cross domain calls, however this is avoided by not using callbacks for sensitive data or using callbacks only with same origin for such data. This enforces that the sensitive data is not in the open unless the request is proper. When programmers rely on cookies alone to determine if the request is valid, it is often vulnerable to cross site request forgery.
In cross origin resource sharing , the website accepting cross domain requests sends an Access-Control-Allow-Origin in its response. The values of the headers indicate which sites are allowed.  To allow access from all site a Access-Control-Allow-Origin : * can be specified. However, this is not advisable unless the API is public with non-sensitive data.
The difference between CORS and JSONP is that JSONP only supports GET methods where as CORS supports other methods. Another difference is that JSONP causes XSS issues when external site is compromised. However, CORS allows websites to manually parse responses to further improve security.
Web messaging or cross domain messaging is used when documents communicate with one another across domains. Here the postMessage method in the messaging API and retrieving the window object of the receiving document, plain text data can directly be posted in an iFrame. The message usually carries the following three attributes : data or the actual content, the origin of the sender and lastly the source or the WindowProxy where the document came from. Window has addEventListener method to receive messages.
Courtesy : Wikipedia.

Monday, August 12, 2013

Javascript & OAuth API calls

Javascript is convenient to make OAuth API calls. User places a simple button to retrieve an OAuth token by way of an API call. The type of OAuth flow required for this could be based on password since it is convenient to ask the user what the password is. This could appear with rich Ajax soft sliding appearance of a text input for password on the click of the token retrieval button. The password entry can then directly be used to make the API calls. Helper libraries from the site hosting this page such as scripts at the root level or framework can be used to simplify the code. Here is an example:
<!DOCTYPE html>
<html>
<head>
<script>
function parseJSON(data) {
    return window.JSON && window.JSON.parse ? window.JSON.parse( data ) : (new Function("return " + data))();
}
function GetAccessToken()
{
if (document.getElementById("password").value == "")
{
alert("Enter your password to retrieve an access token");
return;
}

        var xdr= new XDomainRequest();
        xdr.timeout = 10000;
xdr.onreadystatechange=function()
  {
  if (xdr.readyState==4 && xdr.status==200)
    {
  var resp = parseJSON(xdr.responseText);
  document.getElementById(params[access_token]).innerHTML=resp.access_token;
    }
        }
  xdr.open("POST","https://testhost.openapi.starbucks.com/v1/token/",true);
  xdr.setRequestHeader("Content-type","application/json");
  xdr.send("api_Key="+ document.getElementById("apiKey").value +"&grant_type=password&client_id=" + document.getElementById("apiKey").value + "&username=" + mashery_info.username + "&password=" + document.getElementById("password").value + "&scope=test_scope&client_secret=" + document.getElementById("apiSecret").value);
}
</script>
</head>
<body>

<h2>AJAX</h2>
<button type="button" onclick="GetAccessToken()">Get Access Token</button>
<input type="password" id="password" name="password"  />
<input type="text" name="params[access_token]" value="" placeholder="required" />
</body>
</html>

publishing an app to the app store

The following steps are taken to publish an app to the app store. These are loosely based around a demonstration on the YouTube.
To publish an app, I have to sign up for one of the developer programs from Apple.In this case, I would choose an individual developer program. Then I would connect to the ITunesConnect home page and click on manage my applications. Here I would choose the option to Add new App and enter the app information details such as Default Language, App Name, SKU number, Bundle ID. The SKU  number is any unique number sequence you can give. The Application Id is the same as created new.  I can use the helpful link on the same page to create a new one. The Bundle ID should be the same as what was specified under the xcodeproj under the IOS application target. Next I select the availability date and price tier. The version information and additional details are just useful metadata for publish but they are not used anywhere. So any desription is helpful. Next I create the IOS distribution provisioning profile in iOS provisioning portal. I download the distribution profile and add it to XCode. I define debug and release configurations and specify code signing. I make sure everything is marked for IPhone distribution. Then I click on Product Archive to get it read for upload. This builds the package and signs it.Errors encountered during this process should be ironed out. When the product is build, I mark it as a candidate build for release by adding suitable comments and then click on distribute. When I distribute the application, I should get a message  saying the application has been uploaded to the app store. Once this is done, I should be able to download it from the app store on my IPhone to give it a try.