{ "info": { "author": "Dieter Maurer", "author_email": "dieter@handshake.de", "bugtrack_url": null, "classifiers": [ "Development Status :: 5 - Production/Stable", "Framework :: Zope", "Framework :: Zope2", "Framework :: Zope :: 4", "Intended Audience :: Developers", "License :: OSI Approved :: Zope Public License", "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Topic :: Utilities" ], "description": "This package contains a replacement for Zope's ``Products.Transience``,\nwhich is typically used to implement Zope's sessions.\nWhile ``Products.Transience`` \nhas quite a high risk for ``ConflictError`` if many requests access the\nZope session, the current package should be\nresponsible only for very few ``ConflictError``\\ s, even if every request\naccesses the Zope session.\n\nThis is achieved by a changed organization of the sessions set.\n``Products.Transience`` organizises this set into a list of generations.\nIf a session is accessed, it is moved into the newest generation\n(if not already there). This way, a session access (even\na read only session access) can cause a write and result in\na ``ConflictError``. ``dm.zope.session`` maintains the sessions\nin an ``OOBTree`` (which has partial conflict resolution). To support\nsession timeout, the last access time is maintained on the individual\nsession object in a data structure with 100 % conflict resolution.\nThis way, read access to the session should not result in a\n``ConflictError``.\nTo reduce ZODB bloat, the access time is not updated on every access\nbut employs a limited resolution, by default about 1/8 of the session timeout.\n\n``Products.Transience`` performs an inline cleanup for outdated\nsessions. It can do that because its cleanup is very fast (drop the oldest\ngeneration and create a new newest one). ``dm.zope.session``'s\ncleanup involves visiting all sessions and check whether they are\noutdated. This can be expensive. Therefore, it performs the cleanup\noffline - in a separate thread. The cleanup uses very short transactions\nto reduce the risk of conflicts.\n\nIf you use Zope in a ZEO setup, i.e. serveral Zope processes use\nthe same ZODB, then only one of the Zope processes will run the\ncleanup thread. It may take until the (old) period of this thread\nhas finished before some configuration changes become effective\n(especially ``cleanup_period_sec``). In general, this should not\nmake a big problem. Should it be problematic in special cases,\nyou may need to restart this process. You will find its process\nid in a lockfile under *clienthome* with a name derived from\nthe session container path.\n\n\n**ATTENTION** Like most (server side) session implementations,\n``dm.zope.session`` can be vulnerable to denial of service\nattacks. It is often not difficult to make the server create\na new session and each session needs resources; an attacker\ncan try to massively create sessions in order to overload this\nkind of resource. ``dm.zope.session`` puts its sessions into a\nZODB which typically uses a file as storage. This kind of resource\nusually has a large capacity and therefore is difficult to overload.\nHowever, should an overload happen, the consequences can be severe.\nPlease read the section `DOS attacks`_ to learn about some\nof your options to counter those attacks.\n\n\nFeatures\n========\n\n``dm.zope.session`` supports the following features.\nCorresponding configuration variables are specified in parenthesis.\n\nMaximal session lifetime (``session_max_lifetime_min``)\n This feature allows to limit the maximal lifetime of the session.\n It can be interesting for security reasons: should an\n attacker have been able to hijack a session, he should only\n be able to use it for a limited period.\n\n In Zope's session architecture, the session id is managed by\n the so called ``browser_id_manager``. It is using a cookie\n to pass the session id between browser and server.\n To be effective, the maximal session lifetime must be combined\n with a limited lifetime for the session id; otherwise, an\n attacker can use the known session id to hijack a followup\n session. In modern Zope versions, the session id is by default\n stored in a (browser) session cookie. In this setup, an attacker\n can hijack followup sessions until the user terminates his\n browser session.\n\n The maximal session lifetime is controlled via the\n configuration variable ``session_max_lifetime_min``.\n It specifies the maximal lifetime in minutes. A non positive\n value deactivates the feature.\n\nSession inactivity timeout (``session_timeout_min``)\n A session is deleted when is it not used for about\n ``session_timeout_min`` minutes. If ``session_timeout_min``\n has a non positive value, the feature is deactivated.\n\n The timeout feature is not implemented precisely:\n a session may be deleted slightly before the specified\n inactivity and may live slightly longer than the specified\n timeout. There are two reasons for this:\n\n 1. to avoid ZODB bloat, the session access time is stored\n with limited (usually about 1/8 of the session timeout) resolution.\n\n 2. session inactivation is performed by a periodic cleanup\n process. Nothing happens until the next run of this process.\n\n The inactivity timeout is an inportant feature for\n sessions implemented by ``Products.Transience``, because\n it typically stores sessions in (precious) RAM. ``dm.zope.session``\n sessions are typically stored in a ``FileStorage`` for\n which early freeing resources is of far less importance.\n However, if you store sensible information in the session,\n you may still want to use this feature for security reasons:\n it forces a potential attacker to keep a hijacked session alive\n for continued exploitation.\n\nSession access time resolution (``session_access_time_resolution_min``)\n This controls whether the session access time\n is updated: an update is suppressed if the last update was\n more recent then the access time resolution.\n ``session_access_time_resolution_min`` specifies an access\n time resolution in minutes. The effective access time\n resolution is the minimum of this resolution and about 1/8\n of the session timeout where non positive values are ignored.\n If both resolutions are non positive, the access time is not\n maintained.\n\nSession target number (``session_target_number``)\n A periodic cleanup tries to keep the number of sessions below\n ``session_target_number`` by deleting the oldest sessions.\n A non positive value for ``session_target_number`` deactivates\n the feature.\n\nSession maximal number (``session_max_number``)\n ``session_max_number`` limits the number of session objects.\n The exception ``dm.zope.session.MaximalSessionNumberExceeded``\n is raised when the limit would be exceeded. A non positive\n value deactivates the feature.\n\n This option can be used to limit the thread posed\n by `DOS attacks`_.\n\nPeriodic session cleanup (``cleanup_period_sec``)\n A periodic cleanup process deletes sessions whose maximal lifetime\n or inactivity timeout is reached. It also deletes the oldest\n sessions to keep the session number below\n the session target number. ``cleanup_period_sec`` specifies\n the period for this process in seconds. If it has a non positive\n value, 10 is used instead.\n\nEvents\n For customization purposes, some events are notified. Their\n interfaces are all defined in ``dm.zope.session.interfaces``.\n All events are \"object events\" with either the session\n or the session container as event object.\n\n ``ISessionCreatedEvent``\n Notified when a new session object is created.\n Can be used to transfer information from the request to the\n session, e.g. information potentially helpful to detect\n `DOS attacks`_.\n\n ``IMaximalSessionNumberExceededEvent``\n Notified when the maximal session number is reached.\n Can be used to implement a custom policy to delete\n sessions in such a case in order to let the operation succeed.\n Note, however, that the deletion of the same\n session by concurrent requests leads to an unresolvable\n conflict (only one of those requests will succeed); it is therefore\n advicable to choose the session to be deleted with considerable randomness.\n\n ``ISessionCleanupEvent``\n Notified during each cleanup round.\n Can be used to implement a custom cleanup policy, e.g.\n check for `DOS attacks`_ or enforce a \"One session per user\" policy.\n Note that this event is notified in a separate thread outside\n the typical Zope request context; only very few \"services\"\n are available.\n \n\nInstallation\n============\n\nUnfortunately, it is more difficult to use Zope sessions\nimplemented by ``dm.zope.session`` than those implemented\nby ``Products.Transience``. In the latter case, all you need to\ndo is installing ``Products.Sessions`` and (maybe) (slightly) extending\nyour Zope configuration file. To use ``dm.zope.session``,\nyou must install both it and ``Products.Sessions``, ensure that the\nZCML configuration of ``dm.zope.session`` is executed during startup\nand then [re]configure Zope's session machinery via the ZMI (= \"Zope\nManagement Interface\"). To facilitate this configuration, we\nsketch first Zope's session architecture.\n\nZope's session architecture\n---------------------------\n\nThe various subtasks related to session\nmanagement are delegated to different cooperating Zope objects:\n\n``session_data_manager``\n This objects makes the session available via the request object.\n It uses the ``browser_id_manager`` to generate a session id\n and a session container (called \"transient object container\")\n for the storage of the session objects.\n By default, the session container is located at\n ``/temp_folder/session_data``; this can be changed via the ZMI.\n\n``browser_id_manager``\n This object is responsible to assign session ids (called\n browser ids, because they in fact identify the browser).\n\nsession container\n This is an object used to store (and manage) the sessions.\n Its path is determined by the ``session_data_manager``;\n by default, it is ``/temp_folder/session_data``.\n\n``temp_folder``\n By default, this is a mount point. The mount point\n is configured in the Zope configuration file (``zope.conf``).\n Typically, it mounts a ``Products.TemporaryFolder.TemporaryContainer``\n from a ``tempstorage`` with name ``temporary``.\n A ``tempstorage`` maintains its data in RAM; therefore, the data is lost on\n restart. To (partially) counter this data loss, Zope creates (typically)\n a session container named ``session_data`` with values\n from the Zope configuration file on startup.\n\n\nZMI configuration for ``dm.zope.session``\n-----------------------------------------\n\nThere are various options to configure for the use of\n``dm.zope.session``.\n\nThe easiest way is to create\na ``dm.zope.session:Container`` (via the ZMI) somewhere\n(but not below ``temp_folder`` where it would be lost on restart)\nand then let the ``session_data_manager``'s\n``Transient Object Container Path`` point to its location.\nThis puts the sessions into the main ZODB.\n\nYou might want to maintain the sessions in their own ZODB, e.g.\nto use different parameters (such as e.g. cache size) for sessions\nand the main content or use different pack parameters and/or frequencies.\nTo do this, you would configure a mount point in the Zope\nconfiguration file (likely similar to the definition for the\n``main`` ZODB -- do not use ``temporarystorage``!),\nadd a corresponding mount point in the\nmain ZODB (via the ZMI) and then put there the session container.\n\nShould you use Plone, you likely would need to disable\nits CSRF protection or put the session container into\na mounted ZODB with name ``temporary``: Plone's CSRF protection\nlooks for ZODB writes and usually allows them only, if the request\nis \"authenticated\". To support session access (which\nmight cause writes even for a read access), it allows\nwrites to objects in ``temporary`` also for unauthenticated requests.\nLikely, your Zope configuration file already contains a\ndefinition for this ZODB, adapted for Zope's standard sessions\nand based on ``temporarystorage``; you would need to replace it\nby one for ``dm.zope.session`` (i.e. similar to the\ndefinition for the ``main`` ZODB and especially not using\n``temporarystorage``).\n\n\nUse\n===\n\nThe typical session setup (by ``Products.Sessions``)\nmakes the current session available as *request*\\ ``[\"SESSION\"]`` where\n*request* represents the request object. The session behaves\nsimilar to a Python ``dict``. In addition, you can use the methods\n``set`` and ``delete`` to set a session \"variable\" or delete one, respectively.\n\n``dm.zope.session``'s sessions are (like those\nof ``Products.Transience``) ZODB based. This has\nan important implication: the request does not work with\nthe session directly but with a local copy of the session\nobject maintained in the ZODB. When the request changes the\nsession, then in the first place it only changes the local\ncopy. Some changes are recognized by the ZODB --\nthis includes changes to the session itself and changes\nto other \"persistent object\"s -- and cause the modifications\nto update the affected persistent objects in the ZODB when\nthe request finishes successfully. In this case, followup requests\nwill see the modifications. Other changes (to non persistent objects,\ne.g. lists, dicts, most class instances, ...) are\n**NOT** recognized automatically and are not written to the ZODB.\nIn such a case, some followup requests may see the modifications\nbut others will not. If you use complex (\"mutable\") values for your\nsession variables, try to use \"persistent objects\" (the package\n``persistent`` has persitent variants of lists and mappings)\nor reassign a the value to the session variable after you\nhave changed it, e.g.::\n\n\tcomplex_value = session[\"var\"]\n\t# modify complex_value via its methods\n\tsession[\"var\"] = complex_value\n\nThe code above will ensure that the change will be written\nto the ZODB if the request succeeds (does not fail with an exception).\n\n\nDOS attacks\n===========\n\n``dm.zope.session`` can be vulnerable to denial of service (DOS)\nattacks. In such an attack, the attacker would try to force\nthe server to massively create new sessions. Each of those\nsessions needs resources (typically file space for ``dm.zope.session``).\nThe attacker's aim would be to overload this kind of resource and\nget the site (and maybe other services using the same resource kind)\nin trouble.\n\n``dm.zope.session`` has not enough knowledge to prevent this\nkind of DOS attacks. However, it has features to limit the potential\ndamage and to help detecting and handling such attacks.\n\nThe simplest approach is to limit the number of sessions\nby giving the configuration parameter ``session_max_number`` a positive value.\nThis limits resource usage. However, if you have put data\nvital for the use of your site into the session, your site may still\nno longer function properly because no new sessions can be created\nduring the attack. Therefore, try not to use the session\nfor the most fundamental services of your site - use cookies instead.\n\nAn alternative approach would be to try to detect and handle\nattacks. ``dm.zope.session`` notifies some events to help you\nwith this. An ``ISessionCreatedEvent`` is notified whenever\na new session object is created. You can register a handler\nto add information to the session which helps to detect and/or\nhandle potential attacks; potentially, the handler also performs\nthe detection and handling itself. An ``IMaximalSessionNumberExceededEvent``\nis notified when the maximal session number would be exceeded.\nIn a correspoding handler, you can try to delete sessions based\non custom policies. Potentially, you try to detect a potential attack\nand delete related sessions. ``dm.zope.session`` notifies\nan ``ISessionCleanupEvent`` during each cleanup round. DOS\ndetection and handling could also be implemented in its handler;\nnote, however, that it runs \"offline\" (not inside the typical Zope\nrequest context) and that it can use only very few Zope services.\n\nAny attack comprises a large number of requests, all under the\ncontrol of the attacker. To detect an attack, you must\nbe able to recognize sessions which may have been created by the attacker.\nA fairly reliable way would be to use the session only\nfor authenticated users (and e.g. use cookies for all services\nprovided for anonymous users). In this case, you could store\nthe corresponding user id in the session. If an attack is suspected,\nyou could visit all sessions, check for users with an unexpected\nnumber of sessions and delete those, maybe even disable the user.\nIf you must use the session for anonymous users, you can try to\nuse the request's IP address in place of the user id. Note, however,\nthat this is far less reliable as many organisations grant internet\naccess only through proxies; then all organization members use\nthe same IP address. Therefore, it is much more difficult\nto distinguish normal use from an attack. Sessions have\nproperties ``created`` (a timestamp float) and ``created_date`` (``DateTime``)\nindicating when the session has been created;\nthey can help with this distinction. Note, that advanced attackers\nmay use a large number of (hijacked) clients; in such a case,\nthe attacking requests would come from different IPs; the \"created\" properties\nmight still be used to find candidates for attacker sessions - again\nwith reduced reliability.\n\n\nMaintenance\n===========\n\nThe sessions managed by ``dm.zope.session`` are typically stored\nin a ``FileStorage``. Such a storage not only keeps the current\nstate but also historical data (important e.g. for conflict resolution,\n\"undo\" and analysis of past events). To get rid of old, no longer\nused information, you must regularly \"pack\" the storage.\nThis is particularly important for a storage hosting sessions as\nsessions tend to be much more frequently changed than \"normal\" objects\nand more frequent changes mean more irrelevant historical data.", "description_content_type": "", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "http://pypi.python.org/pypi/dm.zope.session", "keywords": "session application development zope", "license": "ZPL", "maintainer": "", "maintainer_email": "", "name": "dm.zope.session", "package_url": "https://pypi.org/project/dm.zope.session/", "platform": "", "project_url": "https://pypi.org/project/dm.zope.session/", "project_urls": { "Homepage": "http://pypi.python.org/pypi/dm.zope.session" }, "release_url": "https://pypi.org/project/dm.zope.session/1.0/", "requires_dist": null, "requires_python": "", "summary": "ZODB based heavy duty Zope session implementation.", "version": "1.0" }, "last_serial": 5674855, "releases": { "1.0": [ { "comment_text": "", "digests": { "md5": "d637b115a2c02694b7ba0654028020fe", "sha256": "8e1c5ae68be1d41d4f60d87380df6b387c94a7956511472622b2d730cfdf8ad6" }, "downloads": -1, "filename": "dm.zope.session-1.0.tar.gz", "has_sig": false, "md5_digest": "d637b115a2c02694b7ba0654028020fe", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 22766, "upload_time": "2019-08-14T05:15:43", "url": "https://files.pythonhosted.org/packages/ca/86/9a975418c06a1a3cb335899ae0e928a52c1417ed3c3796e96dfd2cad1509/dm.zope.session-1.0.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "d637b115a2c02694b7ba0654028020fe", "sha256": "8e1c5ae68be1d41d4f60d87380df6b387c94a7956511472622b2d730cfdf8ad6" }, "downloads": -1, "filename": "dm.zope.session-1.0.tar.gz", "has_sig": false, "md5_digest": "d637b115a2c02694b7ba0654028020fe", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 22766, "upload_time": "2019-08-14T05:15:43", "url": "https://files.pythonhosted.org/packages/ca/86/9a975418c06a1a3cb335899ae0e928a52c1417ed3c3796e96dfd2cad1509/dm.zope.session-1.0.tar.gz" } ] }