Archive for the ‘interface’ Category

Three-way CSS-only selector

Thursday, February 11th, 2016

I was at the Slovenian CSS Meetup yesterday where I did a short talk on Quantity Queries. That’s a name given to a technique where you use pseudo class selectors to discern how many elements are inside a certain element – for example :first-child:nth-last-child(4) {} will only select the first child if there are exactly 4 elements. If you group that with the general sibling selector ~, you can also get all the other elements.

The idea of quantity queries has been around for a year or so and even though at first glance you might say “We’ve got flexbox for that now”, you’d only be right in certain cases. The thing that quantity queries bring to the table is the idea of being able to change the styling depending on the number of elements, which I guess people currently solve either on the backend or with javascript.

But that’s not the main reason I’m writing this – it’s the last talk of the night where a three-way selector solution was presented by Gorazd. He created a CSS version but had problems with the smoothness of the animation as he didn’t know where the selector was before the selection to move it to the selected position after a user interaction. He resorted to using javascript that basically only did some class switching. This immediately gave me an idea that a sibling selector could be used for that if the indicator had the same parent as the inputs and was positioned after them in the code. And today I made a proof-of-concept solution I’m calling “the three-way CSS-only selector”.

It uses three radio buttons, so the form is perfectly submittable, the labels also select properly, it animates properly and does not use javascript. It’s only been tested on the browsers I have on my Mac, so I can easily see it breaking in IE or mobile browsers – if anyone wants to fix that please go ahead and ping me to add your solution to this post. You can also check the solution on JSBin.

Form protection

Friday, August 5th, 2011

I’ve seen a discussion recently on how to protect your forms from spammers/bots that come and fill the forms to either fill your database with crap data or fill your page with porn links. When I read the answers I figured out that none of the people read the amazing article I did years ago, so I decided to try to remember what it said. So, a big fat disclaimer: I read this in an article somewhere and I don’t remember where. If you know the original article please post it in the comments, I’d love to link to it, I bet it has way more info than this one.

The problem

Almost all websites now have some forms on them, some of them are contact / registration forms, others use the data submitted and display it on the site itself (comment forms). But letting others submit data to your site/database opens you to all sorts of attacks. If you actually show the content of the submitted form, you’ll get a bunch of spammers posting comments with lots of links. If you only store data and not show it anywhere you’re still at risk – if you don’t notice your disk can fill up, your database may grow beyond its limits,… So what we want to do is to prevent bogus form posting.

Spammer approach

If you think about writing a spam-bot that will try to spam as many sites you possibly can you have two basic approaches.

Record / replay

This is a very simple approach – you use a person to submit the form, preferably with something that looks like real input and record the request made. Then you hand that data off to the bot, it changes some content and tries to resubmit it.

Automation based on heuristics

I wanted to say AI, but it really isn’t. What it is is a set of simple rules and randomized values that the bot thinks might trick your site into accepting the submit. Let’s say you have three fields, two are inputs with field names “name” and “email” and the third field is “comment”. A simple script can fill these with “valid” data and try to submit it.

Human entry

By far the simplest, but also most costly for spammers. Go on Amazon Turk or whatever other service, send a link to a Google Spreadsheet and have people manually enter the stuff into your forms. This is the source of “Sorry, this is my job” endings to spam comments.

Popular solutions

Turing test

Add a field to the form that the user must fill with something that humans can do easily, but machines can’t. The biggest group here are Captchas (display an image with distorted characters, possibly an audio link that reads out the same characters, and have the user somehow figure it out and write the solution), but there have been others, like a “Human?” checkbox, or “3 + 4 =” fields, “Is this a kitten?” with a pic next to it.

2-step process

Supposedly by far the easiest way to do this is by introducing a 2-step process. After the initial submit, you get back a preview of the submitted data, possibly with a checkbox that says “Is this correct?” and another submit button. Robots are usually not good at following through and thus don’t actually submit the content.

Both solutions have an impact on user experience. With Captchas it’s sometimes really hard to see what they are and even if they have a “different image” link, it just seems like the owner of the site wants to make your life hell before you can submit your data. The other challenges might be easier on the user, but also easier to figure out if you’re being targeted by bots. The 2-step process works great for comments, that usually don’t have an edit link, so it might actually be good for user experience if done right (not Wikipedia style), but are less appropriate on other types of forms.

Protect yourself differently

These are the techniques that should prevent most bogus form entries from random passing bots, except “Human entry” – no protection for that, even though Captchas try hard. There is not much you can do when you’re targeted…

Honeypot field

