Skip to content

Commit

Permalink
Merge pull request #36749 from nextcloud/backport/36689/stable25
Browse files Browse the repository at this point in the history
[stable25] Change X-Robots-Tag header from "none" to "noindex, nofollow"
  • Loading branch information
blizzz committed Mar 15, 2023
2 parents 5f2816a + b194d84 commit 892a804
Show file tree
Hide file tree
Showing 12 changed files with 80 additions and 37 deletions.
2 changes: 1 addition & 1 deletion .htaccess
Expand Up @@ -31,7 +31,7 @@
Header always set X-Permitted-Cross-Domain-Policies "none"

Header onsuccess unset X-Robots-Tag
Header always set X-Robots-Tag "none"
Header always set X-Robots-Tag "noindex, nofollow"

Header onsuccess unset X-XSS-Protection
Header always set X-XSS-Protection "1; mode=block"
Expand Down
4 changes: 2 additions & 2 deletions build/integration/features/carddav.feature
Expand Up @@ -46,7 +46,7 @@ Feature: carddav
|X-Content-Type-Options |nosniff|
|X-Frame-Options|SAMEORIGIN|
|X-Permitted-Cross-Domain-Policies|none|
|X-Robots-Tag|none|
|X-Robots-Tag|noindex, nofollow|
|X-XSS-Protection|1; mode=block|

Scenario: Exporting the picture of ones own contact
Expand All @@ -60,5 +60,5 @@ Feature: carddav
|X-Content-Type-Options |nosniff|
|X-Frame-Options|SAMEORIGIN|
|X-Permitted-Cross-Domain-Policies|none|
|X-Robots-Tag|none|
|X-Robots-Tag|noindex, nofollow|
|X-XSS-Protection|1; mode=block|
2 changes: 1 addition & 1 deletion build/integration/features/dav-v2.feature
Expand Up @@ -27,7 +27,7 @@ Feature: dav-v2
|X-Content-Type-Options |nosniff|
|X-Frame-Options|SAMEORIGIN|
|X-Permitted-Cross-Domain-Policies|none|
|X-Robots-Tag|none|
|X-Robots-Tag|noindex, nofollow|
|X-XSS-Protection|1; mode=block|
And Downloaded content should start with "Welcome to your Nextcloud account!"

Expand Down
4 changes: 2 additions & 2 deletions build/integration/features/webdav-related.feature
Expand Up @@ -53,7 +53,7 @@ Feature: webdav-related
And User "user0" moves file "/textfile0.txt" to "/testshare/textfile0.txt"
And the HTTP status code should be "403"
When Downloading file "/testshare/textfile0.txt"
Then the HTTP status code should be "404"
Then the HTTP status code should be "404"

Scenario: Moving a file to overwrite a file in a folder with no permissions
Given using old dav path
Expand Down Expand Up @@ -251,7 +251,7 @@ Feature: webdav-related
|X-Content-Type-Options |nosniff|
|X-Frame-Options|SAMEORIGIN|
|X-Permitted-Cross-Domain-Policies|none|
|X-Robots-Tag|none|
|X-Robots-Tag|noindex, nofollow|
|X-XSS-Protection|1; mode=block|
And Downloaded content should start with "Welcome to your Nextcloud account!"

