September 4, 2021 | 23:15

INE WebApp Labs - Introduction

Preparation

# Set lab DNS
$ sudo sed -i 's/nameserver.*/nameserver 10.100.13.37/' /etc/resolv.conf

Cookies

These are labs to understand how cookies work.

Lab 1

Test cookie with domain set by default

$ curl -i -s -k -X $'POST' \
    -H $'Host: a.correctcookie1.site' \
    --data-binary $'username=admin&password=adminpassword' \
    $'http://a.correctcookie1.site/login.php' \
    | grep "TestCookie"
Set-Cookie: TestCookie=Cookie+set+by+default

The cookie is set without a domain value and without a path. It is only valid for the same domain, but all paths:

  • http[s]://a.correctcookie1.site/*

Lab 2

Test cookie set to .correctcookie2.site (dot at the beginning)

$ curl -i -s -k -X $'POST' \
    -H $'Host: a.correctcookie2.site' \
    --data-binary $'username=admin&password=adminpassword' \
    $'http://a.correctcookie2.site/login.php' \
    | grep "TestCookie"
Set-Cookie: TestCookie=Cookie+set+to+correctcookie2.site; domain=correctcookie2.site

The cookie has a domain value of correctcookie2.site (there is no “dot” at the beginning…), which is a suffix of the target domain a.correctcookie2.site. It is valid for:

  • http[s]://correctcookie2.site/*
  • http[s]://*.correctcookie2.site/*

Lab 3

Test cookie set with a specific path (/test/)

$ curl -i -s -k -X $'POST' \
    -H $'Host: a.correctcookie3.site' \
    --data-binary $'username=admin&password=adminpassword' \
    $'http://a.correctcookie3.site/login.php' \
    | grep "TestCookie"
Set-Cookie: TestCookie=Cookie+set+to+%2Ftest%2F; path=/test/

The cookie has no domain value specified and a path value of /test/. It is only valid for the same domain and for all sub-paths of /test/:

  • http[s]://a.correctcookie3.site/test/*

Lab 4

Test cookies set with the same name but different domain values.

$ curl -i -s -k -X $'POST' \
    -H $'Host: a.correctcookie4.site' \
    --data-binary $'username=admin&password=adminpassword' \
    $'http://a.correctcookie4.site/login.php' \
    | grep "TestCookie"
Set-Cookie: TestCookie=Cookie+value+set+to+A+for+.correctcookie4.site; domain=.correctcookie4.site

The cookie has a domain value of .correctcookie4.site (there is a “dot” at the beginning), which is a suffix of the requested domain a.correctcookie4.site. It is valid for:

  • http[s]://correctcookie4.site/*
  • http[s]://*.correctcookie4.site/*
$ curl -i -s -k -X $'GET' \
    -H $'Host: correctcookie4.site' \
    -b $'TestCookie=Cookie+value+set+to+A+for+.correctcookie4.site' \
    $'http://correctcookie4.site/setnewcookie.php' \
    | grep "TestCookie"
Set-Cookie: TestCookie=Cookie+value+set+to+B+with+a+default+domain

When requesting the URL http://correctcookie4.site/setnewcookie.php (note, that the cookie from above is valid here), a new cookie is set. That second cookie has no domain value specified. It is therefore only valid for the same domain and all paths:

  • http[s]://correctcookie4.site/*

As a result, both cookies are individual cookies and valid. For example, when requesting the URL http://correctcookie4.site/setnewcookie.php again, both cookies are sent by the browser as follows:

Cookie: TestCookie=Cookie+value+set+to+A+for+.correctcookie4.site; TestCookie=Cookie+value+set+to+B+with+a+default+domain

When requesting http://a.correctcookie4.site/welcome.php, only the first cookie is sent, because the second one is only valid for the domain correctcookie4.site.

Lab 5

Test cookie set for a different domain

$ curl -i -s -k -X $'POST' \
    -H $'Host: a.incorrectcookie.site' \
    --data-binary $'username=admin&password=adminpassword' \
    $'http://a.incorrectcookie.site/login.php' \
    | grep "TestCookie"
Set-Cookie: TestCookie=Cookie+set+for+a.incorrectcookie.test; domain=a.incorrectcookie.test

A cookie is set for a different domain (note the TLD is .test instead of .site). The cookie is invalid, because a website cannot set cookies for different domains.

Lab 6

Test cookie set for a different subdomain

$ curl -i -s -k -X $'POST' \
    -H $'Host: a.incorrectcookie2.site' \
    --data-binary $'username=admin&password=adminpassword' \
    $'http://a.incorrectcookie2.site/login.php' \
    | grep "TestCookie"
Set-Cookie: TestCookie=Cookie+set+for+b.incorrectcookie2.site; domain=b.incorrectcookie2.site

A cookie is set for a different subdomain b.incorrectcookie2.site. The cookie is invalid, because a subdomain cannot set cookies for a different subdomain.

Same Origin Policy

These are labs to understand how the Same Origin Policy (SOP) work.

VideoLab 1

Simple iframe.

<iframe src="http://a.elssop.site/page1.html"> </iframe>

The target site http://a.elssop.site/ contains an iframe with the same origin (i.e. same protocol, host and port).

VideoLab 2

Change iframe content within same domain

[...]
<input id="clickMe" type="button" value="Test SOP" onclick="testsop();" />
[...]
<iframe src="http://a.elssop.site/page1.html"> </iframe>
[...]
<script>
function testsop(){
  try {
    window.frames[0].document.body.innerHTML = "Content changed"
  } catch(e) {
    alert("Error: "+e)
  }
}
</script>
[...]

