Me
About
Gallery
Company
Girl


Projects
Ruby on Rails
Basecamp
Highrise
Backpack
Campfire
Ta-da List
Writeboard


More
Feed
Archives

April 04, 17:05

Finding the shortcut and using it effectively

Charles Miller examines the getter/setter syndrome in Java1 from a usage (rather than the normal construction) perspective and devices a shortcut. Instead of using individual access methods, he proposes the unified set_properties that takes a hash of attributes and automatically assigns them on the object instance. Unfortunately, he fails to see its uses and discards the idea with a clever Simpsons reference (we like those).

That's a shame because he had the right idea.

In constructing Rails, I reached exactly the same shortcut—albeit with slightly more natural Ruby-like semantics by using a signature of Object#attributes=(attributes). More importantly, I found an extremely handy use for it. Passing data from the view to the model in a MVC-style application usually means doing it twice. In the view with input tags as part of a form and in the controller by picking attributes from the request and calling access methods on the model. That's inefficient at best and error prone at worst.

Instead Rails adopts a combination of PHP-like input names that turns form data into hashes and the unified attribute assignment to do as follows:

<!-- The view -->
<form>
  Name:    <input type="text" name="user[name]">
  Email:   <input type="text" name="user[email]">
  Website: <input type="text" name="user[website]">
</form>
 
# The controller action
def create_user
  user = User.new
  user.attributes = @params["user"]
  user.save
end

As the form is submitted by the user, the Rails controller turns user[name], user[email], and user[website] into a hash that contains the name, email, and website as keys and the user supplied input as values. This hash can be accessed through @params["user"] from the action method.

Now the clever part is that the name, email, and website keys from the form maps to attributes with accessors on the model. This relieves the controller of a per-attribute knowledge responsibility, which allows us to add new fields on the view and model without changing the controller.