Use this field to trick autoguessing bots to submit something in a field you know should be empty.

  • Add an input field to your form with a regular name (state, maiden-name,…) that does not appear on your form otherwise.
  • Use a label that will clearly communicate that it needs to be empty.
  • Hide it with CSS, preferably not by adding class=”hidden”.

If the form post includes content in this field discard it and redirect back to the form. The trick is to make sure the bots don’t figure out this is a honeypot, so use valid looking but nonsensical classes…

Date field

Use it to prevent resubmit of data too far from the creation date. Allow users a few hours to post the form.

To prevent manual modification you can use either proper encryption (symetric or asymetric) that will allow you to decode it on form post or use this date in combination with the onetime token.

Onetime token

Use this field to prevent replay of request data. If you can, save it into the database.It is a good idea to make this token in a form that it cannot be faked (say one character changed ad you have a valid one). This can be done with hashing data or encryption.

This one can be as tricky as you want. What I usually do (disclaimer: I don’t know much about encryption so this might be crap advice) is use a plain datetime field with the onetime token generated from IP address, UserAgent and the date field with HMAC. There is no need for this token to be reversible – I can recreate the same thing with the data from the form post and check if it matches.

When using these techniques make sure you take care of the user experience. If you detect a problem on what might be valid user input (“timeout” on the date field with a non used onetime token, wrong onetime token from an ip change by the service provider), you might want to display a second step from the “2-step process”. Whatever you do, don’t call your users spammers or bots – be nice, bots don’t read the text anyway.

Did I miss anything?

I know of no plugin that uses all of these techniques, but I haven’t really looked for it. What I do know is that I don’t want to ever use a Captcha, cause it often keeps me out, and the 2-step process in just too weird sometimes. Hope this helps. And again – if you find the original article (must be some 5 years old now at least if not more) or have any other solutions you use or endorse, do leave a comment.

Speaking about the web of data

Wednesday, February 25th, 2009

Today at 19:00 CET I’ll be speaking at a local web meet-up about the web of data. There’ll be a live feed of the talk available and since I’ll be speaking in English you can tune it. This is a quick translation of the abstract posted on Slovenian sites:

Numerous services are emerging on the web that provide data in a computer friendly form through APIs, microformats, feeds,… Even your blog is actually a database as it syndicates its content via feeds and new posts trigger a ping you can subscribe to.

This fact opens new ways of collaboration – so called mash-ups, but this isn’t really a new concept. What’s new about it is the fact that we don’t use this word anymore as all the new services are some sort of a mash-up leveraging existing services. But accessing data is not the only way to leveraging these services – it’s becoming increasingly easy to create an application that lives in other applications without their approval through browser extensions and bookmarklets.

Marko Mrdjenovič from Zemanta will talk about what you can do to make your site more mash-up friendly and why that’s becoming increasingly important. As a developer I’ll also present what options you have and give a few tips on what to do and what to avoid when developing these kind of apps.

If you have any questions during the talk use twitter to tell me and I’ll try to answer them. Or put them in the comments.

Update: The video is now online. It’s in English so go watch it and tell me what you think.

Reblog this post [with Zemanta]

Getting into the graph

Sunday, January 11th, 2009

Designing forms online is a hard job. What you need to do is find the right balance between the consumer experience which is generally worse as the number of fields grows and the amount of content you or your employers want to get from the user in a single form. With this you’re defining the conversion rate of a form – less fields will, ceteris paribus, give you a higher conversion rate – which means that you should strive to have less fields in a form (although recently I saw an argument on twitter that you want for people to put some effort into forms to avoid registration from people who will never use your service1). Having many fields in a form has two major effects – users cannot easily scan the form to see if they’re actually willing to give away all the information that you want and they don’t want the form to take a lot of time. Since you sometimes can’t lower the number of required fields you can try to lesser the pain of filling them – by auto pre-filling them.

This is especially true of contact/feedback and registration forms. On contact forms the only thing consumers want to give is the message, on the other hand what you want is at least a name and a way to contact them (the others in your company might want more, but that’s a different storypost). The registration form is somewhat similar in the way that you can make it really simple by just using email and password fields but then again it’s nice if you have a way of addressing your users other than an email address and if your application is at least a bit local you also want their location.

The other side of the story is obviously that consumers don’t want to fill the same forms all the time. As time passes they’re minds are saying “Not again…” which is not that far enough from “Why can’t they get it from some place I already use”.

Into the graph

