EVOLUTION-MANAGER
Edit File: ngCsp.html
<a href='https://github.com/angular/angular.js/edit/v1.3.x/src/ng/directive/ngCsp.js?message=docs(ngCsp)%3A%20describe%20your%20change...#L3' class='improve-docs btn btn-primary'><i class="glyphicon glyphicon-edit"> </i>Improve this Doc</a> <a href='https://github.com/angular/angular.js/tree/v1.3.9/src/ng/directive/ngCsp.js#L3' class='view-source pull-right btn btn-primary'> <i class="glyphicon glyphicon-zoom-in"> </i>View Source </a> <header class="api-profile-header"> <h1 class="api-profile-header-heading">ngCsp</h1> <ol class="api-profile-header-structure naked-list step-list"> <li> - directive in module <a href="api/ng">ng</a> </li> </ol> </header> <div class="api-profile-description"> <p>Enables <a href="https://developer.mozilla.org/en/Security/CSP">CSP (Content Security Policy)</a> support.</p> <p>This is necessary when developing things like Google Chrome Extensions or Universal Windows Apps.</p> <p>CSP forbids apps to use <code>eval</code> or <code>Function(string)</code> generated functions (among other things). For Angular to be CSP compatible there are only two things that we need to do differently:</p> <ul> <li>don't use <code>Function</code> constructor to generate optimized value getters</li> <li>don't inject custom stylesheet into the document</li> </ul> <p>AngularJS uses <code>Function(string)</code> generated functions as a speed optimization. Applying the <code>ngCsp</code> directive will cause Angular to use CSP compatibility mode. When this mode is on AngularJS will evaluate all expressions up to 30% slower than in non-CSP mode, but no security violations will be raised.</p> <p>CSP forbids JavaScript to inline stylesheet rules. In non CSP mode Angular automatically includes some CSS rules (e.g. <a href="api/ng/directive/ngCloak">ngCloak</a>). To make those directives work in CSP mode, include the <code>angular-csp.css</code> manually.</p> <p>Angular tries to autodetect if CSP is active and automatically turn on the CSP-safe mode. This autodetection however triggers a CSP error to be logged in the console:</p> <pre><code>Refused to evaluate a string as JavaScript because 'unsafe-eval' is not an allowed source of script in the following Content Security Policy directive: "default-src 'self'". Note that 'script-src' was not explicitly set, so 'default-src' is used as a fallback. </code></pre> <p>This error is harmless but annoying. To prevent the error from showing up, put the <code>ngCsp</code> directive on the root element of the application or on the <code>angular.js</code> script tag, whichever appears first in the html document.</p> <p><em>Note: This directive is only available in the <code>ng-csp</code> and <code>data-ng-csp</code> attribute form.</em></p> </div> <div> <h2>Directive Info</h2> <ul> <li>This directive executes at priority level 0.</li> </ul> <h2 id="usage">Usage</h2> <div class="usage"> <ul> <li>as attribute: <pre><code><html> ... </html></code></pre> </li> </div> <h2 id="example">Example</h2><p>This example shows how to apply the <code>ngCsp</code> directive to the <code>html</code> tag.</p> <pre><code class="lang-html"><!doctype html> <html ng-app ng-csp> ... ... </html> </code></pre> <p>// Note: the suffix <code>.csp</code> in the example name triggers // csp mode in our http server! <div> <a ng-click="openPlunkr('examples/example-example.csp')" class="btn pull-right"> <i class="glyphicon glyphicon-edit"> </i> Edit in Plunker</a> <div class="runnable-example" path="examples/example-example.csp" name="example.csp" module="cspExample" ng-csp="true"> <div class="runnable-example-file" name="index.html" language="html" type="html"> <pre><code><div ng-controller="MainController as ctrl"> <div> <button ng-click="ctrl.inc()" id="inc">Increment</button> <span id="counter"> {{ctrl.counter}} </span> </div> <div> <button ng-click="ctrl.evil()" id="evil">Evil</button> <span id="evilError"> {{ctrl.evilError}} </span> </div> </div></code></pre> </div> <div class="runnable-example-file" name="script.js" language="js" type="js"> <pre><code>angular.module('cspExample', []) .controller('MainController', function() { this.counter = 0; this.inc = function() { this.counter++; }; this.evil = function() { // jshint evil:true try { eval('1+2'); } catch (e) { this.evilError = e.message; } }; });</code></pre> </div> <div class="runnable-example-file" name="protractor.js" type="protractor" language="js"> <pre><code>var util, webdriver; var incBtn = element(by.id('inc')); var counter = element(by.id('counter')); var evilBtn = element(by.id('evil')); var evilError = element(by.id('evilError')); function getAndClearSevereErrors() { return browser.manage().logs().get('browser').then(function(browserLog) { return browserLog.filter(function(logEntry) { return logEntry.level.value > webdriver.logging.Level.WARNING.value; }); }); } function clearErrors() { getAndClearSevereErrors(); } function expectNoErrors() { getAndClearSevereErrors().then(function(filteredLog) { expect(filteredLog.length).toEqual(0); if (filteredLog.length) { console.log('browser console errors: ' + util.inspect(filteredLog)); } }); } function expectError(regex) { getAndClearSevereErrors().then(function(filteredLog) { var found = false; filteredLog.forEach(function(log) { if (log.message.match(regex)) { found = true; } }); if (!found) { throw new Error('expected an error that matches ' + regex); } }); } beforeEach(function() { util = require('util'); webdriver = require('protractor/node_modules/selenium-webdriver'); }); // For now, we only test on Chrome, // as Safari does not load the page with Protractor's injected scripts, // and Firefox webdriver always disables content security policy (#6358) if (browser.params.browser !== 'chrome') { return; } it('should not report errors when the page is loaded', function() { // clear errors so we are not dependent on previous tests clearErrors(); // Need to reload the page as the page is already loaded when // we come here browser.driver.getCurrentUrl().then(function(url) { browser.get(url); }); expectNoErrors(); }); it('should evaluate expressions', function() { expect(counter.getText()).toEqual('0'); incBtn.click(); expect(counter.getText()).toEqual('1'); expectNoErrors(); }); it('should throw and report an error when using "eval"', function() { evilBtn.click(); expect(evilError.getText()).toMatch(/Content Security Policy/); expectError(/Content Security Policy/); });</code></pre> </div> <iframe class="runnable-example-frame" src="examples/example-example.csp/index.html" name="example-example.csp"></iframe> </div> </div> </p> </div>