Different nonces in CSP header and in HTML

Hi all,

I use:
Nextcloud version (eg, 12.0.2): 13.0.6
Operating system and version (eg, Ubuntu 17.04): Debian 9
Apache or nginx version (eg, Apache 2.4.25): Nginx 1.14
PHP version (eg, 7.1): 7.0.30-0+deb9u1

The issue you are facing:

I have a problem that CSP header shows different nonce than I see in HTML.

script-src 'nonce-anJEM0lLR1E0VDZEbjljWEZaVThra3dVRVVYODE1WjREemFma0dxcW1jaz06dUlHbldlRGNsbmI1cmFWR1djWUU5Q2RXVUJiS2x2c2RWM0R6cFZuTzd2QT0=' 'unsafe-eval';

But in HTML I see:

<script nonce="OFdjQldYZzVmNmRIK0xrcy9ZRHRqQXYycFF5ajJLU1FTTFo0MFArcmtDOD06eDFaUklEbDFDTzg5eXN0OXNkUFY2bUMwNUYrVm1jbjFFUEFVNWN6UDV4WT0=" defer src="/core/vendor/core.js?v=53c05fc6-6"></script>

And console in Firefox shows this message on every page load:

Refused to execute inline script because it violates the following Content Security Policy directive: inline («script-src»).

Is this the first time you’ve seen this error? (Y/N): Y

Steps to replicate it:

  1. I’ve used previous versions on NC without problems
  2. Updated from 13.0.5 to 13.0.6
  3. Just can’t login with TOTP, disable TOTP from logged place and some other things.

The output of your Nextcloud log in Admin > Logging:
When I try to use TOTP code I get this:

	Exception: HMAC does not match.

    /var/www/nextcloud/apps/twofactor_totp/lib/Service/Totp.php - line 131: OC\Security\Crypto->decrypt(*** sensitive parameters replaced ***)
    /var/www/nextcloud/apps/twofactor_totp/lib/Provider/TotpProvider.php - line 93: OCA\TwoFactorTOTP\Service\Totp->validateSecret(Object(OC\User\User), '734892')
    /var/www/nextcloud/lib/private/Authentication/TwoFactorAuth/Manager.php - line 215: OCA\TwoFactorTOTP\Provider\TotpProvider->verifyChallenge(*** sensitive parameters replaced ***)
    /var/www/nextcloud/core/Controller/TwoFactorChallengeController.php - line 169: OC\Authentication\TwoFactorAuth\Manager->verifyChallenge(*** sensitive parameters replaced ***)
    [internal function] OC\Core\Controller\TwoFactorChallengeController->solveChallenge(*** sensitive parameters replaced ***)
    /var/www/nextcloud/lib/private/AppFramework/Http/Dispatcher.php - line 161: call_user_func_array(Array, Array)
    /var/www/nextcloud/lib/private/AppFramework/Http/Dispatcher.php - line 91: OC\AppFramework\Http\Dispatcher->executeController(Object(OC\Core\Controller\TwoFactorChallengeController), 'solveChallenge')
    /var/www/nextcloud/lib/private/AppFramework/App.php - line 115: OC\AppFramework\Http\Dispatcher->dispatch(Object(OC\Core\Controller\TwoFactorChallengeController), 'solveChallenge')
    /var/www/nextcloud/lib/private/AppFramework/Routing/RouteActionHandler.php - line 47: OC\AppFramework\App main('OC\\Core\\Control...', 'solveChallenge', Object(OC\AppFramework\DependencyInjection\DIContainer), Array)
    [internal function] OC\AppFramework\Routing\RouteActionHandler->__invoke(Array)
    /var/www/nextcloud/lib/private/Route/Router.php - line 297: call_user_func(Object(OC\AppFramework\Routing\RouteActionHandler), Array)
    /var/www/nextcloud/lib/base.php - line 999: OC\Route\Router->match('/login/challeng...')
    /var/www/nextcloud/index.php - line 42: OC handleRequest()
    {main}

The output of your config.php file in /path/to/nextcloud (make sure you remove any identifiable information!):

<?php
$CONFIG = array (
  'instanceid' => '*******',
  'passwordsalt' => '***************',
  'secret' => '**********',
  'trusted_domains' =>
  array (
    0 => 'cloud.*****.me',
  ),
  'datadirectory' => '/mnt/***/nextcloud_data',
  'overwrite.cli.url' => 'https://cloud.******.me',
  'dbtype' => 'mysql',
  'version' => '13.0.6.1',
  'dbname' => 'nextcloud',
  'dbhost' => 'localhost',
  'dbtableprefix' => 'oc_',
  'dbuser' => 'nextcloud',
  'mysql.utf8mb4' => true,
  'trashbin_retention_obligation' => 'auto',
  'versions_retention_obligation' => 'auto, 5',
  'installed' => true,
  'loglevel' => 2,
  'logdateformat' => 'F d, Y H:i:s',
  'log_rotate_size' => 20971520,
  'theme' => 'compact',
  'remember_login_cookie_lifetime' => 1296000,
  'session_lifetime' => 259200,
  'session_keepalive' => true,
  'maintenance' => false,
  'logfile' => '/var/log/nextcloud/nextcloud.log',
  'appstore.experimental.enabled' => true,
  'debug' => false,
  'memcache.local' => '\\OC\\Memcache\\APCu',
  'memcache.locking' => '\\OC\\Memcache\\Redis',
  'redis' =>
  array (
    'host' => '/var/run/redis/redis.sock',
    'port' => 0,
  ),
  'dbpassword' => '********************',
  'mail_from_address' => 'cloud',
  'mail_smtpmode' => 'php',
  'mail_domain' => '**********.me',
  'filesystem_check_changes' => 1,
  'updater.release.channel' => 'stable',
  'dbport' => '',
);

The output of your Apache/nginx/system log in /var/log/____:

Nothing suspicious

Same issue with 2 recent upgrades.

1 Like

this is caused by the http server providing $_SERVER[‘CSP_NONCE’] to php, which is the case if using apache module mod_cspnonce or providing this parameter through other means in nginx.

see
nextcloud/lib/private/Security/CSP/ContentSecurityPolicyNonceManager.php → getNonce()
I guess this is meant to use better random nonces from modules, but obviously not complete, because it does not use the server provided nonce for the csp header sent, but uses it only for script tags.

FIX:
unset the $_SERVER Variable in your nextcloud config.php:

$_SERVER['CSP_NONCE']='';
unset ($_SERVER['CSP_NONCE']);

this has to be done again after all updates, as update overwrites this.