Sunday, June 10, 2012

Pygame Google Summer of Code, 2012.

Thanks to the students, and mentors donating their time, along with the PSF, and Google, the following pygame related projects are ongoing over the summer.

"Pygame: GUI toolkit" by Sam Bull (sambull), mentored by Mike Fletcher(mcfletch) and with backup mentor Robert Deaton (masquerade). (Proposal | Blog)

"Pygame: Improved Sprite and Scene system" by Sagie Maoz (n0nick), co-mentored by Robert Deaton (masquerade) and Katie Cunningham (kcunning). (Proposal | Blog)

"Easy networking in PyGame" by Szymon Wróblewski (bluex), mentored by Rene Dudfield (illume) and with backup mentor Mike Fletcher (mcfletch). (Proposal | Blog)


Some project updates:

Sagie wrote a tutorial on pygame.sprite.Dirty and pygame.sprite.LayeredDirty, as well as a blog update on his progress.
    http://dotfile.n0nick.net/quick-dirty-using-pygames-dirtysprite-layered
    http://dotfile.n0nick.net/gsoc-journal-weeks-1-2

Szymon wrote a blog post on the networking project:
    http://pygame-networking.blogspot.com/2012/06/gsoc-journal-introduction.html

Sam wrote a post on the "SCG" beta release of the GUI project:
    http://blog.sambull.org/sgc-0-1-4-beta-release

Sam has also written to the mailing list asking for feedback on his work.
    https://groups.google.com/forum/?fromgroups#!topic/pygame-mirror-on-google-groups/AQiDPF_rINo

Sagie has also been getting into some conversations on the mailing list, and in the irc channel about the sprites project.
    https://groups.google.com/forum/?fromgroups#!topic/pygame-mirror-on-google-groups/KhaV8V6o4Js

Sam, Szymon, and Rene started on a little game for pyweek to be used as an experimental sandbox for testing out gsoc project ideas.
    https://bitbucket.org/pygame/pygamegsoc12


Wednesday, June 06, 2012

Internet protocol 6, 6, 6.

June 6th, 2012 is ipv6 launch day. 
http://www.worldipv6launch.org/


You can now go to http://www.pygame.org/ with version 6 of the internet protocol.

Tuesday, June 05, 2012

Why Firefox 13 'load tabs on demand' is bad UX.

With the new firefox 13, on start-up it does not reload all of the tabs at once.

Theoretically this means firefox loads faster.  Since it only needs to load one website when you restore, not all of them.

This is a great example of a UX/UI app experience that seems good for users, but is in fact bad.  This comes up quite often when optimizing applications, and I have even done this style of optimization in the past.  So I'm using this as a case study in why doing this is not good from a UX perspective.

The Scenario.

I have 8 tabs, and I'm using most of them.

Old firefox behaviour.

  1. Firefox loads, I go away whilst it loads itself, then loads all 8 tabs. I wait.  It takes a while to load - but some stuff can be loaded at the same time, in parallel.  If they are fast pages it is pretty much instant, and I can get to work.
  2. If they are slow pages, then I have to wait once until they are all loaded.  I can go off and do something else until the loads are done.  Or perhaps I can use one of the fast loading pages, whilst the slow ones load in the background.  Browser usage is sluggish, and not all that responsive - but usable.

New firefox behaviour.

  1. Firefox loads, I go away whilst it loads. I wait.
  2. I come back to see the firefox home page.
  3. I have to find the "Restore" button.
  4. I click "Restore" button.
  5. One tab starts reloading, I wait.  I go away to do something else.
  6. I come back, because I need Tab 3.
  7. I click on Tab 3.  It reloads, and I wait.
  8. I go away, and come back to Tab 3.
  9. Later I need to use Tab 5.  I come to browser, click Tab 5, it reloads.. I wait.
  10. [Repeat waiting 5 more times]...
  11. I wait.
  12. I wait.
  13. I wait.
  14. I wait.
  15. I wait.
The other option is I click all of the tabs to get them loading... but that takes longer than the old firefox behaviour, and requires a lot more effort on my part.

Conclusion.

From the above scenario, you can see a lot more waiting with the new firefox 13.

I think it is a bad 'solution' they have chosen.  This is also a good example, of why combining the wait times for users is usually a better option than making them wait multiple times.

