• 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Server config causing CSRF triggers

#1
Exclamation 
FreeBSD 11.0
Apache 2.4
MySQL 5.7
PHP 5.6.31

I've recently built, configured and security hardened this server and I installed opensourcepos which is a project I am contributing to.  With CSRF disabled I have no problems.  When enabled I initially could not login to the app.  I found that the line

Code:
Header edit Set-Cookie ^(.*)$ $1;HttpOnly;Secure

was causing CI CSRF protection to trigger.  IMO this was not a good design decision for CI to use the cookie for the  CSRF token because it prevents server-wide hardening such as the above to keep JavaScript from reading the cookie. While that may not be a problem on CI code, one has to keep in mind that there are likely other apps on the server which do not check for this sort of thing.  It would be better for CI to use a separate header for the CSRF token.

Alas, after commenting that line out I thought my problems were over because I could now log in, however I found that I was getting a HTTP 403 response when submitting changes in a form.  Like before, I believe it's CSRF triggering because when turned off in config.php the form submits fine.  I've attached a screenshot of the 403 response.

So far I've done the following to try to troubleshoot what was causing the problem:
- Set mod_security to DetectionOnly
- Set suhosin to SimulationMode in php.ini
- Commented out mod_evasive
- Commented out the following lines in my httpd.conf
Code:
#Security Directives
# ServerTokens Full
# ServerSignature Off
# FileETag None
# TraceEnable Off
# Header always append X-Frame-Options SAMEORIGIN
# Header set X-XSS-Protection "1; mode=block"
# Timeout 60
# MaxClients 64
# HostnameLookups Off
# RequestReadTimeout header=20-40,MinRate=500 body=20,MinRate=1000

#Require HTTP 1.1
# <IfModule mod_rewrite.c>
# RewriteCond %{THE_REQUEST} ^POST(.*)HTTP/(0\.9|1\.0)$ [NC]
# RewriteRule .* - [F,L]
# </IfModule>
- Commented out open_basedir, disable_functions in php.ini

But I'm getting the same behavior.  I've turned on logs in config.php and here is what it generates for the submit

Code:
INFO - 2017-08-22 14:39:22 --> Config Class Initialized
INFO - 2017-08-22 14:39:22 --> Hooks Class Initialized
DEBUG - 2017-08-22 14:39:22 --> UTF-8 Support Enabled
INFO - 2017-08-22 14:39:22 --> Utf8 Class Initialized
INFO - 2017-08-22 14:39:22 --> URI Class Initialized
INFO - 2017-08-22 14:39:22 --> Router Class Initialized
INFO - 2017-08-22 14:39:22 --> Output Class Initialized
INFO - 2017-08-22 14:39:22 --> Security Class Initialized
DEBUG - 2017-08-22 14:39:22 --> Global POST, GET and COOKIE data sanitized
INFO - 2017-08-22 14:39:22 --> CSRF cookie sent

No errors are generated by PHP, Suhosin, MySQL or mod_security... presumably because the CI CSRF kicks in with a 403 before that can happen.


Attached Files Thumbnail(s)
   
Reply

#2
(08-22-2017, 04:52 AM)objecttothis Wrote: was causing CI CSRF protection to trigger.  IMO this was not a good design decision for CI to use the cookie for the  CSRF token because it prevents server-wide hardening such as the above to keep JavaScript from reading the cookie. While that may not be a problem on CI code, one has to keep in mind that there are likely other apps on the server which do not check for this sort of thing.  It would be better for CI to use a separate header for the CSRF token.

CI has flags for this in config.php. We use CSRF tokens with both cookie_secure and cookie_httponly set to true and have no issues with bad tokens as long as they are only being used once.

In your screenshot, check the response tab. It will show a 403 if that is indeed what's happening. If it is ensure you're only the same token once unless csrf_regenerate is set to false.
Reply

#3
(08-22-2017, 07:18 AM)spjonez Wrote:
(08-22-2017, 04:52 AM)objecttothis Wrote: was causing CI CSRF protection to trigger.  IMO this was not a good design decision for CI to use the cookie for the  CSRF token because it prevents server-wide hardening such as the above to keep JavaScript from reading the cookie. While that may not be a problem on CI code, one has to keep in mind that there are likely other apps on the server which do not check for this sort of thing.  It would be better for CI to use a separate header for the CSRF token.

CI has flags for this in config.php. We use CSRF tokens with both cookie_secure and cookie_httponly set to true and have no issues with bad tokens as long as they are only being used once.

In your screenshot, check the response tab. It will show a 403 if that is indeed what's happening. If it is ensure you're only the same token once unless csrf_regenerate is set to false.

Yes, it is a 403, which is what CSRF is supposed to return when triggered if I understand correctly.  Below is the relevant section of my config.php.  Are you saying that I need to set cookie_secure and cookie_httponly to true? We are handling sessions through the database driver, not file system.

PHP Code:
/*
/*
|--------------------------------------------------------------------------
| Cookie Related Variables
|--------------------------------------------------------------------------
|
| 'cookie_prefix'   = Set a cookie name prefix if you need to avoid collisions
| 'cookie_domain'   = Set to .your-domain.com for site-wide cookies
| 'cookie_path'     = Typically will be a forward slash
| 'cookie_secure'   = Cookie will only be set if a secure HTTPS connection exists.
| 'cookie_httponly' = Cookie will only be accessible via HTTP(S) (no javascript)
|
| Note: These settings (with the exception of 'cookie_prefix' and
|       'cookie_httponly') will also affect sessions.
|
*/
$config['cookie_prefix'] = '';
$config['cookie_domain'] = '';
$config['cookie_path'] = '/';
$config['cookie_secure'] = FALSE;
$config['cookie_httponly'] = FALSE;

