Cara menggunakan is innerhtml safe

Example

Get the HTML content of an element with id="myP":

let html = document.getElementById("myP").innerHTML;

Try it Yourself »

Change the HTML content of an element with id="demo":

document.getElementById("demo").innerHTML = "I have changed!";

Try it Yourself »

Get the HTML content of a

    element with id="myList":

    let html = document.getElementById("myList").innerHTML;

    Try it Yourself »

    Delete the HTML content of a

    element with id="demo":

    Try it Yourself »

    More examples below.


Definition and Usage

The innerHTML property sets or returns the HTML content (inner HTML) of an element.

The Differences BetweeninnerHTML, innerText and textContent

See below


Syntax

Return the innerHTML property:

Set the innerHTML property:

Property Value

PropertyDescriptionStringHTML content.

Return Value

TypeDescriptionStringThe HTML content of the element.

More Examples

Example

Change the HTML content of two elements:

let text = "Hello Dolly.";
document.getElementById("myP").innerHTML = text;
document.getElementById("myDIV").innerHTML = text;

Try it Yourself »

Example

Repeat the HTML content of an element:

element.innerHTML += element.innerHTML;

Try it Yourself »

Example

Change the HTML content and URL of a link:

element.innerHTML = "W3Schools";
element.href = "https://www.w3schools.com";

Try it Yourself »


The Differences BetweeninnerHTML, innerText and textContent

The innerHTML property returns:
The text content of the element, including all spacing and inner HTML tags.The innerText property returns:
Just the text content of the element and all its children, without CSS hidden text spacing and tags, except

Pada kesempatan ini, kita akan belajar tentang cara melindungi aplikasi web–terutama yang dibuat dengan Codeigniter–dari serangan XSS.

Selain itu, kita juga akan belajar melakukan serangan XSS agar tahu cara menghindarinya.

Baiklah..

Mari kita mulai!

Apa itu XSS?

XSS merupakan singkatan dari cross site scripting.

Alasan singkatan yang digunakan XSS bukan CSS, karena CSS sudah digunakan untuk cascade style sheet.

Jadi X untuk singkatan kata Cross.

XSS merupakan salah satu bentuk serangan pada aplikasi web yang dilakukan dengan menginjeksi kode javascript dari sisi client.

Dampak yang bisa diakbiatkan XSS:

  • Keamanan aplikasi web dapat di-bypass;
  • Data user dapat dicuri;
  • Halaman yang terkena XSS bisa dijadikan media Phising;
  • dan lain-lain.

Cara Mengatasi XSS di Codeigniter

“Untuk menangkap pencuri, kita harus berpikir seperti pencuri”

Mari kita pelajari bagaimana cara melakukan serangan XSS agar bisa menghindarinya.

1. Reflected XSS

Ini adalah jenis serangan XSS yang sering dilakukan attacker.

Biasanya terjadi pada input dari parameter query string yang kita tampilkan.

Contoh:

Misalkan kita punya fitur pencarian seperti ini:

<?php

class Search extends CI_Controller
{
	public function index()
	{
		$data["keyword"] = $this->input->get("keyword");

		// do search and render result to view
		$this->load->view('search', $data);
	}
}

Kemudian pada view, kita menampilkan

index.php/search/?keyword=<script>alert('hacked!')</script>
0 yang diinputkan seperti ini:

<p>Hasil pencarian dengan kata kunci <?= $keyword ?></p>
<p>Hasil: ...</p>

Sekilas tidak ada masalah dengan kode ini.

Tapi coba inputkan

index.php/search/?keyword=<script>alert('hacked!')</script>
1 dengan kode Javascript seperti ini:

index.php/search/?keyword=<script>alert('hacked!')</script>

Maka hasilnya:

Cara menggunakan is innerhtml safe

Bagaimana cara mengatasi serangan ini?

✅ Solusinya:

Gunakan fungsi

index.php/search/?keyword=<script>alert('hacked!')</script>
2 pada view untuk menampilkan variabel
index.php/search/?keyword=<script>alert('hacked!')</script>
0.

<p>Hasil pencarian dengan kata kunci <?= htmlentities($keyword) ?></p>
<p>Hasil: ...</p>

Maka sekarang halaman ini tidak akan bisa diserang XSS.

Cara menggunakan is innerhtml safe

Tapi jangan senang dulu..

Masih ada jenis serangan XSS yang lainnya:

2. Stored XSS

Stored XSS adalah serangan XSS yang dilakukan dengan memasukan injeksi XSS pada input yang disimpan ke database.

Sebenarnya tidak harus database, yang penting input itu disimpan di suatu tempat.