The best solution is to make website loading quicker, or more responsive whilst other tabs are loading.  Perhaps by giving background tabs a lower priority.  Or just go back to the old behaviour... [starts hunting for the correct about:config option].

Their solution is probably ok for the 50+ tab using people though.  For that use case, there are probably better heuristics though.  How about, reloading say 8 tabs at once, but restoring the 8 most used tabs, and leaving the rest to load on demand.  Or something else... ?

Sunday, June 03, 2012

SQL Injection via field names, and table names.

About a year ago I had to implement a system where the table name could be configured for an application.  Why would you want to do that?  Lots of reasons really, like if you have a table generator via a web interface.  In this case, the system integrates with other systems, and users need a way to specify where the data would go in an existing database.  So I merrily went ahead to try and put the table name in a prepared statement... but ERROR!  Unfortunately the sqlite database does not do table names or column names via prepared statements (like postgresql does for example).  The documented solution by sqlite is to escape them correctly with the provided functions.  Unfortunately python does not expose these SQL escaping functions - since most people should be using prepared statements.

Here are some WONTFIX, closed, invalid bugs also mentioning table names, and column names not being a problem.  One of them is six years old.

(closed wontfix) http://bugs.python.org/issue11685
(closed invalid) https://code.djangoproject.com/ticket/1474
(closed invalid) https://code.djangoproject.com/ticket/14991

Python and Django don't really consider this a vulnerability in themselves, but a problem in users code.

However, I still think it is something people should still be aware of.  Especially if you are taking user input to generate your table names, or your field names.  For those people, it could be a problem unless you are really careful.


SQL Injection with Django (a case study)

I'm going to use the python framework Django as a case study of what to be careful of.  However this advice applies to all python, php, [insert your favourite language or framework] and other SQL using libraries.

This code is used to quote table names, and field names in Django via the mysql db backend.

    def quote_name(self, name):         if name.startswith('"') and name.endswith('"'):             return name # Quoting once is enough.         return '"%s"' % name

Note how there is no database provided escaping of the input?  To protect against SQL injection it should be using prepared statements or an escaping function.

Because Django mostly does things like validate field names, and table names... this turns out to not be a problem in a lot of cases.  Other layers of security in Django protect it here.  This isn't an "OMG free Django p0wny!" bug, but a fairly niche bug if you do something wrong in your own code.

An example of how you can inject SQL because of quote_name is here, where the command takes a table name:
django-admin.py createcachetable 'myinjectedtable` (id INT) select id from users;create table `thecachetablename'

This SQL injection could be a problem if you are getting the cache table name from user input somewhere else, and not validating it first.

quote_name (as one of the places that does it wrong) is used in public 3rd party code, and internally within Django.  It is not a private method, since it does not begin with '_' or '__'.  There are places where a string can be supplied from outside of django (either through command line, or through other APIs used, or from a file).  It says that the db backends are responsible for quoting the field names (eg, the Q.__str__ method).

The Django book says:
"Thus, if you need to, say, dynamically construct a list of tables from a POST variable, you’ll need to escape that name in your code. Django provides a function, django.db.connection.ops.quote_name, which will escape the identifier according to the current database’s quoting scheme."

Another example where you can inject SQL...
MyObject.objects.extra(where=['"name"="SomeName";CREATE TABLE qwer (id int) select id from users'])

The Django documentation warns to be careful about this function.  However there is no documentation on the extra method about escaping field names, or table names.  Should probably add a warning there: https://docs.djangoproject.com/en/1.4/ref/models/querysets/#extra

You should be careful using input from untrusted places where you'll use it for table names, or field names.  Luckily this is not done very often by lots of people.

What can we do to fix table name SQL injections?

  • Use prepared statements if db backend allows,
  • ... or escape it correctly(as documented by each DB engine) when using prepared statements are not possible.
  • Disable multiple statements in the db connect, so even if something gets through the damage is limited.
  • validate the input where possible (for example, why would a table name need to include ;  or DROP DATABASE?)
  • document dangerous calls to explain how to escape values correctly in your database abstraction.
Some more expensive to do fixes are:
  • have automated SQL injection tests.
  • use the database provided permission systems. So front end code only has permissions to do what is required, and admin code can only do what is required of it.