|--------------------------------------------------------------------------
Cross Site Request Forgery
|--------------------------------------------------------------------------
Enables a CSRF cookie token to be setWhen set to TRUEtoken will be
checked on a submitted form. If you are accepting user datait is strongly
recommended CSRF protection be enabled.
|
'csrf_token_name' The token name
'csrf_cookie_name' The cookie name
'csrf_expire' The number in seconds the token should expire.
'csrf_regenerate' Regenerate token on every submission
'csrf_exclude_uris' = Array of URIs which ignore CSRF checks
*/
$config['csrf_protection'] = TRUE;
$config['csrf_token_name'] = 'csrf_ospos_v3';
$config['csrf_cookie_name'] = 'csrf_cookie_ospos_v3';
$config['csrf_expire'] = 7200;
$config['csrf_regenerate'] = TRUE;
$config['csrf_exclude_uris'] = array(); 
Reply

#4
I was able to change cookie_httponly to TRUE and the app did not give me login errors, but I was not able to re-add the HttpOnly directive in my httpd.conf and it made no difference in the 403 error I am getting. cookie_secure cannot be set to true because the app needs to be accessible from both https and http connections and the flag effectively disables http connections.
Reply

#5
If possible you should enforce HTTPS for everything. It's required for HTTP/2 so if you ever want to use the new protocol you'll need to make that change eventually.
Reply

#6
@spjonez I agree with you but the app is used by a lot of people and not all of them have SSL certificates for their servers. Besides that CI currently supports HTTP/1.1 which does not require HTTPS.

You are missing my point:
- The issue I am having with CSRF happens on an SSL connection and a non-encrypted connection. Enabling both cookie_httponly and cookie_secure and connecting via HTTPS still produces the 403 error, but not 403 as soon as CSRF gets turned off in config.php. Since CSRF doesn't get tripped with other server implementations it tells me this is likely something to do with my FAMP stack and the way it's configured that does not play well with CSRF.
- My opinion about the CI implementation of CSRF was simply because it's preventing serverwide httponly via httpd.conf which is shortsighted because there are non-CI implemented apps on servers and it's nice to force XSS protection via apache without having to stick a .htaccess everywhere.
Reply

#7
Quote:The issue I am having with CSRF happens on an SSL connection and a non-encrypted connection. Enabling both cookie_httponly and cookie_secure and connecting via HTTPS still produces the 403 error, but not 403 as soon as CSRF gets turned off in config.php. Since CSRF doesn't get tripped with other server implementations it tells me this is likely something to do with my FAMP stack and the way it's configured that does not play well with CSRF.

CSRF is just a client cookie + server side session variable that are compared. If you don't set cookie_secure it will work for both HTTP and HTTPS the flag only prevents HTTP requests.

Quote:My opinion about the CI implementation of CSRF was simply because it's preventing serverwide httponly via httpd.conf which is shortsighted because there are non-CI implemented apps on servers and it's nice to force XSS protection via apache without having to stick a .htaccess everywhere.

Code can set a cookie any way it wants regardless of how a server is configured. If you're changing Apache defaults your code has to handle that. Personally I wouldn't configure the server and let the application decide how it should work. As long as the correct flags are set it doesn't matter which side does it but code gives you more flexibility.

I'm not really sure what your problem is?
Reply

#8
Quote:Code can set a cookie any way it wants regardless of how a server is configured. If you're changing Apache defaults your code has to handle that. Personally I wouldn't configure the server and let the application decide how it should work. As long as the correct flags are set it doesn't matter which side does it but code gives you more flexibility.

I'm not really sure what your problem is?

This is why there are uncounted number of compromised WordPress installations. Plugin developers that don't follow best practices and servers that aren't properly hardened don't prevent against these attacks...many of them just isolate the hacked sites so that it doesn't spread to other applications.

I don't know how I can be more clear as to what the problem is.
- I've hardened my FAMP stack and one or more of those customizations triggers CSRF in CI 3.1.2.
- Logs are enabled in the CI app but they aren't giving me anything.
- I need to debug to get down to what exactly is causing the issue.
- What I need is ideas for common Apache and PHP configuration parameters that are know to cause problems with CSRF and or ideas about how to get more information from CSRF than HTTP 403
Reply

#9
The CSRF token is only verified when
  1. $config['csrf_protection'] = TRUE; in config.php
  2. The server method is POST

Does your hardening turns every GET into a POST?

If the request is not POST, then the 403 errors are due to some reason other than CSRF.

When POSTing, the CSRF token_name/token_hash needs to be part of the posted data.
Reply

#10
(08-22-2017, 02:45 PM)dave friend Wrote: The CSRF token is only verified when
  1. $config['csrf_protection'] = TRUE; in config.php
  2. The server method is POST

Does your hardening turns every GET into a POST?

If the request is not POST, then the 403 errors are due to some reason other than CSRF.

When POSTing, the CSRF token_name/token_hash needs to be part of the posted data.

Thanks for the reply.  The request is indeed POST.  I looked through my configuration and I don't see anything indicating GET requests are being turned into POST.  I've attached redacted versions of my php.ini, httpd.conf and httpd-ssl.conf.  Perhaps someone can see something that I'm missing.

I wish I could view more of the output of CSRF, such as a verbose log of what exactly it's hanging up on.


Attached Files
.txt   httpd.txt (Size: 14.33 KB / Downloads: 6)
.txt   httpd-ssl.txt (Size: 2.24 KB / Downloads: 5)
.txt   php.txt (Size: 6.78 KB / Downloads: 5)
Reply


Digg   Delicious   Reddit   Facebook   Twitter   StumbleUpon  


Users browsing this thread:
1 Guest(s)


  Theme © 2014 iAndrew  
Powered By MyBB, © 2002-2017 MyBB Group.