Nantinya, saat ditampilkan di halaman view.. kode injeksi XSS-nya akan dieksekusi.

Contohnya:

Misalkan kita membuat fitur untuk aplikasi lowongan pekerjaan. Input yang kita butuhkan untuk menambahkan lowongan baru sebagai berikut.

  • index.php/search/?keyword=<script>alert('hacked!')</script>
    4 nama atau judul lowongan kerja;
  • index.php/search/?keyword=<script>alert('hacked!')</script>
    5 alamat URL poster;
  • index.php/search/?keyword=<script>alert('hacked!')</script>
    6 alamat pendaftaran lowongan kerja.

Bentuk kode di Controller-nya seperti ini:

📜

index.php/search/?keyword=<script>alert('hacked!')</script>
7

<?php

class Jobvacancy extends CI_Controller
{
	public function addjob()
	{
		if ($this->input->method() === "post") {
			$data["job"] = $this->input->post();

			// di sini biasanya dilakukan penyimpanan ke database

			return $this->load->view("list_job", $data);
		}

		$this->load->view('add_job_form');
	}
}

..dan berikut ini kode untuk view-nya.

📜

index.php/search/?keyword=<script>alert('hacked!')</script>
8

<h1><?= $job["name"] ?></h1>
<img src='<?= $job["job_image_url"] ?>' />
<br>
<a href='<?= $job["job_url"] ?>'>Link Pendaftaran</a>

📜

index.php/search/?keyword=<script>alert('hacked!')</script>
9

<form action="" method="post">
	<label for="name">Vacancy Job name</label>
	<input type="text" name="name" >
	<br>
	<label for="job_image_url">Image URL</label>
	<input type="text" name="job_image_url">
	<br>
	<label for="job_url">Job URL</label>
	<input type="text" name="job_url">
	<br>
	<input type="submit" value="Simpan">
</form>

Ini hasilnya saat kita inputkan data yang benar.

Cara menggunakan is innerhtml safe

Sekarang coba berikan input untuk

index.php/search/?keyword=<script>alert('hacked!')</script>
4 atau judul lokernya dengan kode javascript.

<script>alert('hacked')</script>

Untuk URL kita kosongkan aja dulu..

Cara menggunakan is innerhtml safe

Maka hasilnya:

Cara menggunakan is innerhtml safe

Serangan ini sama persis seperti XSS Reflected, bedanya injeksi pada seraingan ini akan disimpan di database.

Pada contoh di atas memang kita tidak menggunakan database. Tapi dalam prakteknya, pasti kita akan menyimpan ke database untuk input data ini.

Lalu solusi yang bisa kita lakukan apa?

✅ Solusi:

Solusinya sama seperti XSS Reflected, yakni kita harus menampilkan output dengan fungsi

index.php/search/?keyword=<script>alert('hacked!')</script>
2.

Maka pada view 📜

<p>Hasil pencarian dengan kata kunci <?= htmlentities($keyword) ?></p>
<p>Hasil: ...</p>
2 dapat kita ubah seperti ini:

<h1><?= htmlentities($job["name"]) ?></h1>
<img src='<?= htmlentities($job["job_image_url"]) ?>' />
<br>
<a href='<?= htmlentities($job["job_url"]) ?>'>Link Pendaftaran</a>

Hasilnya:

Cara menggunakan is innerhtml safe

Mantap!

Tapi jangan senang dulu..

Karena ini masih belum aman.

Lah kenapa?

Kita patut waspadai output pada atribut

<p>Hasil pencarian dengan kata kunci <?= htmlentities($keyword) ?></p>
<p>Hasil: ...</p>
3 pada image dan
<p>Hasil pencarian dengan kata kunci <?= htmlentities($keyword) ?></p>
<p>Hasil: ...</p>
4 pada link.

Bisa saja mereka memberikan injeksi seperti ini:

x' onerror='alert("Hacked")'

Injeksi ini akan membuat atribut baru bernama

<p>Hasil pencarian dengan kata kunci <?= htmlentities($keyword) ?></p>
<p>Hasil: ...</p>
5 yang berfungsi untuk menjalankan kode javascript.

Atau kita bisa juga menggunakan

<p>Hasil pencarian dengan kata kunci <?= htmlentities($keyword) ?></p>
<p>Hasil: ...</p>
6 seperti ini:

<p>Hasil pencarian dengan kata kunci <?= $keyword ?></p>
<p>Hasil: ...</p>
0

Mari kita coba:

Cara menggunakan is innerhtml safe

Hasilnya:

Cara menggunakan is innerhtml safe

Lihat kan.. belum 100% aman hehe.

Lalu giaman cara mengatasi ini?

✅ Solusi:

