Wednesday, May 25, 2011

Connecting to Salesforce from Google Apps Script via OAuth & RESTful API

Be sure that you get consumer key/secret pair by registering remote application in Salesforce, with callback URL to "https://spreadsheets.google.com/macros". Then set them as proper script properties of Google Spreadsheet.



Run "queryDataFromSalesforce" function from script editor.

Thursday, April 22, 2010

Twitter @Anywhere and eavesdropping threat in IE6/7

Twitter @Anywhere is a kind of "Facebook Connect for Twitter", which allows 3rd party web site to access twitter API using OAuth (maybe early implementation of OAuth WRAP/2.0 ?), but without server-side code, only using JavaScript.

The @Anywhere service seems using iframe-based cross-domain technique to communicate to API server from the web site with different domain. Recent browsers like Firefox 3+/Chrome 4/Safari 4/Internet Explorer 8 has the feature of HTML5 cross document messaging, so it is not so much difficult. For older browser, I mean Internet Explorer 6/7, they are using window.name transport. The detail of window.name cross-domain frame communication technique is in this article.


I found the eavesdropping concern in @Anywhere's cross-domain communication when used with Internet Explorer 6/7. As I mentioned above, they use window.name technique when users are using those browsers, not HTML5 standard. The window.name hack is useful but insecure because which can be read from any domain contents which are included in the page by iframe. Of course window.name property is protected against reading from the script in different domain (interestingly setting value from different domain is allowed in Internet Explorer), but changing its frame location is always allowed so attacker in the other frame can change its frame location to the attacker's domain and then read the name property to eavesdrop the conversation. Especially Twitter @Anywhere's case OAuth token is included inside the conversation message, so attackers can access any twitter API by using the token.


This is especially affected if the service can contain arbitrary URL content inside iframe. I can imagine a URL intermediation service with iframed content (like ow.ly) might think to adopt @Anywhere to share the URL directly to twitter, but this should be avoided currently.

Wednesday, April 01, 2009

Created "OAuth CrossDomain JavaScript Proxy Service"

Service:


OAuth CrossDomain JavaScript Proxy Service

Source Code:


http://xdoauthproxy.googlecode.com/

What can be done by this service ?


It enables you to easily call out OAuth-protected APIs (3-legged) from any JavaScript client - only JavaScript. No serverside programs are required to write a client.

Writing a client is very easy - one simple asynchronous JavaScript method invokation make it enable to access OAuth protected resource. No cumbersome process implementation like passing security tokens, signing, and showing dialogs to ask user's agreement. This proxy service does these works.

This service is running on Google's App Engine platforrm.

Code Example:


Example Client : OAuth CrossDomain JavaScript Proxy


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Example Client : OAuth CrossDomain JavaScript Proxy</title>
<script type="text/javascript" src="http://xdoauthproxy.appspot.com/js/json2.js"></script>
<script type="text/javascript" src="http://xdoauthproxy.appspot.com/js/xd-oauth-client.js"></script>
<script type="text/javascript">
function startXdRequest() {
XdOAuth.init('http://xdoauthproxy.appspot.com/xd-server.html'); // Initialization
XdOAuth.request({
url : 'http://www.google.com/calendar/feeds/default/private/full?alt=json', // OAuth-protected API Endpoint
success : function(data) {
var result = eval('(' + data + ')');
var html = [];
for (var i=0; i<result.feed.entry.length; i++) {
var entry = result.feed.entry[i];
html.push('<li>'+entry.title.$t+'</li>');
}
document.getElementById('result').innerHTML = html.join('');
},
error : function(res) {
alert(res.status + ':' + res.body);
}
});
}
</script>
</head>
<body>
<img src="./img/s.gif" />
<input type="button" onclick="startXdRequest()" value="Start OAuth Request to get private Google Calendar">
<ul id="result"></ul>
</body>
</html>


What's different from OpenSocial's OAuth Proxy?


It's similar on the point that it enables you to access OAuth APIs from JavaScript client, but this service doesn't require any OpenSocial container. It runs outside of gadget.

How many APIs now supporting ?


Almost all Google's OAuth-enabled GData APIs, Myspace, Twitter, and Smart.fm.

Notice


It pop-ups the window during the request for prompting users to agree to access the data, so you should disble browser's popup blocker for "xdoauthproxy.appspot.com"

Known Limitation


Initialy only GET request is supported. In near future we'll add support of POST or other HTTP method.

Others


You'll be prompted twice to allow intersite data exchange (OAuth Provider -> xdoauthproxy.appspot.com, xdoauthproxy.appspot.com -> The site which embedded JS client code). So it seems a little verbose for end users, but it is mondatory in order to avoid CSRF vulnerability.

Sunday, September 30, 2007

Afrous public beta is now opened !

My personal project for creating JavaScript based mashup engine - called "Afrous" - is now opened to public. In this public beta, several new features are introduced; for example, new user interface totally rewritten using ExtJS, increased numbers of operations and web services, configuration open/save functions, html renderers, and so on.

http://www.afrous.com/


Opinions are welcome in anytime. Please contact me freely.

Wednesday, April 18, 2007

Afrous - Ajax for the rest of us

Afrous is a pure JavaScript mashup engine. All of the data is mash-upped on client-side, that is, on web browser. It also includes graphical user interface which enables drag-and-drop process editing. Arbitrary web services with JSONP interface can be invoked.

http://www.nekodrive.com/afrous/

Notice : This is VERY Alpha version service. No saving function, no loading function, and no documentation, right now...