How can I prevent hashing of session IDs in typo3? - php

I work with Typo3 and the actual session ID from the cookie is hashed into the database. How can I turn off the hashing? I am using Typo3 version 11.3.

You can't turn that off by any configuration. Of course you could change the code directly but that is not something this should be done.
May I ask why you need to disable that?
Some additional background taken from Oliver Hader at https://talk.typo3.org/t/disable-hashing-of-ses-id-possible/4617
The change you referring to was part of a security fix, which is described at TYPO3-CORE-SA-2020-011: Cleartext storage of session identifier.
Besides that, I also demonstrated a potential attack technically during the TYPO3 Online Days 2021, which can be watched again on YouTube at TYPO3 Online Days 2021 - #T3OD21 - Day 2 - June 30, 2021 - YouTube
The hashing implementation for the database component is show at [SECURITY] Protect persisted session IDs from being used directly · TYPO3/typo3#dc26a4a
For security reasons (as explained in the resources above), it is not possible to deactivate hashing (via HMAC) of the persisted identifier.

Related

What should a secure login script consist of?

I am going to write a secure login script and I would like to ask what kind of component it should have.
For now this are the things that came to my mind
Basic
Using PDO as connector for mysql database
Securing passwords using SHA512 ( should there be a salt/token involved ? )
Session and cookie management, trying to avoid the hijack of the session id ( could you provide me with some article about it ? )
XSS prevention ( could you referee me an article ? )
SQL Injection prevention sanitation of the input
Secure connection over https
Registration
In terms of registration using a reCaptcha
Login
Count the login attempts and block after 5 failure attempts to prevent from brute force attacks.
After login
Session timer with destruction ( 12 minutes to loose the session ) with a click to renew the timer [ does anyone has a example of this ? I couldn't find any ]
Are there any more major security hints that I should think off?
Thanks.
This is actually a nontrivial problem with a number of issues that need to be considered. Fortunately, a lot of the problems have been solved for you.
Password hashing: Use password_hash() and password_verify() -- don't use fast hashes like MD5 or SHA1, and also don't roll your own hashing strategy or else you'll find yourself reinventing PBKDF2 sloppily -- password_hash() does everything you probably want it to do without having to stress over implementation details. They are adequate; learn these tools well. If you're on PHP < 5.5 use password_compat
Database API: PDO is wonderful. Make sure you take full advantage of prepared statements to separate SQL queries from user-supplied data. Otherwise, doom.
Session Management: Use the built-in sessions, use HTTPS everywhere with no mixed content, set "httponly" and "secure" to true. Regenerate the session when privilege is escalated (e.g. the user logs in).
If you want to be paranoid, you can defend against session fixation attacks (which aren't really considered practical these days) by setting a canary session variable. Upon page load, if $_SESSION['canary'] is not defined (or does not match an expected value), destroy the session and treat the user as a new guest.
Rate-Limiting: Add a manual captcha after N login attempts (where N is greater than 1 but still very small).
Remember Me: Perfect example of "seems trivial, really isn't." Covered in this blog post. If you don't need it, don't implement it.
Account Recovery: A back-door by any other name. If you can get away with neglecting this feature, don't implement it at all. Most users are incapable of providing reliably secret answers to security questions.
Registration: You want at least a CAPTCHA here.
XSS Prevention: This is part of any secure web application, not specific to your login form. That said, HTMLPurifier is pretty reliable if you want to allow HTML and htmlentities($input, ENT_QUOTES | ENT_HTML5, 'UTF-8') is great if you don't want to allow HTML.
This is a subject I am hoping to answer through a series of very thorough blog posts on the Paragon Initiative Enterprises blog.

Is a PHP session secure?

Now I don't care about data transmission - no man-in-the-middle, that's work of http and https.
As far as I know PHP identifies sessions with the http cookie. But what happens if anyone tries bruteforce guessing session ids?
Its safe to assume that nothing is secure..
http://en.wikipedia.org/wiki/Session_hijacking
https://www.owasp.org/index.php/Session_hijacking_attack
http://www.serversidemagazine.com/php/session-hijacking/
Andreas Bogk made some very reasonable recommendations about a year ago to address a cryptographic weakness in the session key generation logic in PHP versions 5.3.2 and earlier that made PHP sessions more vulnerable to "session hijacking" (which seems to be your primary concern) than they ought to have been.
And Przemek Sobstel wrote a generic catalogue of attack types (including session hijacking) targeting the PHP session mechanism over 4 years ago, along with suggestions for mitigating them. The latest PHP version has changed several times since then, as has the "threat landscape". But the attack types have not changed much since then, and neither have the recommended best practices.
If you want to quantify your risk exposure, then you're going to have to define your scenario (implementation, environment, etc.) more precisely.
But what happens if anyone tries bruteforce of guessing session ids?
they would be aging...

PHP Session Security: usefulness of checking $_SESSION['HTTP_USER_AGENT']

Threads such as PHP Session Fixation / Hijacking and some people like Chris Shiflett recommend checking the user agent ( $_SESSION['HTTP_USER_AGENT'] ) to help check for session validity. Some resources even recommend something like this:
<?php
$string = $_SERVER['HTTP_USER_AGENT'];
$string .= 'SHIFLETT';
/* Add any other data that is consistent */
$fingerprint = md5($string);
?>
However, Chris Snyder says that "the universe of browser agents is miniscule in comparison to the universe of users, so it is impossible for each user to have an individual user agent. Furthermore, it isn't hard to spoof a user agent. And so there is little real point in checking this metric as a proof of session validity" (Chapter 7, pg 103).
It's very difficult to know what to do when one encounters conflicting advice, and when some of the advice may be out-of-date (such as the Shiflett/PHPSec example above, whose timestamp seems to be Friday, March 18, 2005). Newer advice such as Snyder's (date of publication: December 9, 2010) would seem to be better, but is this always so? (For example, in spite of spending a lot of time recommending the use of mysqli, Snyder completely ignores what Stack Overflow users seem to agree is the better choice -- PDO -- so I'm not totally sold on Snyder as the ultimate Trustworthy Expert).
So I guess my question has two parts, one specific (should I bother examining the user agent?) and one more general (whose advice should I trust when it comes to the latest thinking in PHP Security?), with my obvious bias being "trust the people on Stack Overflow!" -- or I wouldn't be asking in the first place, because crowd-sourcing the most current thinking is often the best idea.
Following useful discussion in the comments w/ #Radu, to clarify the HTTPS question --
Snyder seems to be saying two things: 1.) HTTPS makes other tools less necessary or unnecessary. 2.) In situations where one cannot use HTTPS, it is still not really useful to check the user agent (and this seems to be the point where he disagrees with some possibly older advice).
If the man in the middle can hijack the session ID, then he should have absolutely no problem in sending the same user agent, so I don't think this will get you anywhere. This is security by obscurity.
If you want real protection, use HTTPS.
The user agent is not totally fool proof by itself but it adds thin layer on top of other security. There is debate on what should go to fingerprint. But nonetheless it adds to defense-on-depth principle. You can set a cookie and use that in combination with user agent and specific word to make fingerprint.
My point is, it adds to security though little!
The problem with sessions is that you just need the session ID to use that session. If you know a valid session ID, you can use that session. That’s how sessions work.
Now some suggest to use an additional datum to verify the validity to use a certain session by a certain client. The user agent ID is such a suggested datum as it is some kind of unique (see Panoptoclick to test your own) and doesn’t change during the session (in opposite to some other informations provided by the client).
But this only lowers the likelihood of Session Fixation and prevents the accidental use of a foreign session in case of Session Hijacking. Because an attacker could try to obtain the victim’s user agent ID and spoof it when fixing or hijacking the session. And here it doesn’t matter whether you store the user agent ID in plain or as a (salted) hash.
Better use the already proven protection measures.

Login/Registration System with php and mysql

I would like to make a simple user login/registration system using PHP and mysql. I don't need to get any information beyond what is necessary for the user to log in and out. I want to make sure that the system is secure.
The way that I currently understand how it should work is:
Registration
User enters their email address and password and confirmation password.
The PHP script makes sure the passwords match and that the email is a valid address and is not already in the database.
It hashes the password along with a random salt and stores the salt and resulting hashed password in the database. (Is php's md5 function suitable for this? I am not quite sure how this part works.)
Store an email confirmation code in the database and send the given email address a link back to the website that contains that code for verification?
Login
User input their email address and password.
The server looks up the email in the database and retrieves the salt. Then hashes the salt with the password the user just provided to see if it matches the one in the database.
How do I make the session persist after login. With a PHP session? A cookie? What should get stored in the cookie for remembering the user between visits?
I basically would just like some verification that the process I am describing is an accurate and secure way of doing user registration/login. Also, what are some good tutorials with more information.
Is php's md5 function suitable for this?
MD5 is no longer considered secure; consider using PHP's newer built-in password hashing with the bcrypt algorithm which has variable computational complexity: PHP password_hash() and password_verify().
How do I make the session persist after login. With a php session? A cookie? What should get stored in the cookie for remembering the user between visits?
Ideally, you would use a PHP session to maintain state during a single visit, and if you would like to have a "remember my login" option, you would use a cookie that contains enough information to authenticate a returning user and restart a new session. There's a good article from 2004 on best practices regarding login cookies here: Persistent Login Cookie Best Practice. You might also be interested in a more modern (2015) solution to securely implementing "remember me" checkboxes.
Apart from these, I think whatever you have described is fine.
A few notes on some missing considerations:
PHP sessions typically already use cookies: the session ID is stored as one.
Sessions can be hijacked; you should also take steps to reduce the possibility (start by reading "PHP: Preventing Session Hijacking with token stored as a cookie?" and "What is the best way to prevent session hijacking?").
Related to hijacking is fixing, where an attacker picks the session ID. There are two ways of combatting this: set session.use_only_cookies (the default in PHP >= 5.3) and change the session ID when a user logs in with session_regenerate_id.
Also see the question "PHP Session Security" and article "PHP Security Guide: Sessions".
if you want a ready made solution
User Cake in php5
pretty much secure .. and stable.
Since Login systems are such an integral part of a website, you're screwed if it gets hacked. Unless you're doing this for educational purposes, I recommend finding a system that was created by someone that has experience in the field. You'll sleep soundly at night.
An example of a solid pre-built login system is tank auth, it's written for the Code Igniter framework. You might want to look at how this guy designed the system to get ideas on what's important if you decide to write your own.
Also just a note from experience, it takes more time to write a login system from scratch than it does to learn the code igniter framework and install tank auth.
Here's a recommendation: consider using a readily available framework that inherently provides such functionality. they are tried and tested. have a look at Kohana. It has an Auth module which takes care authentication.

Historical security flaws of popular PHP CMS's?

I'm creating a PHP CMS, one that I hope will be used by the public. Security is a major concern and I'd like to learn from some of the popular PHP CMS's like Wordpress, Joomla, Drupal, etc. What are some security flaws or vulnerabilities that they have they had in the past that I can avoid in my application and what strategies can I use to avoid them? What are other issues that I need to be concerned with that they perhaps didn't face as a vulnerability because they handled it correctly from the start? What additional security features or measures would you include, anything from minute details to system level security approaches? Please be as specific as possible. I'm generally aware of most of the usual attack vectors, but I want to make sure that all the bases are covered, so don't be afraid to mention the obvious as well. Assume PHP 5.2+.
Edit: I'm changing this to a community wiki. Even though Arkh's excellent answer is accepted, I'm still interested in further examples if you have them.
Cross-Site Request Forgery (CSRF)
Description :
The basic idea is to trick a user to a page where his browser will initiate a POST or GET request to the CMS you attack.
Imagine you know the email of a CMS powered site administrator. Email him some funny webpage with whatever you want in it. In this page, you craft a form with the data used by the admin panel of the CMS to create a new admin user. Send those data to the website admin panel, with the result in a hidden iframe of your webpage.
Voilà, you got your own administrator account made.
How to prevent it :
The usual way is to generate random short-lived (15mn to hour) nonce in all your forms. When your CMS receive a form data, it checks first if the nonce is alright. If not, the data is not used.
CMS examples :
CMS made simple
Joomla!
Drupal
ModX
More information :
On the wikipedia page and on the OWASP project.
Bad password storing
Description :
Imagine your database get hacked and published on something like wikileak. Knowing that a big part of your users use the same login and password for a lot of websites, do you want them to be easy to get ?
No. You need to mitigate the damages done if your database datas become public.
How to prevent it :
A first idea is to hash them. Which is a bad idea because of rainbow tables (even if the hash is not md5 but sha512 for example).
Second idea : add a unique random salt before hashing so the hackers has to bruteforce each password. The problem is, the hacker can compute a lot of hash fast.
So, the current idea is to make it slow to hash the passwords : you don't care because you don't do it often. But the attacker will cry when he gets from 1000 hash generated per ms to 1.
To ease the process, you can use the library phpass developped by some password guru.
CMS examples :
Joomla! : salted md5
ModX : md5
Typo3 : cleartext
Drupal : switched to phpass after this discussion.
More information :
The phpass page.
Cross Site Scripting (XSS)
Description
The goal of these attacks, is to make your website display some script which will be executed by your legitimate user.
You have two kind of these : persistent or not. The first one comes usually from something your user can save, the other count on parameters given by a request sent. Here is an example, not persistent :
<?php
if(!is_numeric($_GET['id'])){
die('The id ('.$_GET['id'].') is not valid');
}
?>
Now your attacker can just send links like http://www.example.com/vulnerable.php?id=<script>alert('XSS')</script>
How to prevent it
You need to filter everything you output to the client. The easiest way is to use htmlspecialchars if you don't want to let your user save any html. But, when you let them output html (either their own html or some generated from other things like bbcode) you have to be very careful. Here is an old example using the "onerror" event of the img tag : vBulletin vulnerability. Or you have the old Myspace's Samy.
CMS examples :
CMS made simple
Mura CMS
Drupal
ModX
More information :
You can check wikipedia and OWASP. You also have a lot of XSS vector on ha.ckers page.
Mail header injection
Description :
Mail headers are separated by the CRLF (\r\n) sequence. When you use some user data to send mails (like using it for the From: or To:) they can inject more headers. With this, they can send anonymous mails from your server.
How to prevent it :
Filter all the \n, \r, %0a and %0d characters in your headers.
CMS examples :
Jetbox CMS
More information :
Wikipedia is a good start as usual.
SQL Injection
Description :
The old classic. It happen when you form a SQL query using direct user input. If this input is crafted like needed, a user can do exactly what he want.
How to prevent it :
Simple. Don't form SQL queries with user input. Use parameterized queries.
Consider any input which is not coded by yourself as user input, be it coming from the filesystem, your own database or a webservice for example.
CMS example :
Drupal
Joomla!
ModX
Pars CMS
More information :
Wikipedia and OWASP have really good pages on the subject.
Http response splitting
Description :
Like e-mail headers, the http headers are separated by the CLRF sequence. If your application uses user input to output headers, they can use this to craft their own.
How to prevent it :
Like for emails, filter \n, \r, %0a and %0d characters from user input before using it as part of a header. You can also urlencode your headers.
CMS examples :
Drake CMS
Plone CMS
Wordpress
More information :
I'll let you guess a little as to where you can find a lot of infos about this kind of attack. OWASP and Wikipedia.
Session hijacking
Description :
In this one, the attacker want to use the session of another legitimate (and hopefully authenticated) user.
For this, he can either change his own session cookie to match the victim's one or he can make the victim use his (the attacker's) own session id.
How to prevent it :
Nothing can be perfect here :
- if the attacker steal the victim's cookie, you can check that the user session matches the user IP. But this can render your site useless if legitimate users use some proxy which change IP often.
- if the attacker makes the user use his own session ID, just use session_regenerate_id to change the session ID of a user when his rights change (login, logout, get in admin part of the website etc.).
CMS examples :
Joomla! and Drupal
Zen Cart
More information :
Wikipedia page on the subject.
Other
User DoSing : if you prevent bruteforcing of login attempt by disabling the usernames tried and not the IP the attempts come from, anyone can block all your users in 2mn. Same thing when generating new passwords : don't disable the old one until the user confirm the new one (by loging with it for example).
Using user input to do something on your filesystem. Filter this like if it was cancer mixed with aids. This concern the use of include and require on files which path is made in part from the user input.
Using eval, system, exec or anything from this kind with user input.
Don't put files you don't want web accessible in web accessible directory.
You have a lot of things you can read on the OWASP page.
I remember a rather funny one from phpBB. The autologin cookie contained a serialized array containing a userId and encrypted password (no salt). Change the password to a boolean with value true and you could log in as anyone you wanted to be. Don't you love weaktyped languages?
Another issue that phpBB had was in an regular expression for the highlighting of search keywords that had a callback (with the e modifier), which enabled you to execute your own PHP code - for example, system calls on unsecure systems or just output the config file to get the MySQL login/password.
So to sum this story up:
Watch out for PHP being weaktyped ( md5( "secretpass" ) == true ).
Be careful with all code that could be used in a callback (or worse, eval).
And of course there are the other issues already mentioned before me.
Another application level security issue that I've seen CMSes deal with is insufficiently authorizing page or function level access. In other words, security being set by only showing links when you are authorized to view those links, but not fully checking that the user account is authorized to view the page or use the functionality once they are on the page.
In other words, an admin account has links displayed to go to user management pages. But the user management page only checks that the user is logged in, not that they are logged in and admin. A regular user then logs in, manually types in the admin page URI, then has full admin access to the user management pages and makes their account into an admin account.
You'd be surprised how many times I've seen things like that even in shopping cart applications where user CC data is viewable.
The biggest one that so many people seem to either forget or not realise is that anyone can post any data to your scripts, including cookies and sessions etc. And don't forget, just because a user is logged in, doesn't mean they can do any action.
For example, if you had a script that handles the adding/editing of a comment, you might have this:
if ( userIsLoggedIn() ) {
saveComment( $_POST['commentid'], $_POST['commenttext'] )
}
Can you see what's wrong? You checked that the user is logged in, but you didn't check if the user owns the comment, or is able to edit the comment. Which means any logged-in user could post a comment ID and content and edit others' comments!
Another thing to remember when providing software to others is that server set ups vary wildly. When data is posted you may want to do this, for example:
if (get_magic_quotes_gpc())
$var = stripslashes($_POST['var']);
else
$var = $_POST['var'];
So so many..
A number of answers here are listing specific vuls they remember or generic "things i worry about when writing a webapp", but if you want a reasonably reliable list of a majority of reported vulnerabilities found historically, then you wouldn't do much worse than to search the National Vulnerability Database
There are 582 vulnerabilities reported in Joomla or Joomla addons, 199 for Wordpress and 345 for Drupal for you to digest.
For generic understanding of common webapp vuls, the OWASP Top Ten project has recently been updated and is an essential read for any web developer.
A1: Injection
A2: Cross-Site Scripting (XSS)
A3: Broken Authentication and Session Management
A4: Insecure Direct Object References
A5: Cross-Site Request Forgery (CSRF)
A6: Security Misconfiguration
A7: Insecure Cryptographic Storage
A8: Failure to Restrict URL Access
A9: Insufficient Transport Layer Protection
A10: Unvalidated Redirects and Forwards
Four big ones in my mind:
using exec on untrusted data/code (or in general)
include-ing files from remote URL's for local execution
enabling register globals so that get and post variables
get variable values automatically assigned.
not escaping db entered data/ allowing SQL injection attacks
(usually happens when not using a DB API layer)
Disallow POST from other domain/IP So Bots cant login/submit forms.
People, the biggest security breech, is the human stupidity. Trust, review code. You need a special team, which will review anything that added as an extra code in your application, cms's problem are the outsource, the incomings, WordPress, Drupal, Joomla, and other popular cms, like default installations, they are really in a very good point secure. The problem is coming when you leave people to add extra code in your application, without a good review (or better, without penetration testing). This is the point where WordPress and Joomla have the weakness, there re so many plugin n theme devs, there are so many approvals,hundreds of outdated plugins n themes outhere.... So imho, if you are able to build a strong team, a good security plan, train your contributors, and learn them how to code secure, and with all the other comments before mine, then you will be able to move on and say :ei hi that's my cms, and it's a bit more secure than all the other cms on the net ;)
Here's a potential pitfall for forum admins especially, but also anyone who codes up a form with a dropdown selector but doesn't validate that the posted response was actually one of the available options.
In college, I realized that the user's 'country' selector in phpBB had no such validation.
In our school forum, Instead of 'United States' or 'Afganistan', my country could be ANYTHING, no matter how silly, or filthy. All I needed was an html POST form. It took my classmates a few days to figure out how I had done it, but soon, all the 'cool kids' had funny phrases instead of countries displayed under their usernames.
Going to a geek college was awesome. :D

Categories