What are the implications of using 'low' security in cakephp? - security

I had an authentication problem in cakephp, when positing credentials from an external site the authentication would work, and then get immediately lost, with the site prompting for login information again.
This guy determined that the cakephp session cookie was changing. His solution was to set security to low.
Seems like in medium or high security Cake makes a double check for
referer... but with low security works fine when clicking auth-
protected links from external sites like hotmail or yahoo
This solution also worked for me, but what I am losing by setting cakephp to 'low' security?

When security is high, a new session ID get generated on every request. It is practically impossible to create a single-sign-on solution between two applications by sharing a session cookie in this case, since Cake will constantly change the session ID without notifying the other application.
When security is medium (or higher), session.referer_check is enabled.
When security is low, you don't have either of the above features, but it is still just as secure as any average PHP website/CMS out there.

The main thing that I know of is the session timeout, as per the app/config/core.php comments, in that your session timeout will be multiplied by a lower number.
The book backs this up,
The level of CakePHP security. The session timeout time defined in 'Session.timeout' is multiplied according to the settings here.
Valid values:
'high' = x 10
'medium' = x 100
'low' = x 300
'high' and 'medium' also enable session.referer_check
CakePHP session IDs are also regenerated between requests if 'Security.level' is set to 'high'.
Ref: http://book.cakephp.org/view/44/CakePHP-Core-Configuration-Variables
So the other thing looks to be the referrer checking.
session.referer_check contains the substring you want to check each HTTP Referer for. If the Referer was sent by the client and the substring was not found, the embedded session id will be marked as invalid. Defaults to the empty string.
So the looks of it, the things you are lose are the ability to accuratly determine who and which sessions you are dealing with.
I ran into a similar problem with losing sessions and many answers pointed to using $this->requestAction() as it will basically curl a request out of the app, so it can look like another session being created with a high security.
The other thing that many google answers threw up was turning off Session.checkAgent in your app/config/core.php as that meant the session would not be checked. This at least prevented me from losing the session information between page requests.
:)

two things happens when setting to 'low'
1)timeout is bigger
2)if session highjacking is easy, then it will be easier! since the session dosent regenerate between requests as when set to 'high'!
and nothing else.
by the way you can change for a specific page the security level or the session timeout or both... so it is not a no-undo-choice

I believe the only ramifications of setting this to low are that the session time is multiplied by 300 rather than 10 or 100 for high and medium respectively and the session refer check that you are having the issue with.
Update:
If you previously had this set to high, you would also loose out on the session id regeneration between requests.

Related

What is more secure concerning Cookies expiration time?