Sebenarnya kita bisa gunakan double quote pada atribut HTML seperti ini:

<p>Hasil pencarian dengan kata kunci <?= $keyword ?></p>
<p>Hasil: ...</p>
1

Hasilnya atribut akan seperti ini:

Cara menggunakan is innerhtml safe

Apakah sudah aman?

Belum! 😄

Percobaan ini saya lakukan di browser versi terbaru. Kemungkin di browser versi lama, akan tetap kena.

Terus solusinya bagaimana?

Kita bisa gunakan konstanta

<p>Hasil pencarian dengan kata kunci <?= htmlentities($keyword) ?></p>
<p>Hasil: ...</p>
7 pada parameter
index.php/search/?keyword=<script>alert('hacked!')</script>
2 untuk melakukan enkode pada tanda petik. Baik yang ganda maupun yang tunggal.

Sehingga kode viewnya akan menjadi seperti ini:

<p>Hasil pencarian dengan kata kunci <?= $keyword ?></p>
<p>Hasil: ...</p>
2

Hasilnya bisa kita lihat di View Source.

Cara menggunakan is innerhtml safe

Masalah injeksi tanda petik sudah beres.

Apakah sudah aman?

Belum! 🤣

Serangan injeksi berikutnya, saat user menginputkan:

<p>Hasil pencarian dengan kata kunci <?= $keyword ?></p>
<p>Hasil: ...</p>
3

Biasanya jika nilai ini diberikan pada link, maka browser akan menjalankan kode javascript yang diberikan.

Coba gunakan input tersebut.

Cara menggunakan is innerhtml safe

Hasilnya:

Cara menggunakan is innerhtml safe

Kita sudah menggunakan

index.php/search/?keyword=<script>alert('hacked!')</script>
2, tapi yang ini bisa lolos.

Solusinya giaman donk?

✅ Solusi:

Solusi yang bisa kita lakukan untuk mengatasi serangan ini adalah dengan melakukan validasi data. Baik di sisi client maupun server.

Pelajari juga:

  • Cara Validasi data di Codeigniter

Mari kita coba lakukan validasi di sisi server terlebih dahulu.

Ubah Controllernya menjadi seperti ini:

<p>Hasil pencarian dengan kata kunci <?= $keyword ?></p>
<p>Hasil: ...</p>
4

Kemudian ubah view untuk form-nya menjadi seperti ini:

📜

index.php/search/?keyword=<script>alert('hacked!')</script>
9

<p>Hasil pencarian dengan kata kunci <?= $keyword ?></p>
<p>Hasil: ...</p>
5

Hasilnya:

Cara menggunakan is innerhtml safe

Mantap!

Dengan begini aman sudah.

Tinggal lakukan validasi di sisi client.

Validasi di sisi client bisa kita lakukan dengan atribut HTML. Kita bisa ubah nilai pada atribut

<?php

class Jobvacancy extends CI_Controller
{
	public function addjob()
	{
		if ($this->input->method() === "post") {
			$data["job"] = $this->input->post();

			// di sini biasanya dilakukan penyimpanan ke database

			return $this->load->view("list_job", $data);
		}

		$this->load->view('add_job_form');
	}
}
1 menjadi
<?php

class Jobvacancy extends CI_Controller
{
	public function addjob()
	{
		if ($this->input->method() === "post") {
			$data["job"] = $this->input->post();

			// di sini biasanya dilakukan penyimpanan ke database

			return $this->load->view("list_job", $data);
		}

		$this->load->view('add_job_form');
	}
}
2 dan juga menambahkan
<?php

class Jobvacancy extends CI_Controller
{
	public function addjob()
	{
		if ($this->input->method() === "post") {
			$data["job"] = $this->input->post();

			// di sini biasanya dilakukan penyimpanan ke database

			return $this->load->view("list_job", $data);
		}

		$this->load->view('add_job_form');
	}
}
3 untuk validasi dengan regex.

Silahkan pelajari juga:

  • Apa itu Regex?

Maka sekarang kita ubah kode view untuk form-nya menjadi seperti ini:

<p>Hasil pencarian dengan kata kunci <?= $keyword ?></p>
<p>Hasil: ...</p>
6

Hasilnya:

Cara menggunakan is innerhtml safe

Kini saya rasa sudah aman..

Tapi jangan berpikir 100% akan aman, hehe.

Karena masih ada bentuk serangan XSS yang lainnya:

3. DOM Based XSS

DOM Based XSS adalah jenis serangan XSS yang injeksinya dijalankan di dalam DOM (Document Object Model).

Apa itu DOM?

Silahkan pelajari di:

  • Tutorial Javascript: Apa itu DOM?

Untuk mendemokan serangan ini, mari kita ubah view pada form

