diff --git a/.htaccess b/.htaccess
index 50c06d4e3aef9..60d71d7a1700a 100644
--- a/.htaccess
+++ b/.htaccess
@@ -285,10 +285,3 @@
## http://developer.yahoo.com/performance/rules.html#etags
#FileETag none
-
-############################################
-## Add custom headers
-
- Header set X-Content-Type-Options "nosniff"
- Header set X-XSS-Protection "1; mode=block"
-
diff --git a/app/code/Magento/Backend/etc/adminhtml/di.xml b/app/code/Magento/Backend/etc/adminhtml/di.xml
index 9656c43e0eb68..0647b8918755a 100644
--- a/app/code/Magento/Backend/etc/adminhtml/di.xml
+++ b/app/code/Magento/Backend/etc/adminhtml/di.xml
@@ -127,7 +127,7 @@
-
+
Magento\Framework\App\Response\HeaderProvider\XFrameOptions::BACKEND_X_FRAME_OPT
diff --git a/app/code/Magento/Cron/etc/adminhtml/system.xml b/app/code/Magento/Cron/etc/adminhtml/system.xml
index dd9131d8c1761..aa664b223304f 100644
--- a/app/code/Magento/Cron/etc/adminhtml/system.xml
+++ b/app/code/Magento/Cron/etc/adminhtml/system.xml
@@ -9,8 +9,8 @@
-
- For correct URLs generated during cron runs please make sure that Web > Secure and Unsecure Base URLs are explicitly set.
+
+ For correct URLs generated during cron runs please make sure that Web > Secure and Unsecure Base URLs are explicitly set. All the times are in minutes.
diff --git a/app/code/Magento/Cron/i18n/en_US.csv b/app/code/Magento/Cron/i18n/en_US.csv
index aba3563db9b5b..7f0fe4935b818 100644
--- a/app/code/Magento/Cron/i18n/en_US.csv
+++ b/app/code/Magento/Cron/i18n/en_US.csv
@@ -2,8 +2,8 @@
Daily,Daily
Weekly,Weekly
Monthly,Monthly
-"Cron (Scheduled Tasks) - all the times are in minutes","Cron (Scheduled Tasks) - all the times are in minutes"
-"For correct URLs generated during cron runs please make sure that Web > Secure and Unsecure Base URLs are explicitly set.","For correct URLs generated during cron runs please make sure that Web > Secure and Unsecure Base URLs are explicitly set."
+"Cron (Scheduled Tasks)","Cron (Scheduled Tasks)"
+"For correct URLs generated during cron runs please make sure that Web > Secure and Unsecure Base URLs are explicitly set. All the times are in minutes.","For correct URLs generated during cron runs please make sure that Web > Secure and Unsecure Base URLs are explicitly set. All the times are in minutes."
"Cron configuration options for group: ","Cron configuration options for group: "
"Generate Schedules Every","Generate Schedules Every"
"Schedule Ahead for","Schedule Ahead for"
diff --git a/app/code/Magento/PageCache/Model/App/FrontController/MessageBox.php b/app/code/Magento/PageCache/Model/App/FrontController/MessageBox.php
deleted file mode 100644
index 38d2e63c6e2fb..0000000000000
--- a/app/code/Magento/PageCache/Model/App/FrontController/MessageBox.php
+++ /dev/null
@@ -1,100 +0,0 @@
-cookieManager = $cookieManager;
- $this->cookieMetadataFactory = $cookieMetadataFactory;
- $this->request = $request;
- $this->config = $config;
- $this->messageManager = $messageManager;
- }
-
- /**
- * Set Cookie for msg box when it displays first
- *
- * @param FrontController $subject
- * @param \Magento\Framework\App\ResponseInterface|\Magento\Framework\Controller\ResultInterface $result
- *
- * @return \Magento\Framework\App\ResponseInterface|\Magento\Framework\Controller\ResultInterface
- * @SuppressWarnings(PHPMD.UnusedFormalParameter)
- */
- public function afterDispatch(FrontController $subject, $result)
- {
- if ($this->request->isPost() && $this->messageManager->hasMessages()) {
- $publicCookieMetadata = $this->cookieMetadataFactory->createPublicCookieMetadata()
- ->setDuration(self::COOKIE_PERIOD)
- ->setPath('/')
- ->setHttpOnly(false);
- $this->cookieManager->setPublicCookie(self::COOKIE_NAME, 1, $publicCookieMetadata);
- }
- return $result;
- }
-}
diff --git a/app/code/Magento/PageCache/Test/Unit/Model/App/FrontController/MessageBoxTest.php b/app/code/Magento/PageCache/Test/Unit/Model/App/FrontController/MessageBoxTest.php
deleted file mode 100644
index cec6b6f530382..0000000000000
--- a/app/code/Magento/PageCache/Test/Unit/Model/App/FrontController/MessageBoxTest.php
+++ /dev/null
@@ -1,148 +0,0 @@
-cookieManagerMock = $this->getMock('Magento\Framework\Stdlib\CookieManagerInterface');
- $this->cookieMetadataFactoryMock = $this->getMockBuilder(
- 'Magento\Framework\Stdlib\Cookie\CookieMetadataFactory'
- )->disableOriginalConstructor()
- ->getMock();
- $this->publicCookieMetadataMock = $this->getMockBuilder(
- 'Magento\Framework\Stdlib\Cookie\PublicCookieMetadata'
- )->disableOriginalConstructor()
- ->getMock();
- $this->requestMock = $this->getMockBuilder('Magento\Framework\App\Request\Http')
- ->disableOriginalConstructor()
- ->getMock();
- $this->messageManagerMock = $this->getMockBuilder('Magento\Framework\Message\Manager')
- ->disableOriginalConstructor()
- ->getMock();
-
- $this->msgBox = (new ObjectManager($this))->getObject(
- 'Magento\PageCache\Model\App\FrontController\MessageBox',
- [
- 'cookieManager' => $this->cookieManagerMock,
- 'cookieMetadataFactory' => $this->cookieMetadataFactoryMock,
- 'request' => $this->requestMock,
- 'messageManager' => $this->messageManagerMock,
- ]
- );
-
- $this->objectMock = $this->getMock('Magento\Framework\App\FrontController', [], [], '', false);
- $this->responseMock = $this->getMock('Magento\Framework\App\ResponseInterface', [], [], '', false);
- }
-
- /**
- * @param bool $isPost
- * @param int $numOfCalls
- * @dataProvider afterDispatchTestDataProvider
- */
- public function testAfterDispatch($isPost, $numOfCalls)
- {
- $this->messageManagerMock->expects($this->exactly($numOfCalls))
- ->method('hasMessages')
- ->will($this->returnValue(true));
- $this->requestMock->expects($this->once())
- ->method('isPost')
- ->will($this->returnValue($isPost));
- $this->cookieMetadataFactoryMock->expects($this->exactly($numOfCalls))
- ->method('createPublicCookieMetadata')
- ->will($this->returnValue($this->publicCookieMetadataMock));
- $this->publicCookieMetadataMock->expects(($this->exactly($numOfCalls)))
- ->method('setDuration')
- ->with(MessageBox::COOKIE_PERIOD)
- ->will($this->returnValue($this->publicCookieMetadataMock));
- $this->publicCookieMetadataMock->expects(($this->exactly($numOfCalls)))
- ->method('setPath')
- ->with('/')
- ->will($this->returnValue($this->publicCookieMetadataMock));
- $this->publicCookieMetadataMock->expects(($this->exactly($numOfCalls)))
- ->method('setHttpOnly')
- ->with(false)
- ->will($this->returnValue($this->publicCookieMetadataMock));
- $this->cookieManagerMock->expects($this->exactly($numOfCalls))
- ->method('setPublicCookie')
- ->with(
- MessageBox::COOKIE_NAME,
- 1,
- $this->publicCookieMetadataMock
- );
- $this->assertSame($this->responseMock, $this->msgBox->afterDispatch($this->objectMock, $this->responseMock));
- }
-
- /**
- * Data provider
- *
- * @return array
- */
- public function afterDispatchTestDataProvider()
- {
- return [
- [true, 1],
- [false, 0],
- ];
- }
-}
diff --git a/app/code/Magento/PageCache/etc/frontend/di.xml b/app/code/Magento/PageCache/etc/frontend/di.xml
index 658dce3f72ed6..1d57d767e9904 100644
--- a/app/code/Magento/PageCache/etc/frontend/di.xml
+++ b/app/code/Magento/PageCache/etc/frontend/di.xml
@@ -9,7 +9,6 @@
-
diff --git a/app/code/Magento/PageCache/view/frontend/web/js/page-cache.js b/app/code/Magento/PageCache/view/frontend/web/js/page-cache.js
index 162a8412aeda8..26f394b98dd07 100644
--- a/app/code/Magento/PageCache/view/frontend/web/js/page-cache.js
+++ b/app/code/Magento/PageCache/view/frontend/web/js/page-cache.js
@@ -51,28 +51,6 @@ define([
return elements;
};
- /**
- * MsgBox Widget checks if message box is displayed and sets cookie
- */
- $.widget('mage.msgBox', {
- options: {
- msgBoxCookieName: 'message_box_display',
- msgBoxSelector: '.main div.messages'
- },
-
- /**
- * Creates widget 'mage.msgBox'
- * @private
- */
- _create: function () {
- if ($.mage.cookies.get(this.options.msgBoxCookieName)) {
- $.mage.cookies.clear(this.options.msgBoxCookieName);
- } else {
- $(this.options.msgBoxSelector).hide();
- }
- }
- });
-
/**
* FormKey Widget - this widget is generating from key, saves it to cookie and
*/
@@ -272,14 +250,12 @@ define([
domReady(function () {
$('body')
- .msgBox()
.formKey();
});
return {
'pageCache': $.mage.pageCache,
- 'formKey': $.mage.formKey,
- 'msgBox': $.mage.msgBox
+ 'formKey': $.mage.formKey
};
/**
diff --git a/app/code/Magento/Store/Model/HeaderProvider/Hsts.php b/app/code/Magento/Store/Model/HeaderProvider/Hsts.php
index 155dac3f6cffb..d9f8d01f41802 100644
--- a/app/code/Magento/Store/Model/HeaderProvider/Hsts.php
+++ b/app/code/Magento/Store/Model/HeaderProvider/Hsts.php
@@ -18,14 +18,14 @@ class Hsts extends \Magento\Framework\App\Response\HeaderProvider\AbstractHeader
*
* @var string
*/
- protected $name = 'Strict-Transport-Security';
+ protected $headerName = 'Strict-Transport-Security';
/**
* Strict-Transport-Security (HSTS) header value
*
* @var string
*/
- protected $value = 'max-age=31536000';
+ protected $headerValue = 'max-age=31536000';
/**
* @var \Magento\Framework\App\Config\ScopeConfigInterface
diff --git a/app/code/Magento/Store/Model/HeaderProvider/UpgradeInsecure.php b/app/code/Magento/Store/Model/HeaderProvider/UpgradeInsecure.php
index 7551836731dd2..1152263a21e63 100644
--- a/app/code/Magento/Store/Model/HeaderProvider/UpgradeInsecure.php
+++ b/app/code/Magento/Store/Model/HeaderProvider/UpgradeInsecure.php
@@ -18,14 +18,14 @@ class UpgradeInsecure extends \Magento\Framework\App\Response\HeaderProvider\Abs
*
* @var string
*/
- protected $name = 'Content-Security-Policy';
+ protected $headerName = 'Content-Security-Policy';
/**
* Upgrade Insecure Requests header value
*
* @var string
*/
- protected $value = 'upgrade-insecure-requests';
+ protected $headerValue = 'upgrade-insecure-requests';
/**
* @var \Magento\Framework\App\Config\ScopeConfigInterface
diff --git a/app/code/Magento/Store/etc/di.xml b/app/code/Magento/Store/etc/di.xml
index 7ab703aff9262..b72ef3a7b1676 100644
--- a/app/code/Magento/Store/etc/di.xml
+++ b/app/code/Magento/Store/etc/di.xml
@@ -318,6 +318,8 @@
- Magento\Store\Model\HeaderProvider\Hsts
- Magento\Store\Model\HeaderProvider\UpgradeInsecure
+ - Magento\Framework\App\Response\HeaderProvider\XContentTypeOptions
+ - Magento\Framework\App\Response\HeaderProvider\XssProtection
diff --git a/dev/tests/js/jasmine/tests/app/code/Magento/PageCache/frontend/js/page-cache.test.js b/dev/tests/js/jasmine/tests/app/code/Magento/PageCache/frontend/js/page-cache.test.js
index 1f7a247a2faf1..3b2a4aad5f5c0 100644
--- a/dev/tests/js/jasmine/tests/app/code/Magento/PageCache/frontend/js/page-cache.test.js
+++ b/dev/tests/js/jasmine/tests/app/code/Magento/PageCache/frontend/js/page-cache.test.js
@@ -63,65 +63,7 @@ define([
expect(iframe.comments().length).toEqual(0);
});
});
-
- describe('Testing msgBox Widget', function () {
- var wdContainer,
- msgCookieName,
- msgContainer;
-
- beforeEach(function () {
- wdContainer = $('');
- msgContainer = $('');
- msgCookieName = 'FAKE_COOKIE';
- });
-
- afterEach(function () {
- $(wdContainer).remove();
- $(msgContainer).remove();
- });
-
- it('widget extends jQuery object', function () {
- expect($.fn.msgBox).toBeDefined();
- });
-
- it('widget gets options', function () {
- wdContainer.msgBox({
- 'msgBoxCookieName': msgCookieName
- });
- expect(wdContainer.msgBox('option', 'msgBoxCookieName')).toBe('FAKE_COOKIE');
- });
-
- it('widget disables cookie if it exist', function () {
- spyOn($.mage.cookies, 'get').and.returnValue('FAKE_MAGE_COOKIE');
- spyOn($.mage.cookies, 'clear');
-
- wdContainer.msgBox({
- 'msgBoxSelector': msgContainer
- });
-
- expect($.mage.cookies.get).toHaveBeenCalled();
- expect($.mage.cookies.clear).toHaveBeenCalled();
- });
-
- it('widget disables messageBox if cookie not exist', function () {
- spyOn($.mage.cookies, 'get');
-
- wdContainer.msgBox({
- 'msgBoxSelector': msgContainer
- });
-
- expect($.mage.cookies.get).toHaveBeenCalled();
- expect(msgContainer.is(':hidden')).toBeTruthy();
- });
-
- it('widget exist on load on body', function (done) {
- $(function () {
- expect($('body').data('mageMsgBox')).toBeDefined();
- done();
- });
- });
- });
-
+
describe('Testing FormKey Widget', function () {
var wdContainer,
msgCookieName,
diff --git a/lib/internal/Magento/Framework/App/ObjectManager/Environment/Developer.php b/lib/internal/Magento/Framework/App/ObjectManager/Environment/Developer.php
index 09d25c7de4d1b..df2a6ceee56e0 100644
--- a/lib/internal/Magento/Framework/App/ObjectManager/Environment/Developer.php
+++ b/lib/internal/Magento/Framework/App/ObjectManager/Environment/Developer.php
@@ -62,6 +62,7 @@ public function getObjectManagerConfigLoader()
*/
public function configureObjectManager(ConfigInterface $diConfig, &$sharedInstances)
{
+ $originalSharedInstances = $sharedInstances;
$objectManager = ObjectManager::getInstance();
$sharedInstances['Magento\Framework\ObjectManager\ConfigLoaderInterface'] = $objectManager
->get('Magento\Framework\App\ObjectManager\ConfigLoader');
@@ -80,5 +81,9 @@ public function configureObjectManager(ConfigInterface $diConfig, &$sharedInstan
$diConfig->setInterceptionConfig(
$objectManager->get('Magento\Framework\Interception\Config\Config')
);
+ /** Reset the shared instances once interception config is set so classes can be intercepted if necessary */
+ $sharedInstances = $originalSharedInstances;
+ $sharedInstances['Magento\Framework\ObjectManager\ConfigLoaderInterface'] = $objectManager
+ ->get('Magento\Framework\App\ObjectManager\ConfigLoader');
}
}
diff --git a/lib/internal/Magento/Framework/App/Response/HeaderProvider/AbstractHeaderProvider.php b/lib/internal/Magento/Framework/App/Response/HeaderProvider/AbstractHeaderProvider.php
index 25f71b47da315..476378dea6294 100644
--- a/lib/internal/Magento/Framework/App/Response/HeaderProvider/AbstractHeaderProvider.php
+++ b/lib/internal/Magento/Framework/App/Response/HeaderProvider/AbstractHeaderProvider.php
@@ -12,10 +12,10 @@
abstract class AbstractHeaderProvider implements \Magento\Framework\App\Response\HeaderProvider\HeaderProviderInterface
{
/** @var string */
- protected $name = '';
+ protected $headerName = '';
/** @var string */
- protected $value = '';
+ protected $headerValue = '';
/**
* Whether the header should be attached to the response
@@ -34,7 +34,7 @@ public function canApply()
*/
public function getName()
{
- return $this->name;
+ return $this->headerName;
}
/**
@@ -44,6 +44,6 @@ public function getName()
*/
public function getValue()
{
- return $this->value;
+ return $this->headerValue;
}
}
diff --git a/lib/internal/Magento/Framework/App/Response/HeaderProvider/XContentTypeOptions.php b/lib/internal/Magento/Framework/App/Response/HeaderProvider/XContentTypeOptions.php
new file mode 100644
index 0000000000000..5d8ef7bdf1f68
--- /dev/null
+++ b/lib/internal/Magento/Framework/App/Response/HeaderProvider/XContentTypeOptions.php
@@ -0,0 +1,17 @@
+value = $xFrameOpt;
+ $this->headerValue = $xFrameOpt;
}
}
diff --git a/lib/internal/Magento/Framework/App/Response/HeaderProvider/XssProtection.php b/lib/internal/Magento/Framework/App/Response/HeaderProvider/XssProtection.php
new file mode 100644
index 0000000000000..e0eaf9ad74bdb
--- /dev/null
+++ b/lib/internal/Magento/Framework/App/Response/HeaderProvider/XssProtection.php
@@ -0,0 +1,47 @@
+headerService = $headerService;
+ }
+
+ /**
+ * Header value. Must be disabled for IE 8.
+ *
+ * @return string
+ */
+ public function getValue()
+ {
+ return strpos($this->headerService->getHttpUserAgent(), self::IE_8_USER_AGENT) === false
+ ? self::HEADER_ENABLED
+ : self::HEADER_DISABLED;
+ }
+}
diff --git a/lib/internal/Magento/Framework/App/Test/Unit/ObjectManager/Environment/DeveloperTest.php b/lib/internal/Magento/Framework/App/Test/Unit/ObjectManager/Environment/DeveloperTest.php
index c86318181a2c0..6e7ddc94f3d26 100644
--- a/lib/internal/Magento/Framework/App/Test/Unit/ObjectManager/Environment/DeveloperTest.php
+++ b/lib/internal/Magento/Framework/App/Test/Unit/ObjectManager/Environment/DeveloperTest.php
@@ -5,6 +5,7 @@
*/
namespace Magento\Framework\App\Test\Unit\ObjectManager\Environment;
+use Magento\Framework\App\ObjectManager;
use Magento\Framework\App\ObjectManager\Environment\Developer;
class DeveloperTest extends \PHPUnit_Framework_TestCase
@@ -29,4 +30,61 @@ public function testGetObjectManagerConfigLoader()
{
$this->assertNull($this->_developer->getObjectManagerConfigLoader());
}
+
+ public function testConfigureObjectManager()
+ {
+ try {
+ $origObjectManager = ObjectManager::getInstance();
+ } catch (\Exception $e) {
+ $origObjectManager = null;
+ }
+
+
+ $objectManagerMock = $this->getMockBuilder('Magento\Framework\App\ObjectManager')
+ ->disableOriginalConstructor()
+ ->getMock();
+ ObjectManager::setInstance($objectManagerMock);
+ $diConfigMock = $this->getMockBuilder('\Magento\Framework\Interception\ObjectManager\ConfigInterface')
+ ->disableOriginalConstructor()
+ ->getMock();
+
+ $configLoaderMock = $this->getMockBuilder('Magento\Framework\App\ObjectManager\ConfigLoader')
+ ->disableOriginalConstructor()
+ ->getMock();
+ $configLoaderMock->expects($this->any())->method('load')->willReturn([]);
+ $omReturnMap = [
+ ['Magento\Framework\App\ObjectManager\ConfigLoader', $configLoaderMock],
+ [
+ 'Magento\Framework\Config\ScopeInterface',
+ $this->getMockBuilder('Magento\Framework\Config\ScopeInterface')
+ ->disableOriginalConstructor()
+ ->getMock()
+ ],
+ [
+ 'Magento\Framework\App\ObjectManager\ConfigCache',
+ $this->getMockBuilder('Magento\Framework\App\ObjectManager\ConfigCache')
+ ->disableOriginalConstructor()
+ ->getMock()
+ ],
+ [
+ 'Magento\Framework\Interception\Config\Config',
+ $this->getMockBuilder('Magento\Framework\Interception\Config\Config')
+ ->disableOriginalConstructor()
+ ->getMock()
+ ]
+ ];
+ $objectManagerMock->expects($this->any())->method('get')->willReturnMap($omReturnMap);
+
+ $sharedInstances = ['class_name' => 'shared_object'];
+ $this->_developer->configureObjectManager($diConfigMock, $sharedInstances);
+
+ $expectedSharedInstances = [
+ 'class_name' => 'shared_object',
+ 'Magento\Framework\ObjectManager\ConfigLoaderInterface' => $configLoaderMock
+ ];
+ $this->assertSame($expectedSharedInstances, $sharedInstances);
+ if (isset($origObjectManager)) {
+ ObjectManager::setInstance($origObjectManager);
+ }
+ }
}
diff --git a/lib/internal/Magento/Framework/App/Test/Unit/Response/HeaderProvider/XssProtectionTest.php b/lib/internal/Magento/Framework/App/Test/Unit/Response/HeaderProvider/XssProtectionTest.php
new file mode 100644
index 0000000000000..18d3d3e72df5d
--- /dev/null
+++ b/lib/internal/Magento/Framework/App/Test/Unit/Response/HeaderProvider/XssProtectionTest.php
@@ -0,0 +1,52 @@
+getMockBuilder('Magento\Framework\HTTP\Header')
+ ->disableOriginalConstructor()
+ ->getMock();
+ $headerServiceMock->expects($this->once())->method('getHttpUserAgent')->willReturn($userAgent);
+ $model = (new ObjectManager($this))->getObject(
+ 'Magento\Framework\App\Response\HeaderProvider\XssProtection',
+ ['headerService' => $headerServiceMock]
+ );
+ $this->assertSame($expectedHeader, $model->getValue());
+ }
+
+ /**
+ * @return array
+ */
+ public function userAgentDataProvider()
+ {
+ return [
+ [
+ 'user-agent' => 'Mozilla/5.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0; GTB7.4)',
+ 'expected-header' => XssProtection::HEADER_DISABLED
+ ],
+ [
+ 'user-agent' => 'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/4.0; GTB7.4)',
+ 'expected-header' => XssProtection::HEADER_ENABLED
+ ],
+ [
+ 'user-agent' => 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) Chrome/41.0.2227.1 Safari/537.36',
+ 'expected-header' => XssProtection::HEADER_ENABLED
+ ],
+ ];
+ }
+}
diff --git a/nginx.conf.sample b/nginx.conf.sample
index ecabf0b2b14bb..87b28aa9f691d 100644
--- a/nginx.conf.sample
+++ b/nginx.conf.sample
@@ -24,9 +24,6 @@ index index.php;
autoindex off;
charset off;
-add_header 'X-Content-Type-Options' 'nosniff';
-add_header 'X-XSS-Protection' '1; mode=block';
-
location /setup {
root $MAGE_ROOT;
location ~ ^/setup/index.php {