Concerning cookies expiration time what is the best practice for a secure application ?
The login system is a SSO that I can't manage, so the ["remember me"][1] option is not possible.
There are 2 solutions
Time expiration, the cookie would expire after a specific amount of time, i.e. 4 hours. But if the user use a shared computer and forgot to log out, another user could access the web application.
Session expiration, the cookie would expire after the web browser is closed (or [even worse][2]. But what if the user never close his session and always keep is computer turned on. The cookie would never expire even if the user doesn't need access to the web application.
Is there not a way to do both at the same time? Base the cookie expiration on the session with a maximum duration of time...
NB : Believing in a security aware user is a sweet dream, thus trust in the user log out is not feasible.
.
[1]: What is an acceptable expiration time for a cookie
[2]: When does a cookie with expiration time 'At end of session' expire?
Since no one else has taken a stab at this question, I'll hopefully get the ball rolling, lol. I'm not sure if this will exactly answer your question, but I'll try my best :).
I think that given the 2 solutions you have presented, along with the dependency of the user behavior, I really don't think there is a good answer in terms of "best practice" (which may also be subjective).
If both solutions were used (that is, a cookie that expires after a specific amount of time [i.e, 4 hours] OR at the end of a session) you would also take on the "con's" of each of those approaches. So, if the user forgets to log out within the expiration period and does not close their session, there is an issue.
So what I am saying is that in any case, the security is based on the user behavior and there will always be these flaws. Using a mix of solutions (defense-in-depth), as you have suggested, is a good line of thinking.

Harm of passing session id as url parameter

So I just noticed that one of the internet banks websites is passing session id as url parameter. ( See image below )
I didn't previously see anywhere that ';' in url, in this case it is after 'private;'.
1) What is the use of this ';'?
2) And why internet bank, which needs to be securest place in the internet is passing session id as url parameter?
At first, I thought they are doing it because some of the users disallow use of cookies, but then again, if they allow it, use cookies, if not - url, but I do allow use of cookies, so obviously thats not the case.
3) I guess then they should have some other security measures? What they could be?
4) And what one can possibly do if he knows others valid session id?
As I know, you can quite easily log into others peoples session if you know that id, because its not hard to edit cookies and its much easier to pass that session id as url parameter, especially if you have something like:
session_id($_GET[sessionid]);
Thanks!
1) You should ask whoever designed the application your red box is covering. URL can be anything you want; the convention of key=value&key2=value2 is just that - a convention. In this case, it's Java, and it commonly uses the convention of ;jsessionid=.... for its SID.
2) It's not that big of a deal. Normal users can't copy-paste cookies like they can copy-paste a GET parameter, but power users can do whatever they want (using Mechanize, wget, curl and other non-browser means, or even browser extensions). And if you allow it for some users and disallow for some, it's not really much of a security precaution, is it? Basically, cookie SID will make the attack a bit harder, but it's like putting your front door key under the mat - definitely doesn't keep your door secure. Additionally, cookies are shared between tabs: if a site wants you to be logged in with two accounts at once, you can't do it with cookies.
3) Serverside security, yes. One effective countermeasure is one-time SIDs (each time you visit a page, the server reads the session from the current SID, then starts a new session with a new SID for the next request). A less effective but still good method is to validate other information for consistency (e.g. - still same IP? Still same browser?)
4) Yes, if you know someone's valid SID, and the server does not adequately protect against session fixation, you can "become" that person. This might enable the attacker to, say, pay his bills with your money, for instance.
So, #Amadan correctly covered #1 and #4. But there's a bit more that needs expansion.
Using Session identifiers in a URL can be a major problem. There are a few cases where it's critically bad:
Session Hijacking:
If a user copy-pastes a URL into an email.
In this case, the attacker can simply read the email, and steal the session identifier (thereby resuming the session).
You could partially defend against this by making session lifetimes short, and validating things like IP addresses or User Agents in the session. Note that none of these are foolproof, they just make it "slightly" harder to attack.
If the connection is ever downgraded to HTTP.
If they are not using Http-Strict-Transport-Security (HSTS), then an attacker may be able to successfully downgrade the session to HTTP only (via MITM style attack). If the server isn't setup perfectly, this can cause the URL to leak to the attacker, and hence the session identifier.
Session Fixation Attacks
An attacker can craft a session identifier, and send the user a forged link with that session identifier. The user then logs in to the site, and the session is now tied to their account.
You can mitigate this by strictly rotating session identifiers every time the session changes (log in, log out, privilege upgrade or downgrade, etc). But many servers don't do this, and hence are susceptible to fixation style attacks.
The reason that cookie sessions are seen as more secure is not because they are harder to edit. It's because they are more resistant to fixation attacks (you can't create a URL or link or form or js or anything that sends a fraudulent cookie on behalf of the user).
Why the bank uses a URL parameter? I have two guesses:
Because they want to support those who don't allow cookies.
Which is sigh worthy.
They don't know any better.
Seriously. If it's not in a compliance doc or NIST recommendation, then they likely don't do it. Hell, there are implemented NIST recommendations that are known to be insecure, yet are still followed because it's in writing.
What is the use of this ;?
This is just a query string separator. & isn't the only sub-delim specified in the URL specification (RFC 3986).
And why internet bank, which needs to be securest place in the internet is passing session id as url parameter?
It could be that this session ID is never used, and the actual session identifier user is passed in cookies or in POST data between each navigated page. The only way to verify this is to try copying the URL into another browser to see if your session is resumed, however then again they may be checking things like User Agent - not real security but would dissuade casual attacks. Do not try this on a live system you do not have permission to do so on as it would be illegal. If you want to learn about security download something like Hacme Bank and try on there.
I guess then they should have some other security measures? What they could be?
No doubt they will, otherwise this would be a huge security threat. The URL could be leaked in the referer header if there are any external links on the page. The types of security a bank uses for their website is too large to list here, however they should be meeting certain industry standards such as ISO/IEC 27001 that will cover the types of threat that their site would need to be secure against.
And what one can possibly do if he knows others valid session id? As I know, you can quite easily log into others peoples session if you know that id, because its not hard to edit cookies and its much easier to pass that session id as url parameter, especially if you have something like:
As the ID is displayed on the screen it might be possible to read it (although IDs are generally long). A more realistic attack is Session Fixation. This is where an attacker can set the Session ID of their victim. For example, sending them a link that includes the attacker's Session ID. When the victim follows it and then logs in, as the attacker has the same session, they are logged in too.
Storing the Session information in a cookie or in a URL are both viable methods. A combination may used as
Security session management and (Server) Session management are separate aspects:
The fundamental difference is that cookies are shared between browser windows/tabs, the url not.
If you want your user to be logged on when navigating to the same site in different tab, sharing the security session (=without a new logon procedure) then cookies are a good way.
To differentiate "sessions" per tab and associate distinct server sessions with distinct tabs (Think of the user running two "stateful" transactions in two different tabs in parallel), managing a sessionId on the client which can be different per tab is required. Cookies won't work here.
Putting it in the URL is one way to assure this information is routinely added to requests fired from the page (referrer header). Alternative methods would require specific code to add this information explicitly to each request which is more work.
See How to differ sessions in browser-tabs?

