Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

EU "cookie law" compliance #1375

Closed
alexbilbie opened this Issue · 36 comments
@alexbilbie

I've added a new branch called feature/eu-cookie-law (https://github.com/EllisLab/CodeIgniter/tree/feature/eu-cookie-law).

This branch makes the CI session library compliant with the EU "cookie law" which states that cookies should not be set on a user's computer unless they have given the [EU based] site permission to do so.

There is a new config variable called $config['cookie_consent_required']. When this is set to TRUE no cookies will be set when the session library is first loaded (if a session cookie doesn't exist already), and any existing session cookies will be destroyed.

Cookies now won't be set until the user has given explicit consent. This can be controlled using two new functions in the cookie helper - cookie_consent_granted() and cookie_consent_withdrawn().

What do people think?

Note this commit only changes the automated behaviour of the session library, cookies can still be set manually using the cookie helper

@alexbilbie

Just to clarify some points that have been brought up on Twitter. The reason why this should be fixed at framework level instead of at application level is because CodeIgniter will drop a session as soon as the session library is loaded (and regardless of whether or not any session data is then actually set) so the user isn't given a choice in the matter.

Also this default cookie contains "private information" (IP address, user agent, etc) instead of functional data (i.e. strictly necessary to operate the website).

@deplorableword

No cookies should be set when the session library is first loaded.

This is the bug which needs to be fixed at a framework level. If you care about performance then this needs to be resolved, it will make anyone who cares about web performance happy.

Once this has been resolved, surely the cookie_consent_granted() function isn't required at a framework level anymore? Isn't this something Application developers can now manage on their own, now they have complete control over when a cookie is dropped with the browser?

(p.s. think it's great that more people are getting directly involved developing CI, so hat tip to that :D )

@dshoreman

AFAIK the exact details of the cookie law are still debatable. Specifically, some people think you absolutely must get permission before setting any cookies; others are of the opinion that you can set cookies straight away as long as you ask permission at some point, and remove them if the user declines.

I haven't read a huge amount on the cookie law so I can't really back either side up. I personally believe the latter, so I'd much rather the session library continued to act as normal until told otherwise. Yes it's law, but not for everyone, so essentially disabling the session library by default could have a negative affect on people that don't have to suffer from EU laws. Then there's the potential issue that the law may differ between various EU countries, though by how much I don't know.

When it comes down to it, having measures in place in the core to help everyone abide by laws (whether they agree with them or not) can only be a good thing -- as long as I have to enable it myself. Just my two pennies, feel free to take them with a pinch of salt.

@joellimberg

I believe that adding features or config options based on laws or regulations passed in certain jurisdictions is a really bad idea. CodeIgniter is a framework, and it's not a framework's job to manage things like this via built-in functionality.

Of course the session library should be fixed so it does not automatically set cookies when no data is actually saved in sessions, etc. But this is an entirely separate concern.

@narfbg
Owner

It is a framework's job to make common features easier to develop and if a law makes it common enough - so be it.

@joellimberg

My main problem is actually that this supposed "cookie law" is so complex that cookie management cannot be boiled down to "Yes/No". Cookie usage restrictions are based on their intent, the status of the web application's owner, etc.

If there's a single "consent" setting, there will likely be incorrect or unnecessary usage.

I'll repeat that I do agree that CI should be smarter about setting cookies overall, so using the Session lib wouldn't automatically create and start managing cookies and session information (when nothing's actually stored).

@alexbilbie

@deplorableword yes

@daveshoreman UK law says you should ask permission before dropping any cookies, other EU states may have slightly different wording

@joellimberg bringing this issue to light might result in CI's session library being re-architected anyway and if it means that CI is compatible with the law then great however it is an important issue

@mdibbets

I am working on a pretty good session storing by using browser fingerprints.

I'm using the class from http://www.wolf-software.com/downloads/php-classes/security-classes/web-fingerprint-class/
To generate a hash with all the user information that is provided by the header requests of the users.
So far with a site that has about 10.000 pageviews a day it's still making unique headers and keeping track of the fingerprint browsing.
Only requirement is that you place the <meta http-equiv="X-UA-Compatible" content="IE=edge" /> in your header so that ie doesn't skip from mode 7 to 9 to 8 to 7 between pages when compatibility mode is enabled by the users.

Now i'm looking for a way to use this fingerprint hash to connect to the session class to retrieve all the information, that way I bypass cookie law in the netherlands.
Users get annoyed if they have to give permission to place a cookie and to be informed that their information is retained on our server bladiebla...

Plus it is another step in preventing session hijacking, because the session id is retrieved by matching fingerprints instead of cookies. My fingerprints at this time have a lifetime of about 10 minutes.

Is this a feasible option for getting past cookie law? or do I need to write my own session class.

@joellimberg

@mdibbets I would be very very cautious when using browser fingerprints as session ids (essentially).

Sure, it might still be unique at 10.000 users, but the randomness of the fingerprint is still extremely low compared to a truly random id.

@alexbilbie

@mdibbets you're not actually complying with the law there because you're still dropping cookies without consent

@mdibbets
@alexbilbie

The ICO (UK information commission office) updated their guidance yesterday to say that "implied consent" is a valid form of consent - this means that you can drop cookies without first asking the user however you should tell them that you've done so and if they want to change it they can remove them from their browser.

See http://www.ico.gov.uk/news/blog/2012/updated-ico-advice-guidance-e-privacy-directive-eu-cookie-law.aspx

Note this just for sites operating in the UK - other EU states may still require explicit consent before any cookies are dropped.

@alexbilbie alexbilbie was assigned
@jberculo

In the Netherlands you can drop cookies that are necessary for the operation of a site (such as user settings and preferences). When you are collecting data and/or sharing information with third parties you should ask permission before the cookie is set (allowing them to be removed isn't good enough).

I am the tech of a large blog, and our users kan add youtube etc. to the comments. As youtube (and Vimeo and... and...) also sets a cookie it is almost impossible for us to comply with the law without removing features for the users. I understand the intention of the law and approve of that, but the complications are severe (and in the end not addressing the real problem).

@alexbilbie

I have finally received a reply from the UK's Information Commissioners Office:

Thank you for your email dated 29 May 2012 about the new Cookie Regulations.

Please accept my apologies for the delay in responding to you, our office is currently dealing with large volumes of work. This has meant that we have been unable to deal with incoming correspondence as promptly as we would like.

You have asked ‘if a user's IP address and browser user agent string are personal data.’

Our view is that in many cases an IP address or browser string will constitute personal data. This is because the information can be used to monitor an individual’s behaviour and make decisions which will affect them. However, it can be difficult to determine with any certainty whether the information is personal data, because it could relate to several individuals who cannot be identified. Our guidance is that this information should be treated as personal data to ensure compliance.

So in their eyes CI would need to ask permission before dropping the session cookie

@deplorableword

So it's even more important that the session library should be fixed so that it does not drop a cookie when it's first loaded. Any chance it can be fixed in the next release?

@and-ers

Well the current method of handle cookies in CI isn't particulary OO, since there's function calls to set_cookie without storing the cookies as objects until they are destroyed.

I made a suggestion for a new cookie class that gives you more control for each cookie so that it's easier to quick adapt to legal frameworks that change over the time.

This class is working most like a kind of template right now and is incomplete.

Feel free to ask, suggest or propose another solution. I'm willing to implement full working cookie management solution, if others agree with the proposal.

http://pastebin.com/udXxG8fg

@and-ers

richwestcoast, it doesn't matter. The code must be object oriented enough to quickly adapt it's behaviour to all kinds of unpredictable political acts happening in any place on the planet. The cookie management in CI is quite incomplete in my eyes. I made a suggestion for a cookie/cookiegroup class before.

#2126

@novium

@richwestcoast @and-ers It's also classy to ask before dropping the cookie. And the CI cookie library shouldnt drop a cookie when it's loaded - it will be a bit more extendable.

@marcvdm

Is this issue/request going to be implemented or is the session library going to be fixed?

@novium

@marcvdm It is in the v3.0.x milestone

@ivantcholakov

A suggestion to the developers:

In application/config/config.php you may change the setting

$config['sess_driver'] = 'cookie';

into

$config['sess_driver'] = 'native';

This is likely a legal topic, and I think this is the easiest way to close it.

@narfbg
Owner

@ivantcholakov Switching to the 'native' driver doesn't solve the issue.

I'm not sure if that cookie law isn't already dead, I know it failed in the UK, but it was also a bit different there. Anybody with an update on it?

@AdwinTrave

I found this page about it: http://www.theeucookielaw.com/

@ivantcholakov

The initial directive is 2002/58/EC
http://eur-lex.europa.eu/LexUriServ/LexUriServ.do?uri=OJ:L:2002:201:0037:0037:EN:PDF

It has been ammended by 2009/136/EC
http://eur-lex.europa.eu/LexUriServ/LexUriServ.do?uri=OJ:L:2009:337:0011:0036:en:PDF

This is the important ammendment:

5) Article 5(3) shall be replaced by the following:

'Member States shall ensure that the storing of information, or the gaining of access to information already stored, in the terminal equipment of a subscriber or user is only allowed on condition that the subscriber or user con­cerned has given his or her consent, having been provided with clear and comprehensive information, in accordance with Directive 95/46/EC, inter alia, about the purposes of the processing. This shall not prevent any technical storage or access for the sole purpose of carrying out the transmission of a communication over an electronic communications net­work, or as strictly necessary in order for the provider of an information society service explicitly requested by the sub­scriber or user to provide the service.';

I had a look at the cookie-session driver and, if I correctly inderstand, the driver initially stores this kind of data:

session_id
ip_address
user_agent
last_activity

session_id and last_activity are OK, they are "for the sole purpose".

But for "carrying out the transmission of a communication" ip_address and user_agent (within the cookie) are not necessary. They may be used for increased security, as an additional measure of protection, but is this a "sole purpose"? Maybe not.

When the native PHP-session driver is used, the PHP-engine may drop a cookie for increased security (with the session name inside, I think), but this is a "technical" kind of data, needed only for carring out the transmission.

In conclusion, I think that:

  1. The default driver to be switched into the PHP-native one. This option is better for not causing legal headaches.
  2. About the cookie driver: Due to the increased security option, ip_address and user_agent should not be excluded. Then, the initial proposal with the $config['cookie_consent_required'] configuration option seems to me adequate. It should be well described within the configuration file. +1
@narfbg
Owner

Thanks for that lengthy explanation. The native driver however also stores a "last_activity" timestamp - it's not explicitly done because the filesystem itself does that, but they would've had to store it in a separate field in order to know when to expire the session. In other words - 'last_activity' is a part of that "technical data". 'sess_match_useragent' on the other hand is turned off by default, so what's the problem with it?

On 'cookie_consent_required', I don't see how this is applicable - you'd have to develop some kind of a pop-up or a more traditional HTML form to be displayed in e.g. a welcome page where users can give their consent about it. Having a configuration option won't save you that part of the work and I don't see how it helps.

@ivantcholakov

I'll have a close look at the session_cookie driver to clarify my opinion.

@ivantcholakov

Let us adopt the assumption that presence of 'ip_address' and 'user_agent' pieces of data within the session cookie involve legal implications that require some code modifications. I am trying to figure out the easiest way, with minimum intrusion and keeping the things simple.

The current default configuration options are:

$config['sess_driver']          = 'cookie';
$config['sess_valid_drivers']   = array();
$config['sess_cookie_name']     = 'ci_session';
$config['sess_expiration']      = 7200;
$config['sess_expire_on_close'] = FALSE;
$config['sess_encrypt_cookie']  = FALSE;
$config['sess_use_database']    = FALSE;
$config['sess_table_name']      = 'ci_sessions';
$config['sess_match_ip']        = FALSE;
$config['sess_match_useragent'] = TRUE;
$config['sess_time_to_update']  = 300;

Let us see what the behavior of the session cookie-based driver is at the moment, some variants:

  1. Cookie-based driver, without involving the database:

    $config['sess_driver'] = 'cookie';
    $config['sess_use_database'] = FALSE;
    $config['sess_match_ip'] = FALSE;
    $config['sess_match_useragent'] = FALSE;

'ip_address' and 'user_agent' are always present within the cookie althogh in this case we don't need them for security improvement.

  1. Cookie-based driver, with using the database:

    $config['sess_driver'] = 'cookie';
    $config['sess_use_database'] = TRUE;
    $config['sess_match_ip'] = TRUE;
    $config['sess_match_useragent'] = TRUE;

'ip_address' and 'user_agent' are always present within the cookie. We need them for security improvent. But I wonder, is it necessary to store them within the session cookie? The corresponding values can be retrieved from the database?

At the moment this is what I see:

  1. A mandatory action:
    Make corrections within the driver, so
    'ip_address' is to be stored within the cookie only when $config['sess_match_ip'] = TRUE and $config['sess_use_database'] = FALSE
    'user_agent' is to be stored within the cookie only when $config['sess_match_useragent'] = TRUE and $config['sess_use_database'] = FALSE
    Some notes within the configuration are to be added for $config['sess_match_ip'] and $config['sess_match_useragent'] that before their activation, posible legal implications to be known.

  2. Optional (I hesitate):
    Change $config['sess_match_useragent'] to FALSE

  3. Optional:
    Change $config['sess_driver'] to 'native'

Maybe at framework level this is enough to be done.

@narfbg
Owner

The unconditional storage of IP addresses and User-Agent strings is indeed a problem and there's an issue open about it: #1344

Changing 'sess_match_useragent' to FALSE by default is acceptable and this is probably the only difference to how the "native" driver behaves with no configuration changes. In fact, during discussion on another issue, the OP gave a good explanation on why the user-agent string is unreliable - it's client input and therefore attackers could change it at their will. With that said - I'd even agree on removing it completely.

What I don't agree with is your assumption that storing the IP address is a problem, unless of course it's indeed not used in validation. The cookie law gained quite the heat and that's no coincidence - it's not clear enough and obviously you prefer to understand it as 'restrict everything possible'.
I on the other hand don't believe cookies should be used with no IP address validation and IPs are technically required data. In fact, the only cases where it makes sense to not validate them is within an intranet, where this law wouldn't apply anyway.

@ivantcholakov

Ha, dchill42 said something similar #1344 (comment)

I agree with you that validation against UA is pointless.

About the IP validation: If the IP is not stored in plain text, it would not be used for other purposes, but solely for the proper communication. And let us rename it as something as "security_token", it sounds "technical".

I think about something like this:

$security_token = encryption_with_random_salt(one_way_hash($ip), $some_encryption_key);

Such a security token would be compliant. We may validate by IP, but it would not be possible the IP to be retrieved from the cookie.

@ivantcholakov

Or (optionally):

$security_token = encryption_with_random_salt(one_way_hash($ip.$user_agent), $some_encryption_key);

Edit:

I forgot something, the length of the security token should be controlled, it should not be long too much. So, the encryption key should be hashed (the result will be with a fixed length, which we may reduce at will).

$security_token = symmetric_encryption_with_random_noise(hash($ip), substr(hash($some_encryption_key), $max_key_length)));

@narfbg
Owner

I've got at least 3 arguments against that:

  1. It's an IP address, not a password, nor any kind of sensitive data - it doesn't make sense to encrypt it. (plus, there's hashing)
  2. Again, it's an IP address - we're not supposed to obfuscate it. What sense does it make to call it "security_token" just for the sounds of it?
  3. Cookies are read on every HTTP request and this would impact performance.
@narfbg
Owner

FYI, I've removed the latest comments.
GitHub is a place for development, and this is an issue about cookies and the EU cookie law.

If you want to ask other questions - ask them on the forums or IRC.

@narfbg narfbg removed this from the v3.0.x milestone
@alexbilbie alexbilbie removed their assignment
@jim-parry
Owner

Superceded by #3073. Can this be closed?

@narfbg
Owner

No, it will be closed when #3073 is closed.

@jim-parry jim-parry removed the Dead Issue? label
@narfbg
Owner

Fixed by #3073.

@narfbg narfbg closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.