Actually, we only lavishly spent three lines in the controller to make it slightly easier to follow each step separately. Normally, it would likely look as follows (if there's to be no validation of the attributes):

def create_user
  User.new(@params["user"]).save
end


Relief from per-attribute knowledge responsibility
In fact, the Rails framework goes even further in its attempt to relieve as many layers of per-attribute knowledge responsibility as possible. In your average web-application layer stack, it's not uncommon to have per-attribute knowledge spread across five concerns:

  1. The form: One input field per attribute.
  2. The action: The request is picked for attributes and they're assigned to the model.
  3. The model: Each attribute is specified on the model with a type and boiler-plate serving of accessor methods.
  4. The ORM: Column names are matched against model attributes and a type-conversion specified.
  5. The database table: All persistable attributes in the model are given a column with a name and a type.

Everytime the model needs to evolve to either add, remove, or change attributes, you have to change each concern in a similar but distinct manner to move forward. That's an extremely cumbersome, time-consuming, and—again—error-prone dance of repetition.

Rails allows you to cut all that clutter in between the form and the database table and only work at the ends when the model needs to evolve. The action, model, and mapping steps are all handled by building on the knowledge already present in the form and in the database table.

So let's imagine that our lovely user from the example above needs to also be identified by a instant message handle. In Rails, this would require the following changes:

  • Addition to view:
    IM: <input type="text" name="user[im_handle]" />
  • Addition to database table:
    im_handle VARCHAR(100)

That's it. Now you're free to enjoy the rest of the Sunny day on the lawn with a drink and a hat while your lesser fortunate friends is caught in the toils of per-attribute knowledge spread across the entire layer stack. So much for low coupling, eh?

1. That onerous expenditure of 8-12 lines boiler-plate access code per attribute in stark contrast to Ruby's use of just 1 line for all attributes. An inefficiency that it shares with C#.


Challenge by Florian on April 04, 22:51

As handy as it might seemt to directly transfer input data to business objects, when you do it like in your example above you allow users to edit ALL properties of the user object. just something to consider..

Challenge by Tomas on April 04, 23:14

I'd like to hear what David has to say about what Florian says.

Challenge by David Heinemeier Hansson on April 04, 23:39

I've found that to be what I want in 9 out of 10 cases. When it's not what I want, I'll either strip it out in the controller or as a validation on the model. This goes to the core of Rails. Assume the common case, make the odd case possible.

But I hear you. Using Rails, or any framework, isn't an invitation to leave the head on the counter. You still have to think.

Challenge by Tomas on April 04, 23:48

What if a user property one would like to view/set isn't in the user table, but is, perhaps, in another table (say, for instance, in the company table (because only the id, not the name, of the company is stored in the user table)), or is a read-only figure such as user.articles_posted, or something completely different which isn't a single read/write attribute stored in the user table?

How would one handle these kind of fields with Rails?

Challenge by Charles Miller on April 05, 0:05

Yes, I'd have the same worry about parameter-injection attacks. There are some properties on your business-layer objects that you really don't want the user to change, and it's always better from a security perspective to explicitly state what is permitted, rather than rely on remembering what is not allowed.

It's the same sort of problem that PHP runs into (or at least was prone to when I used to code PHP) because HTTP parameters are assigned directly to local variables in the script: you have to be very careful to initialise local variables explicitly, or an attacker can hijack them.

Conceptually, I'd also prefer type-coercion to happen at a higher level so my business objects only deal with their natural types, but that's a matter preference.

Challenge by gabriele on April 05, 0:17

I'm not sure I understood.
does attribute=(hsh) work like this:

def attribute=(hsh)
hsh.each do |key,val|
self.send(key+"=",val)
end
end

?
Cause I believe that if it works like this there is little chance to hijack things.

If User has more attributes it sounds reasonable to strip them in initialize() and even if you don't the worst thing you can do is call an accessor methods that must exist, and should check it's argument anyway, ain't it ?

OTOH if there is direct raw access a-la eval I agree that it seem little hackish & insecure

Challenge by David Heinemeier Hansson on April 05, 0:35

Rails, in this case the model part of Rails called Active Record, has a wide array choices for representing relationships. There's "has_one", "has_many", "belongs_to", and just lately, we've added a many-to-many link tentatively called "has_and_belongs_to_many" (better names that still match the style of the previous three are much appriciated).

So let's say the user belongs to a company. We'd represent that in an Active Record with the following:

class User < ActiveRecord::Base
belongs_to :company
end

This gives you a number of new methods on the user class, such as User#company (which returns the company object that this user belongs to) and User#company?(some_company) (which is a comparison method for whether the argument is the same company as that associated with the user).

That way, you can traverse the object graph in a natural way, such as user.company.name, which would get the name of the company that the user belongs to.

But no, you can't automatically assign the name of the users company from the view to the model. This would require some direct involvement from the controller.

The point isn't to put the controller out of work. It's to make the laborous default case as easy as possible and other cases doable.

Challenge by Charles Miller on April 05, 0:44

gabriele: it's a matter of access-control. Generally, a User object will only have a certain subset of its fields that are user-changeable, others are maintained by the system, or its administrators.

Say you add a new admin-only attribute. You need to make no changes whatsoever to the admin-accessible actions, but you _do_ need some mechanism to block this attribute from the user. If you miss anywhere, you end up with a security hole.

Security is one of those things where you'd rather not rely on someone remembering stuff like that. It works 99% of the time in a small application, but once the app grows beyond your ability to hold the whole thing in your head at once, you'll inevitably miss something, and end up that day's featured attraction on Bugtraq.

Alternatively, you can rearrange your object model to separate fields by user role, but that's a bit ugly.

Challenge by Tomas on April 05, 0:46

David: Sounds reasonable. So, if one wanted the value of user.company.name in a form, how would that look?

Sorry if I'm pre-empting your revealing of Rails, I can't help myself. Rails seems to swing it in favor of Ruby, instead of Python, for me (regarding web development at least).

Challenge by David Heinemeier Hansson on April 05, 0:47

No, all instance variables aren't exposed to this access structure. Only those fetched from the database. So if you like Charles wants to keep properties on your business objects that's not accessible like this, you can either keep them outside of the table (just as regular instance variables initialized by force or configuration files) or as an associated object, such as PersonStatistics with a articles_posted field.

Challenge by David Heinemeier Hansson on April 05, 0:58

Miller: I guess it depends on the way you structure your application. I've build the domain model for Basecamp to keep user-editable and admin-stuff separate to allow for this type of development without security concerns. But I'm glad you brought it up. This should certainly be part of documentation and guiding in how to build Rails applications.

And no, I don't subscribe to the model of forcing tedious work on the developer in order to make sure he thinks about security. Fowler has a good essay on directing vs enabling that goes to the heart of this issue. You seem to want some directing, Rails wants to be enabling.

Challenge by David Heinemeier Hansson on April 05, 1:01

Thomas: Your template would look something like this

User name: <%= @user.name %>
Company name: <%= @user.company.name %>

That's another cool thing with Rails. You have full access to the object graphs through the template, so you don't have to specifically fetch and assign the user's company to a variable that's accessible to the template. You just find the user, through something like User.find(user_id) (or one of the more security sensitive finders that the Active Record base class provides if user_id is tainted), and make it available to the template.

Challenge by David Heinemeier Hansson on April 05, 1:04

Miller: PHP hasn't worked like that for quite a long time. I can't remember when they turned of automatic assignment, but I think it was around 4.1 or something. I agree that this was probably too far into the land of convenience over security. I remember Rasmus Lerdof disagreed, though.

Challenge by Tomas on April 05, 1:15

David: As far as I know, the @ in Ruby signifies that the object is an instance variable, what implied class is the "user" an instance variable of? Why did you choose this approach, as opposed to the user object being unattached to another object?

Challenge by David Heinemeier Hansson on April 05, 1:40

The template runs off an instance of the template class. This instance is handed a set of variables from the controller which it provides access to via instance readers. The Rails frameworks make it seems like you're just setting instance variables on the controller in order to make them accessible to the template, but that's just for convenience (which goes to the philosophy of doing only enough work to make the framework able to infer the complete meaning).

A sample action method on the controller might look like this:

class UserController < ActionController::Base
def display
@user = User.find(@params["id"])
end
end

Since we haven't specified either a render or redirect, which is what all controllers do, the default case is assumed: render "user/display". In the user/display template, we can now access the user object as in the example I provided above.

Challenge by Tomas on April 05, 2:06

David: Thanks for the explanation, really appreciate it. Keep working on Rails, it seems to be a wonderful framework, right up my alley. I'm looking forward to learning more about it.

Challenge by Charles Miller on April 05, 2:51

PHP was like that in 1999, which was the last time I programmed in it. :)