Why do session stores have static timeouts/maxAge

I am using node.js + redis for session persistency, however I'm noticing that in nearly every example of redis store or other session persistence, there is a static maxAge or timeout for sessions that you can configure.
It makes sense to me that the session length should be based on the last interaction, and thus allow me to make an update on the timeout. Redis's documentation on its EXPIRE documentation has a section on refreshing the timeoutl
Is refreshing the session timeout bad by design? Should static timeouts always be used?
Edit
My original question was very general since I couldn't find documentation for my specific case and I assumed perhaps it was bad practice! I finally discovered how to do this with Connect + Node after looking at the source code:
Connect listens to the header end event (to know to update the session)
When the event fires, it asks the session store to save the session
Specifically as part of connect-redis, the save method updates the maxAge
In short, I was looking at the wrong place for documentation. Connect#session documents how if maxAge is assigned a new value, session stores (like connect-redis) should honor that.
There is no such thing as bad design, only bad choices.
Static Max Timeout
A good choice where security is of the utmost importance. Using a tight session timeout, especially with authentication, ensures that the end user is the intended user and not someone who dropped in while the principal user was away from his/her pc or device. The major downside to this approach is negative impact to user experience. The last thing you want is the session going stale just before the user was about to checkout or do something important; with a static timeout, this is inevitable and will happen often enough to piss off users.
Reset Timeout Based on Last Visit
It's safe to say most websites use this approach since it offers a good balance between security and user experience. Resetting the session timeout based on last visit eliminates the issue related to static max timeout, and most ecom and banking websites use this approach, so it's certainly an accepted approach.
Not knowing what you're actually building, I'd say going with the reset approach is probably a good choice nonetheless. The examples you mentioned likely omitted resetting the timeout for brevity reasons, not because it's a bad design.

How to remember the non-register user choice?

