Test Protractor with HTTP headers: (X-)Content-Security-Policy

Is it possible to use Protractor to test the HTTP headers sent along with the main HTML page? Specifically, I am interested in testing for the presence of security-related headers like X-Content-Security-Policy:

Content-Security-Policy: default-src 'none'; script-src 'self'; connect-src 'self'; img-src 'self'; style-src 'self'; font-src 'self';

My preference is to not only check for its existence but also verify its effects on the behavior of the page. This will ensure that the page functions according to my requirements.

Answer №1

The code snippet below is aimed at testing the presence of script-src 'self' in Chrome, specifically checking if injected inline scripts can be executed. This test ensures that the value does not include unsafe-inline or *:

it('should not run injected scripts', function() {
  var script = 'window.inlineTagEvaluated = false;';
  script += 'var callback = arguments[arguments.length - 1];';
  script += 'var script = document.createElement("script");';
  script += 'script.text = "window.inlineTagEvaluated = true;";';
  script += 'document.head.appendChild(script);'
  script += 'callback(window.inlineTagEvaluated);';

  expect(browser.executeAsyncScript(script)).toBe(false);
});

To test that the CSP restrictions prevent running unsafe-eval code is challenging due to the prohibition of inline scripts. One workaround is to have a file on the server /test-eval.js containing:

try {
  new Function('');
}
catch(e) {
  window.caught = true;
}

This file is then added to the DOM during the test runtime with the following script:

it('should not run eval-ed scripts', function() {
  var script = 'window.caught = false;'
  script += 'var callback = arguments[arguments.length - 1];';
  script += 'var script = document.createElement("script");';
  script += 'script.src = "/eval-test.js";';
  script += 'script.onload = function() {callback(window.caught);};';
  script += 'script.onerror = function() {callback(window.caught);};';
  script += 'document.head.appendChild(script);'

  expect(browser.executeAsyncScript(script)).toBe(true);
});

Testing the inability to execute scripts from external domains involves serving a Javascript file from a different domain using an HTTP server setup specifically for the test.

it('should not run scripts from another domain', function() {

  function setupServer() {
    var defer = protractor.promise.defer();

    require('http').createServer(function (request, response) {
       response.setHeader('Content-Type', 'application/javascript');
       response.end('window.externalScriptEvaluated = true;');
    }).listen(8081, function() {
      defer.fulfill();
    });
    return defer.promise;
  }
  protractor.promise.controlFlow().execute(setupServer);

  var script = 'window.externalScriptEvaluated = false;';
  script += 'var callback = arguments[arguments.length - 1];';
  script += 'var script = document.createElement("script");';
  script += 'script.src = "http://localhost:8081/";';
  script += 'script.onload = function() {callback(window.externalScriptEvaluated);};';
  script += 'script.onerror = function() {callback(window.externalScriptEvaluated);};';
  script += 'document.head.appendChild(script);'
  expect(browser.executeAsyncScript(script)).toBe(false);
});

The next test focuses on verifying the restriction set by style-src 'self', ensuring that inline styles cannot be applied.

it('should not use injected styles', function() {
  var script = 'document.body.style.backgroundColor = "rgb(0, 1, 1)";';
  script += 'var callback = arguments[arguments.length - 1];';
  script += 'var style = document.createElement("style");';
  script += 'style.type = "text/css";';
  script += 'style.appendChild(document.createTextNode("body {background-color: rgb(1, 0, 0) !important}"));';
  script += 'document.head.appendChild(style);'
  script += 'callback(window.getComputedStyle(document.body).getPropertyValue("background-color"));';

  expect(browser.executeAsyncScript(script)).toBe("rgb(0, 1, 1)");
});

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Steps to create a clickable row with color change in Angular 4

How do I make an entire row clickable and change the row color when a checkbox is clicked? This is my HTML file: <section class="others"> <div class="sub-header">Others</div> <p class="text-center" *ngIf="otherTests.length === 0"> ...

The `mouseenter` event handler fails to trigger properly on its initial invocation

As I work on a function to remove a CSS class display:hidden; when the mouse enters a specific part of the DOM to reveal a menu, I encounter an issue. Upon loading the page and hovering over the designated area for the first time, the event fails to trigge ...

The property is not found within the type, yet the property does indeed exist

I'm baffled by the error being thrown by TypeScript interface SendMessageAction { type: 1; } interface DeleteMessageAction { type: 2; idBlock:string; } type ChatActionTypes = SendMessageAction | DeleteMessageAction; const CounterReduc ...