As to the other point, I consider security a special case. Enabling security is fundamentally more dangerous than directing it, because when it comes to security, there is a vital and painful difference between a system that fails open, and one that fails closed.

Challenge by Charles Miller on April 05, 2:52

Oh, and I apologise for sounding overly-critical here. Rails does indeed look uber-neat.

Challenge by David Heinemeier Hansson on April 05, 12:27

No need for apologies, Charles. I'm glad you brought these issues up. As a direct consequence, I think I'm going to add a "mass_assign_protection" macro or something like it that'll make it really, really easy to guard parts of the business object from being accessible for through mass assignment. So you'd do something like:

class User < ActiveRecord::Base
  mass_assign_protection :rating, :balance
end

That would prevent "rating" and "balance" from being assigned with the attributes= writer.

Also, your concerns make it easier to know exactly how to address the security issues when explaining Rails. Thanks!

Challenge by Luke Holden on April 06, 23:16

David: I would much rather see the reverse of mass_assign_protection

ex:

class User < ActiveRecord::Base
  attributes :name, :passwd, :fullname
end

or what have you.


Mind you, I understand that how you have things now is to cut out the middle layer... and allow changes to the database to only effect changes to the layout... and that aspect is a great one. But I think allowing arbitrary changes by default is a bad idea.