<?php

class Jobvacancy extends CI_Controller
{
	public function addjob()
	{
		if ($this->input->method() === "post") {
			$data["job"] = $this->input->post();

			// di sini biasanya dilakukan penyimpanan ke database

			return $this->load->view("list_job", $data);
		}

		$this->load->view('add_job_form');
	}
}
4 menjadi seperti ini:

<p>Hasil pencarian dengan kata kunci <?= $keyword ?></p>
<p>Hasil: ...</p>
7

Kita menambahkan fitur untuk preview image berdasarkan URL image yang diinputkan.

Jika URL yang diinputkan bernar, maka akan tampil seperti ini:

Cara menggunakan is innerhtml safe

Berdasarkan kode javascript yang kita buat. Kita menampilkan image dengan manipulasi DOM.

Ini tentunya akan membuat kita bisa melakukan DOM based XSS.

Mau bukti?

Silahkan inputkan injeksi XSS berikut di dalam URL image.

<p>Hasil pencarian dengan kata kunci <?= $keyword ?></p>
<p>Hasil: ...</p>
8

Maka hasilnya:

Cara menggunakan is innerhtml safe

Benar kan! 😆

Padahal kita sudah melakukan validasi di sisi client dan server.

Lalu gimana solusinya?

✅ Solusi:

Solusi untuk menghindari DOM based XSS sebenarnya hampir sama seperti Reflected XSS.

Bedanya, DOM based XSS dilakukan di client atau di dalam Javascript.. bukan di dalam PHP atau kode server.

Namun, fungsi

index.php/search/?keyword=<script>alert('hacked!')</script>
2 di javascript belum ada. Fungsi ini bisa kita buat secara manual, atau bisa juga memanfaatkan library seperti underscore.js dengan fungsi
<?php

class Jobvacancy extends CI_Controller
{
	public function addjob()
	{
		if ($this->input->method() === "post") {
			$data["job"] = $this->input->post();

			// di sini biasanya dilakukan penyimpanan ke database

			return $this->load->view("list_job", $data);
		}

		$this->load->view('add_job_form');
	}
}
6.

Ada juga library DOMPurifyyang khusus untuk mengatasi XSS.

OWASP sendiri juga menawarkan library ESAPI untuk escape HTML di javascript.

Kamu bisa baca:

  • Cara Mitigasi DOM Based XSS menurut OWASP.

Solusi lain bisa dengan men-trigger validator HTML saat input field diinputkan.

Contohnya seperti ini:

<p>Hasil pencarian dengan kata kunci <?= $keyword ?></p>
<p>Hasil: ...</p>
9

Maka preview image tidak akan ditampilkan selama nilai URL yang diberikan tidak valid.

Cara menggunakan is innerhtml safe

4. Self-XSS

Teknik XSS ini sulit diatasi dari kode aplikasi. Karena dilakukan sendiri oleh user.

Misalnya gini:

Seorang Attacker melakukan sosial enginering ke pada pengguna market place.

Attacker: “Hi, saya punya kode rahasia buat dapetin diskon 99%”

Korban: “Benarkah? gimana caranya?”

Attacker: “Buka aplikasinya dari Google Chrome di Laptop, masuk ke halaman checkout, Klik kanan, lalu pilih inspect element, Lalu masuk ke Console. Setelah itu, paste Kode ini

<?php

class Jobvacancy extends CI_Controller
{
	public function addjob()
	{
		if ($this->input->method() === "post") {
			$data["job"] = $this->input->post();

			// di sini biasanya dilakukan penyimpanan ke database

			return $this->load->view("list_job", $data);
		}

		$this->load->view('add_job_form');
	}
}
7, setelah itu tekan Enter. ”

Korban: “Wah boleh nih dicoba.”

Beberapa hari kemudian..

Korban: “Kok saldo saya hilang 😭!!!”

Nah kira-kira begitulah skenario terjadinya Self XSS.

Injeksi XSS-nya dijalankan sendiri oleh user yang merupakan korban Social Engineering.

Lalu bagaimana cara mengatasinya?

✅ Solusi:

Seperti yang saya bilang, Self XSS sulit diatasi dari kode aplikasi. Salah satu cara yang bisa dilakukan adalah memberikan edikasi kepada user agar tidak menjalankan kode apapun di dalam Console Javascript browser.

Kita bisa tiru cara facebook memberikan edukasi dengan menampilkan pesan ini di console Javascript.

Cara menggunakan is innerhtml safe

5. Mutated XSS (mXSS)

Teknik serangan XSS yang ini sangat jarang digunakan dan sulit untuk dideteksi. Karena baru ditemukan di tahun 2019.