Archive | Programming  

Facebook Developer: how to solve the "Page requested not found" error when developing a Facebook application

10 Sep

I’m developing a Facebook application for fun in my free time and found the solution to a problem that nagged me for a while.

To develop a Facebook application, you use the Facebook Developer application and create a new application. You can even define a localhost application so that you can debug your application locally. Once all the required parameters are well defined for you application and you begin to test the Facebook integration, you may encounter the following error when following you Canvas Page URL:

FacebookDeveloper2

When this was happening to me, my application wasn’t being called at all by Facebook. If you have a real error in your application, your application should be called and you should be able to debug it or you should be at least getting a 404 error from your server.

The solutionFacebookDeveloper1

With trial and error, incomprehension and a lot of swearing, I finally found out that this is a bug in Facebook and pinpointed exactly how it happens for me.

Ensure that the Canvas Page URL and that your Side Nav URL are both in lowercase! There is something in the Facebook folks code that forbids you to add any uppercase letters to the Canvas Page URL and Side Nav URL. So, to be on the safe side, for every URL defined in your application’s settings in Facebook, use lowercase letters!

By the way, it now looks like this problem is now specific to the Side Nav URL being in lowercase. I am pretty sure that there was a similar Facebook error when the Canvas Page URL was in uppercase.

United Nation Web site hacked through amateur SQL injection security hole

13 Aug

You might have heard that the United Nation Web site was hacked Sunday morning. As of Sunday evening was still open to attacks.

What is surprising (or is it?), is that it was easily hacked through a SQL injection attack. If any self-called Web developer were to tell me they don’t know what SQL injection is, I would tell them to change career.

A typical SQL injection attack is made possible when an application does not filter SQL escape characters for character strings. When SQL statements are constructed, string delimiters are inserted in the statement to change the statement or terminate the statement and execute other SQL statements.

For example (typical examples from Wikipedia):

sql = "SELECT * FROM users WHERE name = '" + userName + "';"

This statement checks for a user name (it could also check for a password). As you see, the userName variable is concatenated to the string and surrounded by quotes, the usual literal string escape character in SQL. However, such code is very poor and open to attack because if userName comes from a user input, the user can inject additional quotes by supplying something like:

a' or 1=1

When reconstructed by the deficient code, the SQL statement becomes:

SELECT * FROM users WHERE name = 'a' or 1 = 1;

If that statement was used for some kind of authentication mechanism, it would always be true and the system might open content that was not intended for the current user.

In the case of the UN web site, one of the original Web pages that was hacked can be viewed here.image

The titles for the latest speeches were changed to “Hacked By kerem125 M0sted and Gsy
That is CyberProtest Hey Ýsrail and Usa
dont kill children and other people
Peace for ever
No war”.

The Web site was probably hacked through one of the speeches Web page, which have a URL as follows:

http://www.un.org/apps/news/infocus/sgspeeches/statments_full.asp?statID=105

As you can see, this kind of hyperlink takes the parameter:

statID=105

Well, by simply appending a quote to this URL, anyone was able to access their database with the security permissions of the Web application. So, the hackers were able to insert (or update) different speeches that are supplied from the database by concocting their own SQL statements.

It now seems that a filter has been installed on their server, because if you try this URL, you connection will be reset and you will not reach their Web server. Some basic Web security filter will filter out URLs that seem suspect and URL with quotes in them are rarely used and stopping these can mitigate these sort of attacks.image

This might stop this attack, but if they had data entry forms with similar holes, they would still be open to attack. URL filtering would not stop these. You might put a plaster to try to protect a Web site, but in this case, the plaster has not been applied to other Web sites. For example, at this very moment, other Web sites are open to the same basic amateur holes. For example, the UNEP (United Nations Environment Programme), has also been defaced, probably through the same techniques.

Good security implies different layers of security. At the entry point of the network, you need good firewalls with filtering and intrusion detection systems and fully patched systems. But if the application opens up the database through programming holes, these are not worth much.

What’s more damning for an institution or a company that faces humiliation through such public attacks is that basic programming techniques would easily have avoided these holes in the first place:

  1. For performance and security reasons, it is recommended to use prepared SQL statements instead of dynamically building strings. All modern database engines support prepared statements.
  2. As an alternative to point #1, string inputs could filter escape characters. However, since most databases support multi-byte character sets and different character set settings, it can be quite easy to still leave some character escaping holes opened. If you need to do this instead (you don’t!), you would need a model that ensures that all input strings are correctly filtered. Leaving this task to the Web page developers will certainly leave some holes opened.
  3. There is a debate about using stored procedures, but by parameterizing inputs and forcing types, user inputs can be correctly filtered. Evidently, to avoid most holes, you would still need to use prepared statements to call stored procedures.
  4. A good object-oriented approach will also close some holes. In the example of the UN, the parameter is an integer corresponding to the identifier of a record. A typical entity class would necessitate to use integer properties and lookup methods that only accept integers to search by identifier. Therefore, by using strong types and forcing type conversions, this particular attack would not have happened.
  5. 3-tier architecture will isolate the database access functions in separate layer. It does not stops vulnerabilities, but having the database facing code isolated helps to avoid adding new vulnerabilities.
  6. A model-view controller architectural pattern can further isolate the interface from the database.