Think of your ActiveRecords as a firewall.

Take OpenBSD packet filters for example. in pf... you generally set the tightest possible filter, and then open things up as needed.

ex:
  block in all
  pass in from any to 192.168.1.5/32


Maybe this could be applied to ActiveRecord... By default you 'block in all'... but you can widen things as needed. ex:

secure business object: (Mind you, this code as is might not be valid)
class BusinessObject < ActiveRecord::Base
  attributes_block_all
  attributes_allow :name, :street
  attributes_allow_prefix :option_
end

This would by default, block assignment to all variables.
It would then allow assignment to name and street...
Then finally allow assignment to any variable with the option_ prefix... which would allow you to add arbitrary options to the table without having to change anything else but the view.

If you wanted your object to allow assignment in a totally 'transparent' behavior, this could also be achived.

unsecure object:
UserPrefs < ActiveRecord::Base
  attributes_allow_all
end

Challenge by David Heinemeier Hansson on April 06, 23:49

I think it's a good idea, but also that it's placing too much of a burden on the Active Record. Acting as the firewall should be the role of the controller. So "mass_assign_protection" would just be really simple shortcut. Yearh, it's bleeding responsibility a tad, but enough to be really useful and not enough to offset the greater picture.

And then if you really want OpenBSD-level security then you probably shouldn't use the mass-assignment method. Or, if you do, implement a before_filter on the controller that makes sure bad variables doesn't make it to the mass-assignment (you can just take them out of the request).

Remember, though, that you're not putting every single model object up for general editing like this. If you want to use this convenience either:

  • Make sure that the model objects you present to the user consists of all safe-to-change attributes (this has been the case for Basecamp more often than not)
  • Use the upcoming shortcut to protect a few variables
  • Keep the sensitive attributes in a separate model-object associated with a link that's not available for mass-assignment
  • Implement an OpenBSD-like firewall on the controller as a before_filter

I think that's a reasonable amount of options for ensuring security without detracting from ease of use by default. But I'm more than open to additional suggestions. Through this discussion I think there should be a good understanding of my position on ease of use vs security.

Thanks again to all that have contributed to this discussion. Keep it coming!

Challenge by Tomas on April 07, 0:08

I understand your position, David, but I must say I agree with Luke's as well. In my opinion, the optimal solution would be if one could select which road to take, by either explicitly stating which attributes are exempt from mass-assignment (or rather easy-assignment as I like to think of it), or the exact opposite; explicitly stating which attributes _are_ available.

Challenge by Luke Holden on April 07, 0:14

Instead of putting the filter logic in the ActiveRecord, how about a filter proxy which implements this model? You could then move ALL of the access control methods, and even the attributes = method to this new class.

So you would have something like: (again, more code that probably syntactically wrong... but should get the idea accross)

user = User.new
# Would return 'undefined method'
user.attributes = @params["user"]

proxuser = RecordProxy.attach(user) do
attributes_block_all
attributes_allow :name, :passwd
attributes_allow_prefix :option_
end

# Only the attributes allowed by the filter are set
proxuser.attributes = @params["user"]
proxuser.save

And of course, you could do a one time proxy...
user = RecordProxy.assign(User.new, @params["user"]) do
attributes_block_all
attributes_allow :name, :passwd
attributes_allow_prefix :option_
end


or if you needed the filter more than once but for different objects... you could do something like:

userproxy = RecordProxy.new
userproxy.filter do
attributes_block_all
attributes_allow :name, :passwd
attributes_allow_prefix :option_
end

user1 = userproxy.pass(User.new, @params["user1"])
user2 = userproxy.pass(User.new, @params["user2"])

etc =)

Challenge by David Heinemeier Hansson on April 07, 13:05