The target site http://a.elssop.site/test1.html embeds an iframe with the same origin and contains a button, that successfully changes the HTML content of that iframe.

VideoLab 3

Change iframe content on different domain

[...]
<input id="clickMe" type="button" value="Test SOP 2" onclick="testsop2();" />
[...]
<iframe src="http://b.elssop.site/page2.html"> </iframe>
[...]
<script>
function testsop2(){
  try {
    window.frames[1].document.body.innerHTML = "Content Changed"
  } catch(e) {
    alert("Error: "+e)
  }
}
</script>
[...]

The next target site http://a.elssop.site/test2.html additionally contains an iframe with a different origin (different host), which means that it’s content can’t be changed with the button click. The error message is:

Error: SecurityError: Permission denied to access property "document" on cross-origin object

VideoLab 4

Get and Set location on same origin and different origin

[...]
<h2 style="margin:0px;">Same Origin</h2>
[...]
<input id="clickMe" type="button" value="Test SET Location" onclick="testlocation(0);" />
[...]
<input id="clickMe" type="button" value="Test GET Location" onclick="testlocation2(1);" />
[...]
<iframe src="http://a.elssop.site/page1.html"></iframe>
[...]
<iframe src="http://a.elssop.site/page1.html"></iframe>
[...]
<h2 style="margin:0px;">Different Origin</h2>
[...]
<input id="clickMe" type="button" value="Test SET Location" onclick="testlocation(2);" />
[...]
<input id="clickMe" type="button" value="Test GET Location" onclick="testlocation2(3);" />
[...]
<iframe src="http://b.elssop.site/page2.html"></iframe>
[...]
<iframe src="http://b.elssop.site/page2.html"></iframe>
[...]
<script>
function testlocation(frameid){
  try {
    window.frames[frameid].location="http://www.elsfoo.com";
  } catch(e) {
    alert("Error: "+e)
  }
}

function testlocation2(frameid){
  try {
    alert(frames[frameid].location);
  } catch(e) {
    alert("Error: "+e)
  }
}
</script>
[...]

The target site http://a.elssop.site/test3.html embeds four iframes and four buttons, that try to set or get the location of the iframes. The first iframes have the same origin, while the other two have a different host.

For the iframes with the same origin, it’s possible to set and get the location. For the iframes with different origin, it’s possible to set the location, but not allowed to read the location. The corresponding error message is:

Error: SecurityError: Permission denied to access property Symbol.toPrimitive on cross-origin object

This shows, that a document can update the location property of another document (with some existing relationship, in our example here one embedded the other), but cannot read it, except both documents have the same origin.

VideoLab 5

Change parent content from iframe (same domain)

[...]
<iframe src="http://a.elssop.site/good.html"> </iframe>
[...]

The target site http://a.elssop.site/test4.html embeds an iframe with the same origin, which contains code that tries to change the parent document’s content:

[...]
<input id="clickMe" type="button" value="Test SOP" onclick="testsop();" />
[...]
<script>
	function testsop(){
	  try {
	    window.parent.document.body.innerHTML = "Parent document content changed"
	  } catch(e) {
	    alert("Error: "+e)
	  }
	}
</script>
[...]

Clicking the button actually changes the target site’s content. This shows, that documents with the same origin can access and change each other’s content via JavaScript.

VideoLab 6

Change parent content from iframe (differnet domain)

<iframe src="http://b.elssop.site/evil.html"> </iframe>

The target site http://a.elssop.site/test5.html embeds an iframe with different origin, which contains the same code as the one above:

[...]
<input id="clickMe" type="button" value="Test SOP" onclick="testsop();" />
[...]
<script>
	function testsop(){
	  try {
	    window.parent.document.body.innerHTML = "Parent document content changed"
	  } catch(e) {
	    alert("Error: "+e)
	  }
	}
</script>
[...]

This time, the content is not changed and an error message is shown:

Error: SecurityError: Permission denied to access property "document" on cross-origin object

That’s because documents with different origins can’t change each other’s content via JavaScript.

VideoLab 7

Test location by changing the document.domain property

[...]
<input id="clickMe" type="button" value="Get iframe location" onclick="testsop();" />
<input id="clickMe" type="button" value="Change domain" onclick="changedomain();" />
[...]
<iframe src="http://b.elssop.site/domain.html"> </iframe>
[...]
<script>
	function changedomain(){
	  try {
	    document.domain = "elssop.site"
	  } catch(e) {
	    alert("Error: "+e)
	  }
	}

	function testsop(){
	  try {
	    alert(frames[0].location);
	  } catch(e) {
	    alert("Error: "+e)
	  }
	}
</script>
[...]

The target site http://a.elssop.site/test6.html embeds an iframe with different origin containing the following:

[...]
<input id="clickMe" type="button" value="Get parent location" onclick="testsop();" />
<input id="clickMe" type="button" value="Change domain" onclick="changedomain();" />
[...]
<script>
	function changedomain(){
	  try {
	    document.domain = "elssop.site"
	  } catch(e) {
	    alert("Error: "+e)
	  }
	}
	function testsop(){
	  try {
	    alert(window.parent.location)
	  } catch(e) {
	    alert("Error: "+e)
	  }
	}
</script>
[...]

Trying to access the .location of a document with a different origin doesn’t work. That’s why clicking on Get iframe/parent location results in the following error message:

Error: SecurityError: Permission denied to access property Symbol.toPrimitive on cross-origin object

However, when clicking on both Change domain buttons, both documents can be considered to have the same origin, hence it is then possible to access the location of the other document.

© Pavel Pi 2021

Powered by Hugo & Kiss'Em.