In Web applications and Web sites, many more vulnerabilities can be made possible though amateurish programming:

  1. Incorrect use of hidden form fields. In HTML forms, hidden fields in forms can be quite useful. When used by amateurish programmers, they are dangerous. For example, I once stumbled on a shopping cart that used hidden fields for the prices of the products sold. By simply saving the HTML of the page to my desktop and changing the prices, I could have ordered the products with my own user-defined pricing injection! Fortunately for the company, it was before publishing of the web site and they called me to check the Web site. When it took me 5 minutes to find the hole and came back to them with my findings. The next thing I heard was that the developing company was fired and I would doubt they got paid.
  2. Incorrect use of cookies. When a Web application relies on cookies, it must be very careful about what is stored in the cookie. For example, a poorly developed web site could simply store a user id in the cookies for a “remember me” option. Then, a malicious user might change that identifier to something else and even maybe change his access to a user that has administrative access to the application. In that case, storing the identifier directly is a very bad idea. To at least avoid impersonating other users (without access to their computers), a secret random-like key could be stored. Still, someone with access to the computer could still do damage. Because of this, pages that give access to or allow to update sensitive information should be protected by asking the user to be authenticated, independently of a “remember me” option. There are a lot of different strategies to mitigate the risks of cookie usage.
  3. Code injection. Even if your application prevents SQL injection holes, it might still be vulnerable to certain types of code injection attacks if you allow user inputs. For example, with community features like discussion forums, the application needs to filter inputs to avoid Web site defacement through injection of HTML or Javascript code.

Application security is a serious matter and is more complex than what I can go in depth in this blog. I’ve noted a couple of beginner’s mistakes, but there is much more than this.

More often than not, especially for small businesses, Web projects will go to the lowest bidders that are not necessarily professionals in the domain. This approach can be risky. I wonder how much the UN paid for their Web sites… I wouldn’t think they would go to the lowest bidder. But, even when paying the right price, you can get more than what you bargain for. It is important to correctly research the credentials and experience of the developers that will do the coding.

An institution like the UN would at least need to get an independent consultant that know the right questions to ask the developers to verify that they do apply the best practices in their development.

SIMILE Timeline: Manually Adding Events

28 Jun

Introducing SIMILE Timeline’s documentation

A few months ago, I began to use the SIMILE Timeline JavaScript control for a project. It’s really a handy control to visually show – you guessed it – a timeline of events.SIMILETimeline

However, there’s not a lot of documentation for it. As you can see on the documentation page, in pure Open Source spirit, you will see many “for now, read the code” references for parts of the API where the documentation is the source code. There’s also a Wiki documentation page where you can find a bit more information, which is handy to find a few more things, like how to change themes.

Because of this, I though I would write a few posts with a few tips and tricks I discovered. Now, that the introduction is made, let’s start with my first post…

Why would you want to manually add events in the Timeline?

One thing you might want to do at some point, is to use Javascript to manually add events to the Timeline.

There are methods to load data in a Timeline through XML with the Timeline.loadXML method, as described in the How to Create Timelines tutorial. Also, for more efficiency over the wire, you might discover and want to use the Timeline.loadJSON method. So, why would you want to add events manually?

Well, the are many reasons why you might deem this necessary and most of these are for efficiency reasons:

  1. You already loaded the Timeline through XML or JSON, but you want to add new events to the Timeline without refreshing the Web page. You want to use your AJAX skills, don’t you?
  2. You are already using a JSON (or XML) Web service for other things on the Web page and you don’t want to make a second call to load the Timeline.
  3. You want to process your JSON’s Web service data to, for example, generate the HTML for the pop-up through JavaScript from the data instead of sending the whole HTML thru the wire.

How to manually add events in the Timeline?

 It’s not that hard to add an event manually. When browsing the source code, you will see the definition for a new event in sources.js. The constructor is Timeline.DefaultEventSource.Event.  It accepts the following parameters: start, end, latestStart, earliestEnd, instant,text, description, image, link,icon, color, textColor.

Knowing this, here’s some code to generate 50 random events up to 20 days in the past or the future. Compared to the code on the official tutorial page, the important differences are in bold.

<html>
  <head>
    <script src=”http://simile.mit.edu/timeline/api/timeline-api.js” type=”text/javascript”></script>
    <script>