I think this debate is coming partly from the fact that I didn't make it clear how easy it is to do per-attribute assignment on the controller level. If you're uneasy with mass-assignment and like to keep sensitive data mixed with non-sensitive data (that's often a good idea), you'd just do like this:

def create_user
  User.new(
    "name" => @params["name"], 
    "email" => @params["email"], 
    "website" => @params["website"]
  ).save
end

...or this:

def create_user
  user = User.new
  user.name = @params["name"]
  user.email = @params["email"]
  user.website = @params["website"]
  user.save
end

Now you can add membership_level as an attribute on the user object without worrying that it's accessible for parameter-injection.

But of course this goes much against the entire idea of the post, which was to use mass-assignment for something useful and to decrease the per-attribute knowledge in the layers.

It is, however, much better to keep this information on the controller than on the model from my conceptual viewpoint. And it's also a much lighter system than building firewalls or wrapping proxies around the models.

So that would be my recommendation. Use mass-assignment when you work with all-accessible objects (you'll discover that many objects are indeed safe to make accessible in their entirety). Or use the upcoming shortcut if you only have a handful of sensitive fields and still want the mass-assignment advantages. Or use per-attribute assignment on the controller if mass-assignment makes you feel uneasy or if you have more sensitive fields than not.

Challenge by Luke Holden on April 07, 18:11

That’s one thing I rather like about your approach to rails. K.I.S.S.

I guess you might say I am just a tad used to over engineered java projects =)

Question though… Say I have my ‘simple’ security unimportant object which I use mass assign with..

Box.new(@params[“box”]).save

What happens if someone say… puts ‘box[id]=5’ or ‘box[oid]=5’ in the request?...

Anyways… still looking forward to getting my copy of rails =)

Challenge by David Heinemeier Hansson on April 07, 18:25

The id is the one attribute that you can't mass assign :)

Challenge by Xen on May 11, 14:19

Someone said something about only having user changable attributes in the model, which made me think something along these lines:

class User mass_assignable :name, :passwd, :fullname
end

class UserAdmin all_mass_assignable
end

Then one uses the User class in the frontend, and UserAdmin in the admin interface. I'd prefer one User class, but then it gets messy when you have different 'views'. Leveraging (gah, marketingspeak) the object hierarchy makes code reuse simple, while still allowing for seperation.

'Acting as the firewall should be the role of the controller.' That pretty much kills off the usefulness of attributes= and neatness of not having to change the controller, doesn't it? Then the controller has to know about all the models and whether they have protected attributes, or not, and what those limitations is. I'd say that it's the model that knows whats assignable, and what limitations there is on attributes, not the controller, and putting the validation into the controller only gets us back to where we started. Going out on a limb here, but assuming that attributes= uses normal accessor fuctions, we'd do something like:

class User def email=(email)
raise InvalidInput, "Bad email address" if email !~ /^[a-z0-9_.-]@[a-z0-9.-]$/
super(email)
end
end

and then in the controller:

def update
begin
@user = User.find(id)
@user.attributes = @params["user"]
@user.save
rescue InvalidInput => e
@error = e.message
render "user/edit"
end
redirect "user/display/" + @user.id.to_s
end

or, with a convenience method:

def update
update_or_reedit("user/edit") do
@user = User.find(id)
@user.attributes=(@params["user"]).save
end
redirect "user/display/" + @user.id
end

That way, when I decide that VARCHAR(255) was too much for User.name, I cut it down to 80 in the DB, modify the model and the view, and I don't have to hop around and fix the input validation on user/create, user/update, admin/newuser admin/edituser, so on and so forth (though I'm assuming that in such a simple case, that ActiveRecord is doing much the same from the data it gleaned from the DB in the first place). Extend the InvalidInput exception to carry information about which field failed, and why, a bit of magic to attributes= to collect exceptions from all the attribues, and an easy way for the view to use this information, and things could get very nice indeed.

Challenge by David Heinemeier Hansson on May 11, 23:55