There have been a lot of attempts at solving this issue of repetitive entering of same data. There’s a way to do it with OpenID, which unfortunately isn’t ready for mass use since not many people use it. Other possibilities are public APIs of numerous services that allow you to get at least some user information if you have some data about them.

One of these APIs is Flickr‘s as it allows access to user information if you have the user’s email through flickr.people.findByEmail and then flickr.people.getInfo as is neatly demostrated by huffduffer which uses it to retrieve your Flickr avatar.

What you have now is the user’s name, “preferred” username, location and avatar (which you might have had already if the user is registered with gravatar).

The graph

Social Graph Platform Wars
Image by davemc500hats via Flickr

The other place where you can get decent information about the user is Google’s SocialGraph API. With it you get lots of services from which you can get all kinds of public information about a user. The problem with this API is that you first need a relevant entry point which must be a URL that the user owns. This can be a Flickr user URL (that you have if you successfully completed the previous step) but these don’t always produce very good results.

What seems to produce better results are twitter URLs – the only problem wasis how to get one. An easy way to get the users twitter URL is demonstrated in a blog post by Chris Heilmann. This will get you all the information you get from Flickr for all the users that are currently logged in to their twitter account. Seems that this is not possible anymore!

If you’re still not getting anything you can still ask a user for a URL – be it their blog or any social network service account. Or you can let her log in using other services that will give you a good starting point, like Facebook Connect or OpenID.

Data from the graph

What SocialGraph gives you is a list of services the user is registered with. You can also get their list of friends – if any of them are also users of your service you can suggest they also connect on your service. You might also get to know whether they use OpenID and suggest them that they use that login to log into your service too. Or you might be able to figure out what their blogs are – especially when they’re claimed on Technorati.

This information can also help you get in touch with your users as you can automatically contact them on services where you also have an account, like Facebook, twitter, friendfeed and others.

The thing is that once you have all this information you should be able to get all the public information the user has exposed on any of these services. And you can use this information to help the user by pre-filling forms or use it in other ways that a user might find helpful, but not spooky.

What you shouldn’t do is use this information in ways that might scare the user. For example if you can get the birth date from any of the services, don’t hide the fact that you did – offer a form to fill the date and prefill it. This way the user won’t be spooked if you send them a happy birthday note or you greet them with a happy birthday note.

This form should get your Twitter data and then get some of your services via Google’s SocialGraph. It’s all nicely wrapped in an hCard.

  1. Sorry I forgot your name as I’m not yet used to bookmarking twitter statuses. back
Reblog this post [with Zemanta]

jQuery window.name transport is out…

Wednesday, October 1st, 2008
JQuery intermediate site

Image by Phillie Casablanca via Flickr

After a week of mostly testing and fine-tuning the code I finally released the windowName transport plugin for jQuery. You can get the plugin here but I suggest you first check the plugin page.

I need help testing

If you have an obscure browser / OS combination that is supported by jQuery I urge you to test the plugin. There are no good test pages yet so my temporary test page will have to do. The test page POSTs the querystring passed to it to a nonlocal domain and should open a JavaScript alert with the same querystring plus php=true.

On a sidenote – I figured out that the page looks better without the background images. So I changed the theme – let me know what you think.

Reblog this post [with Zemanta]

Discovering Greasemonkey again

Friday, August 15th, 2008

Meissner effect: levitation of a magnet above ...Image via Wikipedia I’ve been rediscovering the joy of Greasemonkey scripts lately. For those who don’t know, Greasemonkey is one of the best extensions for Firefox ever made (the other being Zemanta of course:) that allows you to run JavaScripts on specified pages. This doesn’t really mean much to the non-technical crowd, but to us geeks this means you can do almost whatever you want with the page. As I make more and more of these I decided to share them here.

For my Slovenian readers

  1. Finance unfixed is a script that will unfix the header of finance.si. This means the header will scroll and you’ll get more space to read the article.
  2. RTVSlo OI is a script that will remove the header from the OI page on rtvslo.si again leaving you with more real estate for reading.
  3. Delo is a script that will help your eyes when reading delo.si news site since it’s small default line-height might make them hurt.

Developers

  1. JSLint highlighter will help you read the JSLint results. If you write JavaScript and don’t know what JSLint is you should go check!

How to work it

Well first you have to have Greasemonkey installed. After that installing a user script should be as simple as a click of a link. When a script activates you’ll see a little green box that will say ‘Greased’ in the top right corner. Clicking it will toggle the script – either it’s on and active (green) or off and the page looks as it would in the first place (red). You can also toggle the script with alt+g.

Reblog this post [with Zemanta]