Expand Down
4 changes: 2 additions & 2 deletions core/js/setupchecks.js
Expand Up @@ -628,13 +628,13 @@
if (xhr.status === 200) {
var securityHeaders = {
'X-Content-Type-Options': ['nosniff'],
'X-Robots-Tag': ['none'],
'X-Robots-Tag': ['noindex, nofollow'],
'X-Frame-Options': ['SAMEORIGIN', 'DENY'],
'X-Permitted-Cross-Domain-Policies': ['none'],
};
for (var header in securityHeaders) {
var option = securityHeaders[header][0];
if(!xhr.getResponseHeader(header) || xhr.getResponseHeader(header).toLowerCase() !== option.toLowerCase()) {
if(!xhr.getResponseHeader(header) || xhr.getResponseHeader(header).replace(/, /, ',').toLowerCase() !== option.replace(/, /, ',').toLowerCase()) {
var msg = t('core', 'The "{header}" HTTP header is not set to "{expected}". This is a potential security or privacy risk, as it is recommended to adjust this setting accordingly.', {header: header, expected: option});
if(xhr.getResponseHeader(header) && securityHeaders[header].length > 1 && xhr.getResponseHeader(header).toLowerCase() === securityHeaders[header][1].toLowerCase()) {
msg = t('core', 'The "{header}" HTTP header is not set to "{expected}". Some features might not work correctly, as it is recommended to adjust this setting accordingly.', {header: header, expected: option});
Expand Down
89 changes: 66 additions & 23 deletions core/js/tests/specs/setupchecksSpec.js
Expand Up @@ -1569,7 +1569,7 @@ describe('OC.SetupChecks tests', function() {
msg: 'The "X-Content-Type-Options" HTTP header is not set to "nosniff". This is a potential security or privacy risk, as it is recommended to adjust this setting accordingly.',
type: OC.SetupChecks.MESSAGE_TYPE_WARNING
}, {
msg: 'The "X-Robots-Tag" HTTP header is not set to "none". This is a potential security or privacy risk, as it is recommended to adjust this setting accordingly.',
msg: 'The "X-Robots-Tag" HTTP header is not set to "noindex, nofollow". This is a potential security or privacy risk, as it is recommended to adjust this setting accordingly.',
type: OC.SetupChecks.MESSAGE_TYPE_WARNING
}, {
msg: 'The "X-Frame-Options" HTTP header is not set to "SAMEORIGIN". This is a potential security or privacy risk, as it is recommended to adjust this setting accordingly.',
Expand All @@ -1596,7 +1596,7 @@ describe('OC.SetupChecks tests', function() {
suite.server.requests[0].respond(
200,
{
'X-Robots-Tag': 'none',
'X-Robots-Tag': 'noindex, nofollow',
'X-Frame-Options': 'SAMEORIGIN',
'Strict-Transport-Security': 'max-age=15768000;preload',
'X-Permitted-Cross-Domain-Policies': 'none',
Expand Down Expand Up @@ -1627,7 +1627,7 @@ describe('OC.SetupChecks tests', function() {
{
'X-XSS-Protection': '1; mode=block',
'X-Content-Type-Options': 'nosniff',
'X-Robots-Tag': 'none',
'X-Robots-Tag': 'noindex, nofollow',
'X-Frame-Options': 'SAMEORIGIN',
'Strict-Transport-Security': 'max-age=15768000',
'X-Permitted-Cross-Domain-Policies': 'none',
Expand All @@ -1641,6 +1641,49 @@ describe('OC.SetupChecks tests', function() {
});
});

describe('check X-Robots-Tag header', function() {
it('should return no message if X-Robots-Tag is set to noindex,nofollow without space', function(done) {
protocolStub.returns('https');
var result = OC.SetupChecks.checkGeneric();
suite.server.requests[0].respond(200, {
'Strict-Transport-Security': 'max-age=15768000',
'X-XSS-Protection': '1; mode=block',
'X-Content-Type-Options': 'nosniff',
'X-Robots-Tag': 'noindex,nofollow',
'X-Frame-Options': 'SAMEORIGIN',
'X-Permitted-Cross-Domain-Policies': 'none',
'Referrer-Policy': 'no-referrer',
});
result.done(function( data, s, x ){
expect(data).toEqual([]);
done();
});
});

it('should return a message if X-Robots-Tag is set to none', function(done) {
protocolStub.returns('https');
var result = OC.SetupChecks.checkGeneric();
suite.server.requests[0].respond(200, {
'Strict-Transport-Security': 'max-age=15768000',
'X-XSS-Protection': '1; mode=block',
'X-Content-Type-Options': 'nosniff',
'X-Robots-Tag': 'none',
'X-Frame-Options': 'SAMEORIGIN',
'X-Permitted-Cross-Domain-Policies': 'none',
'Referrer-Policy': 'no-referrer',
});
result.done(function( data, s, x ){
expect(data).toEqual([
{
msg: 'The "X-Robots-Tag" HTTP header is not set to "noindex, nofollow". This is a potential security or privacy risk, as it is recommended to adjust this setting accordingly.',
type: OC.SetupChecks.MESSAGE_TYPE_WARNING
}
]);
done();
});
});
});

describe('check X-XSS-Protection header', function() {
it('should return no message if X-XSS-Protection is set to 1; mode=block; report=https://example.com', function(done) {
protocolStub.returns('https');
Expand All @@ -1650,7 +1693,7 @@ describe('OC.SetupChecks tests', function() {
'Strict-Transport-Security': 'max-age=15768000',
'X-XSS-Protection': '1; mode=block; report=https://example.com',
'X-Content-Type-Options': 'nosniff',
'X-Robots-Tag': 'none',
'X-Robots-Tag': 'noindex, nofollow',
'X-Frame-Options': 'SAMEORIGIN',
'X-Permitted-Cross-Domain-Policies': 'none',
'Referrer-Policy': 'no-referrer',
Expand All @@ -1670,7 +1713,7 @@ describe('OC.SetupChecks tests', function() {
'Strict-Transport-Security': 'max-age=15768000',
'X-XSS-Protection': '1; mode=block',
'X-Content-Type-Options': 'nosniff',
'X-Robots-Tag': 'none',
'X-Robots-Tag': 'noindex, nofollow',
'X-Frame-Options': 'SAMEORIGIN',
'X-Permitted-Cross-Domain-Policies': 'none',
'Referrer-Policy': 'no-referrer',
Expand All @@ -1690,7 +1733,7 @@ describe('OC.SetupChecks tests', function() {
'Strict-Transport-Security': 'max-age=15768000',
'X-XSS-Protection': '1',
'X-Content-Type-Options': 'nosniff',
'X-Robots-Tag': 'none',
'X-Robots-Tag': 'noindex, nofollow',
'X-Frame-Options': 'SAMEORIGIN',
'X-Permitted-Cross-Domain-Policies': 'none',
'Referrer-Policy': 'no-referrer',
Expand All @@ -1715,7 +1758,7 @@ describe('OC.SetupChecks tests', function() {
'Strict-Transport-Security': 'max-age=15768000',
'X-XSS-Protection': '0',
'X-Content-Type-Options': 'nosniff',
'X-Robots-Tag': 'none',
'X-Robots-Tag': 'noindex, nofollow',
'X-Frame-Options': 'SAMEORIGIN',
'X-Permitted-Cross-Domain-Policies': 'none',
'Referrer-Policy': 'no-referrer',
Expand All @@ -1742,7 +1785,7 @@ describe('OC.SetupChecks tests', function() {
'Strict-Transport-Security': 'max-age=15768000',
'X-XSS-Protection': '1; mode=block',
'X-Content-Type-Options': 'nosniff',
'X-Robots-Tag': 'none',
'X-Robots-Tag': 'noindex, nofollow',
'X-Frame-Options': 'SAMEORIGIN',
'X-Permitted-Cross-Domain-Policies': 'none',
'Referrer-Policy': 'no-referrer',
Expand All @@ -1762,7 +1805,7 @@ describe('OC.SetupChecks tests', function() {
'Strict-Transport-Security': 'max-age=15768000',
'X-XSS-Protection': '1; mode=block',
'X-Content-Type-Options': 'nosniff',
'X-Robots-Tag': 'none',
'X-Robots-Tag': 'noindex, nofollow',
'X-Frame-Options': 'SAMEORIGIN',
'X-Permitted-Cross-Domain-Policies': 'none',
'Referrer-Policy': 'no-referrer-when-downgrade',
Expand All @@ -1782,7 +1825,7 @@ describe('OC.SetupChecks tests', function() {
'Strict-Transport-Security': 'max-age=15768000',
'X-XSS-Protection': '1; mode=block',
'X-Content-Type-Options': 'nosniff',
'X-Robots-Tag': 'none',
'X-Robots-Tag': 'noindex, nofollow',
'X-Frame-Options': 'SAMEORIGIN',
'X-Permitted-Cross-Domain-Policies': 'none',
'Referrer-Policy': 'strict-origin',
Expand All @@ -1802,7 +1845,7 @@ describe('OC.SetupChecks tests', function() {
'Strict-Transport-Security': 'max-age=15768000',
'X-XSS-Protection': '1; mode=block',
'X-Content-Type-Options': 'nosniff',
'X-Robots-Tag': 'none',
'X-Robots-Tag': 'noindex, nofollow',
'X-Frame-Options': 'SAMEORIGIN',
'X-Permitted-Cross-Domain-Policies': 'none',
'Referrer-Policy': 'strict-origin-when-cross-origin',
Expand All @@ -1822,7 +1865,7 @@ describe('OC.SetupChecks tests', function() {
'Strict-Transport-Security': 'max-age=15768000',
'X-XSS-Protection': '1; mode=block',
'X-Content-Type-Options': 'nosniff',
'X-Robots-Tag': 'none',
'X-Robots-Tag': 'noindex, nofollow',
'X-Frame-Options': 'SAMEORIGIN',
'X-Permitted-Cross-Domain-Policies': 'none',
'Referrer-Policy': 'same-origin',
Expand All @@ -1842,7 +1885,7 @@ describe('OC.SetupChecks tests', function() {
'Strict-Transport-Security': 'max-age=15768000',
'X-XSS-Protection': '1; mode=block',
'X-Content-Type-Options': 'nosniff',
'X-Robots-Tag': 'none',
'X-Robots-Tag': 'noindex, nofollow',
'X-Frame-Options': 'SAMEORIGIN',
'X-Permitted-Cross-Domain-Policies': 'none',
'Referrer-Policy': 'origin',
Expand All @@ -1867,7 +1910,7 @@ describe('OC.SetupChecks tests', function() {
'Strict-Transport-Security': 'max-age=15768000',
'X-XSS-Protection': '1; mode=block',
'X-Content-Type-Options': 'nosniff',
'X-Robots-Tag': 'none',
'X-Robots-Tag': 'noindex, nofollow',
'X-Frame-Options': 'SAMEORIGIN',
'X-Permitted-Cross-Domain-Policies': 'none',
'Referrer-Policy': 'origin-when-cross-origin',
Expand All @@ -1892,7 +1935,7 @@ describe('OC.SetupChecks tests', function() {
'Strict-Transport-Security': 'max-age=15768000',
'X-XSS-Protection': '1; mode=block',
'X-Content-Type-Options': 'nosniff',
'X-Robots-Tag': 'none',
'X-Robots-Tag': 'noindex, nofollow',
'X-Frame-Options': 'SAMEORIGIN',
'X-Permitted-Cross-Domain-Policies': 'none',
'Referrer-Policy': 'unsafe-url',
Expand All @@ -1919,7 +1962,7 @@ describe('OC.SetupChecks tests', function() {
{
'X-XSS-Protection': '1; mode=block',
'X-Content-Type-Options': 'nosniff',
'X-Robots-Tag': 'none',
'X-Robots-Tag': 'noindex, nofollow',
'X-Frame-Options': 'SAMEORIGIN',
'X-Permitted-Cross-Domain-Policies': 'none',
'Referrer-Policy': 'no-referrer',
Expand Down Expand Up @@ -1965,7 +2008,7 @@ describe('OC.SetupChecks tests', function() {
{
'X-XSS-Protection': '1; mode=block',
'X-Content-Type-Options': 'nosniff',
'X-Robots-Tag': 'none',
'X-Robots-Tag': 'noindex, nofollow',
'X-Frame-Options': 'SAMEORIGIN',
'X-Permitted-Cross-Domain-Policies': 'none',
'Referrer-Policy': 'no-referrer',
Expand All @@ -1990,7 +2033,7 @@ describe('OC.SetupChecks tests', function() {
'Strict-Transport-Security': 'max-age=15551999',
'X-XSS-Protection': '1; mode=block',
'X-Content-Type-Options': 'nosniff',
'X-Robots-Tag': 'none',
'X-Robots-Tag': 'noindex, nofollow',
'X-Frame-Options': 'SAMEORIGIN',
'X-Permitted-Cross-Domain-Policies': 'none',
'Referrer-Policy': 'no-referrer',
Expand All @@ -2015,7 +2058,7 @@ describe('OC.SetupChecks tests', function() {
'Strict-Transport-Security': 'iAmABogusHeader342',
'X-XSS-Protection': '1; mode=block',
'X-Content-Type-Options': 'nosniff',
'X-Robots-Tag': 'none',
'X-Robots-Tag': 'noindex, nofollow',
'X-Frame-Options': 'SAMEORIGIN',
'X-Permitted-Cross-Domain-Policies': 'none',
'Referrer-Policy': 'no-referrer',
Expand All @@ -2039,7 +2082,7 @@ describe('OC.SetupChecks tests', function() {
'Strict-Transport-Security': 'max-age=15768000',
'X-XSS-Protection': '1; mode=block',
'X-Content-Type-Options': 'nosniff',
'X-Robots-Tag': 'none',
'X-Robots-Tag': 'noindex, nofollow',
'X-Frame-Options': 'SAMEORIGIN',
'X-Permitted-Cross-Domain-Policies': 'none',
'Referrer-Policy': 'no-referrer',
Expand All @@ -2059,7 +2102,7 @@ describe('OC.SetupChecks tests', function() {
'Strict-Transport-Security': 'max-age=99999999',
'X-XSS-Protection': '1; mode=block',
'X-Content-Type-Options': 'nosniff',
'X-Robots-Tag': 'none',
'X-Robots-Tag': 'noindex, nofollow',
'X-Frame-Options': 'SAMEORIGIN',
'X-Permitted-Cross-Domain-Policies': 'none',
'Referrer-Policy': 'no-referrer',
Expand All @@ -2079,7 +2122,7 @@ describe('OC.SetupChecks tests', function() {
'Strict-Transport-Security': 'max-age=99999999; includeSubDomains',
'X-XSS-Protection': '1; mode=block',
'X-Content-Type-Options': 'nosniff',
'X-Robots-Tag': 'none',
'X-Robots-Tag': 'noindex, nofollow',
'X-Frame-Options': 'SAMEORIGIN',
'X-Permitted-Cross-Domain-Policies': 'none',
'Referrer-Policy': 'no-referrer',
Expand All @@ -2099,7 +2142,7 @@ describe('OC.SetupChecks tests', function() {
'Strict-Transport-Security': 'max-age=99999999; preload; includeSubDomains',
'X-XSS-Protection': '1; mode=block',
'X-Content-Type-Options': 'nosniff',
'X-Robots-Tag': 'none',
'X-Robots-Tag': 'noindex, nofollow',
'X-Frame-Options': 'SAMEORIGIN',
'X-Permitted-Cross-Domain-Policies': 'none',
'Referrer-Policy': 'no-referrer',
Expand Down
2 changes: 1 addition & 1 deletion lib/private/legacy/OC_Response.php
Expand Up @@ -99,7 +99,7 @@ public static function addSecurityHeaders() {
header('X-Content-Type-Options: nosniff'); // Disable sniffing the content type for IE
header('X-Frame-Options: SAMEORIGIN'); // Disallow iFraming from other domains
header('X-Permitted-Cross-Domain-Policies: none'); // https://www.adobe.com/devnet/adobe-media-server/articles/cross-domain-xml-for-streaming.html
header('X-Robots-Tag: none'); // https://developers.google.com/webmasters/control-crawl-index/docs/robots_meta_tag
header('X-Robots-Tag: noindex, nofollow'); // https://developers.google.com/webmasters/control-crawl-index/docs/robots_meta_tag
header('X-XSS-Protection: 1; mode=block'); // Enforce browser based XSS filters
}
}
Expand Down
2 changes: 1 addition & 1 deletion lib/public/AppFramework/Http/Response.php
Expand Up @@ -258,7 +258,7 @@ public function getHeaders() {

$this->headers['Content-Security-Policy'] = $this->getContentSecurityPolicy()->buildPolicy();
$this->headers['Feature-Policy'] = $this->getFeaturePolicy()->buildPolicy();
$this->headers['X-Robots-Tag'] = 'none';
$this->headers['X-Robots-Tag'] = 'noindex, nofollow';

if ($this->ETag) {
$mergeWith['ETag'] = '"' . $this->ETag . '"';
Expand Down
2 changes: 1 addition & 1 deletion tests/data/setUploadLimit/htaccess
Expand Up @@ -11,7 +11,7 @@
# Add security and privacy related headers
Header set X-Content-Type-Options "nosniff"
Header set X-XSS-Protection "1; mode=block"
Header set X-Robots-Tag "none"
Header set X-Robots-Tag "noindex, nofollow"
Header set X-Frame-Options "SAMEORIGIN"
SetEnv modHeadersAvailable true
</IfModule>
Expand Down
2 changes: 1 addition & 1 deletion tests/lib/AppFramework/Controller/ControllerTest.php
Expand Up @@ -117,7 +117,7 @@ public function testFormatDataResponseJSON() {
'Content-Security-Policy' => "default-src 'none';base-uri 'none';manifest-src 'self';frame-ancestors 'none'",
'Feature-Policy' => "autoplay 'none';camera 'none';fullscreen 'none';geolocation 'none';microphone 'none';payment 'none'",
'X-Request-Id' => $this->request->getId(),
'X-Robots-Tag' => 'none',
'X-Robots-Tag' => 'noindex, nofollow',
];

$response = $this->controller->customDataResponse(['hi']);
Expand Down
2 changes: 1 addition & 1 deletion tests/lib/AppFramework/Http/DataResponseTest.php
Expand Up @@ -68,7 +68,7 @@ public function testConstructorAllowsToSetHeaders() {
'Cache-Control' => 'no-cache, no-store, must-revalidate',
'Content-Security-Policy' => "default-src 'none';base-uri 'none';manifest-src 'self';frame-ancestors 'none'",
'Feature-Policy' => "autoplay 'none';camera 'none';fullscreen 'none';geolocation 'none';microphone 'none';payment 'none'",
'X-Robots-Tag' => 'none',
'X-Robots-Tag' => 'noindex, nofollow',
'X-Request-Id' => \OC::$server->get(IRequest::class)->getId(),
];
$expectedHeaders = array_merge($expectedHeaders, $headers);
Expand Down
2 changes: 1 addition & 1 deletion tests/lib/AppFramework/Http/ResponseTest.php
Expand Up @@ -52,7 +52,7 @@ public function testSetHeaders() {
'Last-Modified' => 1,
'ETag' => 3,
'Something-Else' => 'hi',
'X-Robots-Tag' => 'none',
'X-Robots-Tag' => 'noindex, nofollow',
];

$this->childResponse->setHeaders($expected);
Expand Down

0 comments on commit 892a804

Please sign in to comment.