My website collect user comments about some images. Non registered user can click "Good" button. What is the best way to remeber by system the user choice? One person can click "Good" only one time. Cookies? Session? Other way?
First you have to realise that all session techniques are cookie based. That is all good techniques. That means that they all have the downside that they will not work where cookies do not work user choices will be forgotten. In those (hopefully rare) cases you could store these choices either in the URL or as a CGI parameter. In any cases you can not make it really secure.
That being said, you have tradeoffs to consider.
Cookies
If you use purely cookie based storage then you could be limited in the number of user choices that can be stored in cookies under a single domain name. RFC 6265 states some SHOULDs regarding those and implementation matching these will give you at most 200KB which should be quite enough. Older RFC 2965 says implementations should give you 80KB. Also remember that the browser will send you the cookie for every request to your website. This could mean slow browsing for your users.
Assuming a 24 bits image ID (16 million possible images), base64 encoded to 4 bytes you can pack close to 20,000 choices into cookies. For 32 bits image ID, encoded to 6 bytes you still get more than 10,000 choices into your cookies.
When cookies prove too cumbersome, say after 1,000 votes you could switch the browser into the session technique… Or consider that he will never get to this without having registered ;-)
Sessions
If you decide to store the user choices in the session then you will have to dedicate some storage area on the server. The downsides are that:
you have no safe way to know when a session is not used anymore. Therefore you need some mecanism to reclaim unused sessions, typically expiring sessions after a fixed amount of inactivity,
it is more difficult to scale if and when you want to distribute the load amongs multiple HTTP servers.
You create a unique "token" that you save as cookie (hash of IP + timestamp for example). This value is also beeing saved to the database in conjunction with the vote.

Best way to limit (and record) login attempts

Obviously some sort of mechanism for limiting login attempts is a security requisite. While I like the concept of an exponentially increasing time between attempts, what I'm not sure of storing the information. I'm also interested in alternative solutions, preferrably not including captchas.
I'm guessing a cookie wouldn't work due to blocking cookies or clearing them automatically, but would sessions work? Or does it have to be stored in a database? Being unaware of what methods can/are being used so I simply don't know what's practical.
Use some columns in your users table 'failed_login_attempts' and 'failed_login_time'. The first one increments per failed login, and resets on successful login. The second one allows you to compare the current time with the last failed time.
Your code can use this data in the db to determine how long it waits to lock out users, time between allowed logins etc
Assuming google has done the necessary usability testing (not an unfair assumption) and decided to use captchas , I'd suggest going along with them.
Increasing timeouts is frustrating when I'm a genuine user and have forgotten my password (with so many websites and their associated passwords that happens a lot , especially to me)
Storing attempts in the database is the best solution IMHO since it gives you the auditing records of the security breach attempts. Depending on your application this may or may not be a legal requirement.
By recording all bad attempts you can also gather higher level information, such as if the requests are coming from one IP address (i.e. someone / thing is attempting a brute force attack) so you can block the IP address. This can be VERY usefull information.
Once you have determined a threshold, why not force them to request the email to be sent to their email address (i.e. similar to 'I have forgotten my password'), or you can go for the CAPCHA approach.
Answers in this post prioritize database centered solutions because they provide a structure of records that make auditing and lockout logic convenient.
While the answers here address guessing attacks on individual users, a major concern with this approach is that it leaves the system open to Denial of Service attacks. Any and every request from the world should not trigger database work.
An alternative (or additional) layer of security should be implemented earlier in the req/ res cycle to protect the application and database from performing lock out operations that can be expensive and are unnecessary.
Express-Brute is an excellent example that utilizes Redis caching to filter out malicious requests while allowing honest ones.
You know which userid is being hit, keep a flag and when it reaches a threshold value simply stop accepting anything for that user. But that means you store an extra data value for every user.
I like the concept of an exponentially increasing time between attempts, [...]
Instead of using exponentially increasing time, you could actually have a randomized lag between successive attempts.
Maybe if you explain what technology you are using people here will be able to help with more specific examples.
Lock out Policy is all well and good but there is a balance.
One consideration is to think about the consruction of usernames - guessable? Can they be enumerated at all?
I was on an External App Pen Test for a dotcom with an Employee Portal that served Outlook Web Access /Intranet Services, certain Apps. It was easy to enumerate users (the Exec /Managament Team on the web site itself, and through the likes of Google, Facebook, LinkedIn etc). Once you got the format of the username logon (firstname then surname entered as a single string) I had the capability to shut 100's of users out due to their 3 strikes and out policy.
Store the information server-side. This would allow you to also defend against distributed attacks (coming from multiple machines).
You may like to say block the login for some time say for example, 10 minutes after 3 failure attempts for example. Exponentially increasing time sounds good to me. And yes, store the information at the server side session or database. Database is better. No cookies business as it is easy to manipulate by the user.
You may also want to map such attempts against the client IP adrress as it is quite possible that valid user might get a blocked message while someone else is trying to guess valid user's password with failure attempts.

Resources