Performing form validation prior to executing an onclick event to insert data into the database

I am uncertain about whether I can perform form validation before an onclick function that sends data to be inserted in a database, as the data is sent even when the form is incomplete. HTML <td class="text-center"><input type="checkbox" class=" ...

After clicking the submit button, make sure to automatically fill in all empty input fields

I am currently working on a form that includes various input types such as text fields, radio buttons, select dropdowns, and text areas. The form is displayed in a table format with an option to add additional rows. One issue I have encountered is that us ...

What is the process for integrating an AngularJS component as a header in our index.html file?

Within my project, I have a header component that is comprised of its own HTML and JavaScript files. How can I effectively integrate this component into the main index.html of my application? ...

We were unable to locate the module: Unable to locate './components/counter' in 'C:/...democounter-appsrc'

I'm completely new to React and currently following tutorials by MOSH on YouTube. However, I've encountered an error that I can't seem to resolve even after searching for similar questions. index.js import React from 'react'; imp ...

Mastering various techniques for creating styles with makeStyles in React JS Material-UI

As a newcomer to React JS and Material UI, I am experimenting with creating various styles of buttons. Each button should have a unique appearance based on attributes like name= submit, ok, cancel, confirm, alert. App.JS import CssButton from './con ...

Implement a cron job in Node.js to automatically trigger an Express route on a weekly basis

I need to run tests on a certain page every week by creating a cron job that will access my express route at regular intervals. Currently, I have set up a cron job to run every 2 minutes as a test: //schedule job every 2 minutes schedule.scheduleJob("* /2 ...

The size of the SVG <g> element remains zero even though it contains children

I inserted some elements into an SVG with one large group. The basic code for the group is as follows: <svg ng-attr-view-box="{{getViewbox()}}" width="100%" height="100%"> <!-- This will be the global group element I reference below --& ...

No value being returned by promise

Encountering a node issue with the use of the imap module, where the goal is to implement a promise. I have set up a Promise.method() using bluebird. The code can be found at: https://github.com/dkran/email-thinky-test/ The problem arises in a file that c ...

Learn how to clear form values in react-bootstrap components

My objective upon clicking the register button is: Clear all input fields Hide any error tooltips Check out the CodeSandbox link I attempted to reset using event.target.reset();, but the tooltips persist on the screen. export default function App() { ...

Can an unresolved promise lead to memory leaks?

I have a Promise. Initially, I created it to potentially cancel an AJAX request. However, as it turns out, the cancellation was not needed and the AJAX request completed successfully without resolving the Promise. A simplified code snippet: var defer = $ ...

What is causing my website to refresh before I can save the edits I have made after clicking on the edit button

My website is fairly simple, allowing users to add blog posts with a title, author, and content. Each post has two buttons - one for deleting and one for editing. These actions add, delete, or edit the chosen posts within a .json file through a local json ...

Convert $_FILES['tmp_name'] into JSON format and send it again

I recently experimented with using AJAX to upload multiple images and sort data according to the following data structure. My query pertains to utilizing AJAX to retrieve $_FILES['tmp_name'] and incorporating it into client-side JSON data (the ...

Creating a nested JSON structure by fetching data from a remote source

i'm looking to populate the json file located at through a get request. This json contains music from various churches in different cities, with data organized into multiple levels. I want to parse this data using jquery and utilize hidden div elemen ...

There was a TypeError encountered when attempting to read the length property of a null value in the Google Map JSON data

I keep getting an Uncaught TypeError: Cannot read property 'length' of null error when I attempt to use JSON data as markers on my Google map. However, when I check console.log(data);, it shows that the data is fine. What could be causing this is ...

Guide to verifying the scope of a dynamic array in Javascript

Hey there, I'm currently trying to verify if a value falls within a specific range in a dynamic array. Let's say I have an amount of 3555, and an array of values like [1000,2000,999999]. Typically we would use conditional statements to check for ...

The v-html command displays unprocessed HTML code on the webpage

This is a visual representation of my component: <template> <div v-html="someHtml"></div> </template> <script> export default { name: "test", props: { someHtml: String, }, } </script&g ...

Having trouble opening the application on MacOS Sierra with Firefox 56.0 - the browser opens but then times out before the application loads

Operating System: MacOS Sierra Browser: Firefox 56.0 Selenium Server standalone version 3.6.jar Browser Driver: geckodriver version 0.19 public class DemoTestNg { @Test public void test1() { System.setProperty("webdriver.firefox.marionette", ...