Active Record implements a sophisticated validations and callback system that does much as you describe in a very clean way. Have a look at the latest slides and look forward to the release in just a few days.

Challenge by Xen on May 12, 1:23

Oho, I just spotted a 'if person.save' thing in the slides... Which I must have missed in Roskilde.. Very, very nice indeed...

And if I understand it correctly, it's doing exactly what I was thinking, keeping the 'firewall' in the model, and the controller only have to deal with whether there was an error or not.

I need to wrap my head around Ruby better. I keep going 'Damn.. Now *that's* elegance...'

I'm looking forward.. Man, am I looking forward...

Challenge by David Heinemeier Hansson on May 12, 1:30

Right. I didn't go into validations at all in Roskilde. We should have had another hour for all the cool advanced stuff ;).

Also, note that the firewall approach can now be taken with:

class User 

Now only those two attributes are accessible for mass-assignment. The rest is safe. That's the flip-side of:

class User 

Which will allow anything but the attributes named to be accessible for mass-assignment.

Challenge by ho scale slot cars on May 08, 21:45

Please check out some information about video strip poker video strip poker http://www.juris-net.com/video-strip-poker.html poker strategy poker strategy http://www.juris-net.com/poker-strategy.html poker roomcom poker roomcom http://www.juris-net.com/poker-roomcom.html play poker game play poker game http://www.juris-net.com/play-poker-game.html blackjack books blackjack books http://www.juris-net.com/blackjack-books.html craps tables craps tables http://www.juris-net.com/craps-tables.html gambling gifts gambling gifts http://www.juris-net.com/gambling-gifts.html las vegas slot dealers las vegas slot dealers http://www.juris-net.com/las-vegas-slot-dealers.html poker babes poker babes http://www.juris-net.com/poker-babes.html gambling games gambling games http://www.juris-net.com/gambling-games.html negative effects of gambling negative effects of gambling http://www.juris-net.com/negative-effects-of-gambling.html pogo slots pogo slots http://www.juris-net.com/pogo-slots.html gambling sports gambling gambling sports gambling http://www.juris-net.com/gambling-sports-gambling.html play free roulette play free roulette http://www.juris-net.com/play-free-roulette.html kinder louisiana gambling kinder louisiana gambling http://www.juris-net.com/kinder-louisiana-gambling.html black jack game download black jack game download http://www.juris-net.com/black-jack-game-download.html craps free craps free http://www.juris-net.com/craps-free.html craps tables for sale craps tables for sale http://www.juris-net.com/craps-tables-for-sale.html roulette wheel picture roulette wheel picture http://www.juris-net.com/roulette-wheel-picture.html bible gambling bible gambling http://www.juris-net.com/bible-gambling.html washington state gambling commission washington state gambling commission http://www.juris-net.com/washington-state-gambling-commission.html black jack instruction black jack instruction http://www.juris-net.com/black-jack-instruction.html craps statistics craps statistics http://www.juris-net.com/craps-statistics.html california gambling california gambling http://www.juris-net.com/california-gambling.html cheapest craps cheapest craps http://www.juris-net.com/cheapest-craps.html download free blackjack game download free blackjack game http://www.juris-net.com/download-free-blackjack-game.html roulette craps blackjack roulette craps blackjack http://www.juris-net.com/roulette-craps-blackjack.html black jack probability calculator black jack probability calculator http://www.juris-net.com/black-jack-probability-calculator.html craps table odds craps table odds http://www.juris-net.com/craps-table-odds.html free games slots black jack free games slots black jack http://www.juris-net.com/free-games-slots-black-jack.html electronic hand held black jack electronic hand held black jack http://www.juris-net.com/electronic-hand-held-black-jack.html how to win in keno how to win in keno http://www.juris-net.com/how-to-win-in-keno.html volcanic bingo roulette volcanic bingo roulette http://www.juris-net.com/volcanic-bingo-roulette.html black jack game to download black jack game to download http://www.juris-net.com/black-jack-game-to-download.html buy roulette wheel buy roulette wheel http://www.juris-net.com/buy-roulette-wheel.html ... Thanks!!!

