I tried to mount a client-side "attack" on a news website poll by using only Javascript. And I failed miserably.
Tags: webdev, javascript, beginners, discuss
Published: 2021-07-14 00:18:10

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ofx1p297o3kb1prtxn9k.png)

## First step - Running the script locally
For academic purposes I tried to create a client-side script to manipulate the results of a random poll on a [Croatian news portal](https://www.index.hr/vijesti/clanak/velika-anketa-treba-li-cijepljenje-u-skolstvu-zdravstvu-i-socijali-biti-obavezno/2290306.aspx)

The poll is open at the moment writing, but it probably won't stay that way for long.

[Here's the code](https://stackblitz.com/edit/js-ddpj1r?file=backup.js)

The code consists of these steps:

- <em>waiting for "DOMContentLoaded" event</em>

- <em>closing the cookie banner</em>

- <em>selecting a poll answer</em>

- <em>MutationObserver indicates changes in the DOMTree target iframe. This means that the results are "in". Then the  localStorage is cleared.</em>

- <em>a timer, which started running immediately after "DOMContentLoaded", reloads the page after 2 seconds. And the script starts from the beginning</em>

It works as intended if you run it directly in the dev tools console.

You'll probably notice how the code is tightly coupled with the html/css implementation of the web page. 

Since I was creating a proof of concept I didn't bother to  write the functions in a generalised way. 

I used the exact CSS class names from the site, and targeted the poll iframe based on its position in the HTML. 

I had a pretty strong hunch that it won't work anyway (not that it stopped me from trying).

## Second step - Automating the script

The next step was to think of a way to run the script automatically, without the need to paste the code in the console every time. 

So, I created a custom [browser extension](https://stackblitz.com/edit/js-uhxg5p?file=content-script.js), which has only one additional manifest.json file.

And that didn't work. 

Line 2 is the problem.

```javascript
  document.getElementsByTagName('iframe')[3].contentDocument;
```

It doesn't work because of the ["Same Origin Policy"](https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy). 

It's a "critical security mechanism that restricts how a document or script loaded by one origin can interact with a resource from another origin".

And this also applies to iframes.

"External" iframe's can't be accessed, nor manipulated from a document which is not served on the same origin (domain). 

...

For completeness sake, I also tried to use the 3 most popular browser extensions that enable running custom scripts on any web page; 

- GreaseMonkey
- TamperMonkey
- ViolentMonkey.

I tested out a few StackOverflow suggestions, related to the configuration of those extensions, in a foolish attempt to beat the system. 

But with no luck.

You can't beat the system by breaking its hard rules. Unless you're the One. And it turns out I'm not. At least not yet. 

## A glimmer of hope

Fortunately not all of my work was in vain. 

As I was slowly accepting my fate, and getting ready to completely give up, I stumbled on an alternative approach to this problem. 

There's a method called [Window.postMessage](https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage)

And its API looks kind of promising (with regard to CORS issues caused by external iframe communication).

So the story continues. Stay tuned. :)

##Conclusion

Do you know any other way, or a hack, to bypass the Same Origin Policy? 

Is there another approach to the "external iframe" problem, which I didn't think of?

Or is it just plain impossible to do this on the client (FE) side (which is a good thing I suppose, because it prevents malicious behaviour).