var tl;
function onLoad() {

  var eventSource = new Timeline.DefaultEventSource();
  //Generate 50 random events up to 20 days in the past or the future
  for(var i=0;i<50;i++) {
      var dateEvent = new Date();
      dateEvent.setTime(dateEvent.getTime() + ((Math.floor(Math.random()*41) – 20) * 24 * 60 * 60 * 1000));
      var evt = new Timeline.DefaultEventSource.Event(

         dateEvent, //start

         dateEvent, //end

         dateEvent, //latestStart

         dateEvent, //earliestEnd

         true, //instant

         “Event ” + i, //text

         “Description for Event ” + i //description

      );
      eventSource.add(evt);
  }
  //create the timeline
  var bandInfos = [
    Timeline.createBandInfo({
        trackGap:       0.2,
        width:          "70%",
        intervalUnit:   Timeline.DateTime.DAY,
        intervalPixels: 50,
        eventSource: eventSource
    }),
    Timeline.createBandInfo({
        showEventText:  false,
        trackHeight:    0.5,
        trackGap:       0.2,
        width:          "30%",
        intervalUnit:   Timeline.DateTime.MONTH,
        intervalPixels: 150,
        eventSource: eventSource
    })
  ];
  bandInfos[1].syncWith = 0;
  bandInfos[1].highlight = true;
  tl = Timeline.create(document.getElementById(“my-timeline”), bandInfos);

}

var resizeTimerID = null;
function onResize() {
    if (resizeTimerID == null) {
        resizeTimerID = window.setTimeout(function() {
            resizeTimerID = null;
            tl.layout();
        }, 500);
    }
}
    </script>
  </head>
  <body onload=”onLoad();” onresize=”onResize();”>
     <h1>Creating Events Manually in a SIMILE Timiline</h1>
     <div id=”my-timeline” style=”height: 150px; border: 1px solid #aaa”></div>
  </body>
</html>

You can see a working example here.

Tip: Get Vista’s “Open Command Window Here” on XP

20 Jun

Sometimes, we don’t think about the simplest tricks.

Steven Harman has a new post with some tips for developing with Visual Studio.OpenCommandWindowHereVista

One cool option Windows Vista has, is that in Windows Explorer, when you right-click on a folder, the context sensitive menu gives the “Open Command Window Here” option. It does what it says: you open the Command Prompt with the current directory set to the one you just clicked.

A commenter, earljon, explains how to enable the same option in Windows XP. It’s one of those things were you ask yourself why you didn’t do that sooner! Here’s his explanation:

On the Command Window context part, some of us don’t already have this but one can manually add a context menu for command prompt by following simple steps:

  1. On Windows Explorer, Tools/Folder Options.
  2. Click the tab File Types.
  3. Find the File Type “Folder” and click the Advanced button.
  4. Click the New button, and type “Open Command Window Here” (no quotes) on the Action text box and type “cmd.exe” as the application that will perform.
  5. Close all the windows and new context menu is created.

Very useful when you need the Command Prompt.

Disclaimer: the picture included with this post was ripped from Steven Harman’s post.

ASP.NET AJAX: How to call client-side Javascript once an UpdatePanel request is over

1 Mar

The UpdatePanel control in Microsoft’s ASP.NET AJAX, is a good way to save some time when you have simple AJAX programming needs to post data to a form without refreshing the Web page.

However, once the asynchronous post has been executed, you might want to execute some Javascript after the request. In my case, my form’s controls where to be used to control a Google Map. Every time the form was updated, I wanted to refresh the map to reflect the data changes.

The trick is to add an “end request” handler to the request manager using:

    Sys.WebForms.PageRequestManager.getInstance().add_endRequest(EndRequestHandler);

where EndRequestHandler will be your handler function. In this function, you can also detect errors.

Here’s a simple example of a form with 2 TextBox controls where you enter text into one textbox and the server returns the length of the text in the second textbox. Then, when the server is done, the Javascript handler is called to display an alert.

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="DemoJScriptUpdate.aspx.cs" Inherits="CharterWeb.DemoJScriptUpdate" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">
    protected void txtDataOnChange(object sender, EventArgs e) {
        txtLength.Text = txtData.Text.Length.ToString();
    }
</script>
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>Client-side Javascript call after an UpdatePanel asychronous request</title>
</head>
<script type="text/javascript">
function EndRequestHandler(sender, args) {
   if (args.get_error() == undefined)
       alert("Your text has: " + document.getElementById("txtLength").value + " character(s)");
   else
       alert("There was an error" + args.get_error().message);
}
function load() {
   Sys.WebForms.PageRequestManager.getInstance().add_endRequest(EndRequestHandler);
}
</script>
<body onload="load()">
    <form id="form1" runat="server">
    <asp:ScriptManager ID="_scriptManager" runat="server" />
    <div>
        <asp:UpdatePanel ID="UpdatePanel1" runat="server">
           <ContentTemplate>
              Write something: <asp:TextBox ID="txtData" runat="server" AutoPostBack="true" OnTextChanged="txtDataOnChange" /><br />
              Server says the length is: <asp:TextBox ID="txtLength" runat="server" AutoPostBack="true" />
           </ContentTemplate>
        </asp:UpdatePanel>
    </div>
    </form>
</body>
</html>

If you want to learn how to have more control over error handling, I recommend reading: “UpdatePanel: having fun with errors“, an excellent post by Luis Abreu.