Challenge by serge on May 09, 21:35

Hi. This is my links.
Sex creampies Amateur creampie pictures Creampie gangbang pregnant cum load inside Internal cum shot creampie video Free creampies pics Gallery creampie pics Creampie video free Creampie cock in pussy Anal creampie movie free Creampie gangbang pregnant cum load inside Creampie cock in pussy Creampie gangbang pregnant cum load inside Amateur creampie pictures Galleries free creampie movies Internal cum shot creampie video Free thumbnails of creampie women Creampies pussy Unsuspecting teen creampies Creampie hardcore sex pictures Galleries free creampie movies Creampie sex videos Anal creampie movie free Mature black babes nasty creampies cunt spreads Creampie video free Eating anal creampies Creampie internal, cumshots Anal creampie mpegs Cheat creampie stories Mature black babes nasty creampies cunt spreads Creampie internal, cumshots Creampie video free Creampie cock in pussy Creampie vaginal cum shot Anal creampie mpegs Creampie video free Internal cum shot creampie video Creampie stories Brittanys interracial creampie videos Anal creampie movie free Creampie video free Gallery pictures creampie Porn movies creampie frei tgp Creampie eating stories Porn movies creampie frei tgp Brittanys interracial creampie videos Creampies pussy Hairy internal creampie pussy Free thumbnails of creampie women Creampie hardcore sex pictures Creampie sex videos Gallery pictures creampie Free thumbnails of creampie women Creampie stories Mature black babes nasty creampies cunt spreads Brittanys interracial creampie videos Creampie pussy cunt Creampie stories Cheat creampie stories Eating anal creampies Creampie sex videos Grannies pussy creampies Sex advice creampie Creampie pussy cunt Creampies pussy Creampie eating stories Brittanys interracial creampie videos Creampies pussy Gallery pictures creampie Mature black babes nasty creampies cunt spreads Anal creampie movie free

Challenge by bob on June 04, 12:08

Sorry for my links
free thumbnail pictures of older women mature amature free thumbnail pictures of older women nud3 senior women south indian mature women mature anal mature amature mature anal mature ladies in lingerie older moms mature gallerys mature women stories mature gallerys older moms older s3xy women mature women stories nud3 senior women mature living mature amature mature gallerys mature nud3 pics mature nudists photos mature women stories mature living mature spunker nud3 senior women nud3 senior women free thumbnail pictures of older women mature video mature gallerys mature ladies in lingerie mature amature mature video mature anal free naked older women mature women stories south indian mature women mature nudists photos mature video mature spunker

Challenge by petra on June 05, 5:23

Hello. I am new here. It is very interesting.
free pantyhose thumbs pantyhose chat girls in body stockings free pantyhose thumbs free panty thumbnail gallery men who wear pantyhose pantyhose and nylon feet and toes nylon stocking galleries men who wear pantyhose boys in pantyhose boys in pantyhose men pantyhose boys in pantyhose girl panty pics feet in nylon girls in body stockings free panty thumbnail gallery girls in fishnet stockings girls in fishnet stockings pantyhose chat boys in pantyhose girls in body stockings russian pantyhose women feet in pantyhose pics free panty thumbnail gallery boys in pantyhose free pantyhose thumbs pantyhose crossed legs girls in fishnet stockings feet in nylon girl panty pics pantyhose crossed legs men who wear pantyhose free pantyhose thumbs mature pantyhose pictures girls in fishnet stockings pantyhose and nylon feet and toes girl panty pics girl panty pics nylon galleries

Challenge by jon on June 05, 9:27

Sorry for my links
free creampie pics free creampie movie creampies xyx creampies xyx creampie p0Rn free creampie clips creampie p0Rn creampie anal creampie anal gangbang creampies videos pictures creampie free creampie pics and stories creampie cum and amature creampie pussies asian creampies interracial wives bareback creampies free creampie pics free creampie pic creampie pic creampie internal, cumshots creampie p0Rn gangbang creampies videos creampie pic asian creampies free creampie pics and stories creampie anal interracial wives bareback creampies pictures creampie creampie cum and amature free creampie clips creampie movie free anal creampie pics pictures creampie creampie pic creampie cum and amature latina creampie free anal creampie pics interracial wives bareback creampies amature creampies free creampie pics free

Challenge by atmor on June 06, 11:32

Hello. I am new here. It is very interesting.
young girls older men mature mistress mature asian women free older women galleries older women stories mature pic gallery black older ladies mature mistress older holland older women stories mature pic gallery older holland older holland older black women mature glamour young girls older men older women stories free older women galleries mature pantyhose pictures mature mistress naked old women thumbs mature mistress older holland mature pic gallery how to meet older women mature index young girls older men mature glamour naked old women thumbs thumbs gallery older women black older ladies older 1esbians older 1esbians how to meet older women mature mistress young girls older men mature glamour older holland older women stories thumbs gallery older women

Challenge by juju on June 08, 0:05

Hi. This is my links.
office girls in nylons men caught wearing pantyhose men caught wearing pantyhose satin panty galleries hooters girls in pantyhose celebrities in pantyhose winnie-cooper pantyhose men's pantyhose satin panty galleries mature women in pantyhose panty fetish mature pantyhose pics panty fetish wet pantyhose wet pantyhose white pantyhose panty fetish cheerleader panty pics hooters girls in pantyhose office girls in nylons free wet panty wet pantyhose cheerleader panty pics mature pantyhose pics men caught wearing pantyhose mature women in pantyhose wet pantyhose men caught wearing pantyhose hooters girls in pantyhose pantyhose images mature ladies in pantyhose girls in nylons winnie-cooper pantyhose office girls in nylons panty post mature pantyhose pics panty post white pantyhose men's pantyhose celebrities in pantyhose

Challenge by mara on June 08, 4:30

Hi. This is my links.
silkies pantyhose crotchless pantyhose pantyhose pic gallery men in panty pics pantyhose pic gallery free pantyhose pics pantyhose foot gallery teen panty pictures crotchless pantyhose panty girls panty girls bra and panty pics pantyhose men free panties pantyhose pic gallery shiny pantyhose bra and panty pics shiny pantyhose free panty galleries men in panty pics mature women in nylons pantyhose fetish free pantyhose sites mature women in nylons panty line pics pantyhose foot gallery pantyhose foot gallery crotchless pantyhose mature women in nylons little school girls panties pantyhose men free pantyhose pics mature women in nylons free panties bra and panty pics free panty galleries little school girls panties mature women in nylons teen panty pictures mature women in nylons

Challenge by mara on June 08, 19:32

Sorry for my links
mature cart00ns mature personals mature personals mature s3x pics free mature s3x pics victor mature free mature s3x pics mature 1esbian nud3 mature men mature 1esbian top mature t9p's daily mature boobs bcn mature older women pictures older women pictures meet older women daily mature boobs free mature movies older women pictures daily mature boobs free pics mature ladies mature 1esbian free pics mature ladies meet older women daily mature boobs bcn mature mature cart00ns older women pictures free mature movies mature older t9p mature s3x pics mature 1esbian s3xy mature women nud3 mature top mature t9p's meet older women mature older t9p free mature movies nud3 mature mature s3x pics

Challenge by free poker on June 21, 8:57

Please check some relevant information on free poker free poker http://www.poker-adventure.com/free-poker.html ... Thanks!!!

Challenge by weight loss pills on June 24, 6:52

In your free time, visit the sites in the field of online pharmacy online pharmacy http://www.thebest-pills/online-pharmacy.html pharmacy pharmacy http://www.thebest-pills/pharmacy.html weight loss pills weight loss pills http://www.thebest-pills/weight-loss-pills.html .