Category Archive: Software Development

Jan 17 2012

Pengurutan (Sorting) Multi Kolom dengan Java

Pengurutan merupakan sesuatu yang umum dan sering diperlukan. Saat belajar algoritma dan pemrograman, topik pengurutan biasanya selalu ada. Masalah pengurutan ini juga sering muncul dalam programming, baik itu dalam programming ilmu komputer (seperti soal-soal ICPC, TopCoder, dll) maupun dalam programming dunia industri.

Andaikan kita seorang software developer yang sedang mengerjakan proyek web sepak bola. Dalam web tersebut, kita akan menampilkan klasmen suatu liga. Nah, buat yang belum mengerti apa itu klasmen, begini penjelasannya.

Klasmen merupakan tabel berisi data hasil pertandingan. Hasil pertandingan yang dimaksud adalah:

  • jumlah pertandingan yang sudah dijalani (Wins + Draws + Loses [lihat 3 item selanjutnya!])
  • jumlah pertandingan yang berakhir dengan dimenangkan (Wins, disingkat menjadi W)
  • jumlah pertandingan yang berakhir seri (Draws, disingkat menjadi D)
  • jumlah pertandingan yang berakhir dengan kekalahan (Loses, disingkat menjadi L)
  • jumlah gol ke gawang lawan (Goals For, disingkat menjadi GF)
  • jumlah gol ke gawang sendiri (Goals Against, disingkat menjadi GA)
  • selisih gol (Goals Difference, disingkat menjadi GD, yaitu GF – GA)
  • poin (Points, disingkat menjadi Pts, yaitu 3 * W + D)

Klasmen disusun berdasarkan poin. Tim yang memiliki poin lebih besar akan berada di atas, demikian sebaliknya. Jika poin kedua sama, diurutkan berdasarkan selisih gol. Tim yang memiliki selisih gol lebih besar akan berada di atas, demikian sebaliknya.

Perhatikan data hasil pertandingan (pertengahan Januari 2012) dari enam klub English Premier League berikut:

Klub/Tim             Wins  Draws  Loses  Goals-For  Goals-Against
-----------------------------------------------------------------
Arsenal              11    3      6      36         28
Chelsea              12    4      5      40         25
Liverpool            9     8      4      24         18
Manchester City      15    3      2      56         16
Manchester United    15    3      3      52         20
Tottenham Hotspur    14    4      3      39         21

Tabel di atas masih berisi data mentah dan belum diurutkan (urutan sementara berdasarkan nama klub). Untuk mengurutkannya, kita harus menghitung poin dan selisih goal, sebagai berikut:

Klub                 W   D  L  GF  GA  Pts(1)  GD(2)
----------------------------------------------------
Arsenal              11  3  6  36  28  36      8
Chelsea              12  4  5  40  25  40      15
Liverpool            9   8  4  24  18  35      6
Manchester City      15  3  2  56  16  48      40
Manchester United    15  3  3  52  20  48      32
Tottenham Hotspur    14  4  3  39  21  46      18

Keterangan
(1) Pts = points = poin
(2) GD = goals difference = selisih gol

Maka klasmen akan diperoleh sebagai berikut:

Klub                 W   D  L  GF  GA  Pts  GD
----------------------------------------------
Manchester City      15  3  2  56  16  48   40
Manchester United    15  3  3  52  20  48   32
Tottenham Hotspur    14  4  3  39  21  46   18
Chelsea              12  4  5  40  25  40   15
Arsenal              11  3  6  36  28  36   8
Liverpool            9   8  4  24  18  35   6

Perhatikan bahwa data sekarang telah diurut berdasarkan poin (Pts) dan selisih gol (GD). Ada dua klub yang memiliki poin sama, yaitu Manchester City dan Manchester United. Tetapi, karena selisih gol Manchester City lebih besar, klub tersebut berada di atas.

Sekarang, anggap data hasil pertandingan tersebut disimpan di tabel tbl_klasmen dalam database. Tabel tersebut memiliki struktur seperti ini:

Field            Type
------------------------
team_name        VARCHAR
wins             INTEGER
draws            INTEGER
loses            INTEGER
goals_for        INTEGER
goals_against    INTEGER

Dan berisi enam data seperti yang diperlihatkan pada tabel pertama di atas.

Jika menggunakan query SQL, maka untuk mendapatkan klasmen akan semudah ini:

SELECT *, (3 * wins + draws) AS points, (goals_for - goals_against) AS goals_difference
  FROM `tbl_klasmen`
  ORDER BY points DESC, goals_difference DESC;

Masalah selesai.

Bagaimana kalau datanya tidak berasal dari tabel database?

Read the rest of this entry »

  • Facebook
  • Twitter
  • Delicious
  • Digg
  • Google Buzz
  • StumbleUpon
  • Add to favorites
  • Email
  • RSS

Permanent link to this article: http://www.muhammadalvin.net/2012/01/pengurutan-multi-kolom-dengan-java/

Jan 16 2012

Mengenal Cross-Site Scripting (XSS)

Cross-site scripting (untuk selanjutnya akan disebut sebagai XSS) merupakan celah keamanan (security vulnerability)  yang biasa ditemukan di aplikasi berbasis web. Celah keamanan ini memungkinkan penyerang memasukkan (inject) kode tertentu yang bersifat client-side (misalnya JavaScript, CSS). Kode yang di-inject oleh penyerang tersebut akan dilihat dan dijalankan juga oleh pengguna lain. Akibat dari celah keamanan ini cukup bervariasi, mulai dari sekedar mengganggu, merusak tampilan web, hingga pencurian data seperti cookie.

Contoh halaman web yang memiliki celah keamanan ini bisa dilihat di sini.

Pertama, coba isikan sesuatu secara normal (misalnya nama = alvin, komentar = hello world). Apa yang terjadi? Tentu saja tidak ada masalah. Nama dan komentar akan  muncul sesuai dengan apa yang diinputkan.

Sekarang, coba isikan komentar yang ‘sedikit aneh’. Masukkan komentar yang berisi tag HTML, misalnya sebagai berikut:

Halo... ini contoh teks <b>bold</b> dan <u>underline</b>...

Apa yang terjadi? Komentar Anda muncul seperti ini:

Halo… ini contoh teks bold dan underline.

Nah, kode HTML yang kita sisipkan diproses oleh browser. Cobalah minta teman Anda untuk membuka halaman tersebut (dari komputer lain). Maka ia akan memperoleh hasil yang sama. Ini berarti si penyerang (dalam contoh ini adalah kita) berhasil meng-inject-kan kode buatannya. Hal seperti ini yang disebut celah keamanan Cross-Site Scripting. Ini harusnya tidak boleh terjadi. Bayangkan jika si penyerang menyisipkan kode berikut:

Halo...
<script type="text/javascript">
window.onload = function() {
    document.getElementsByTagName("body")[0].innerHTML = '<h1>This web is hacked!</h1>';
}
</script>

Atau komentar berikut yang sangat mengganggu pengguna lain (pengguna lain akan mendapatkan alert/popup yang tidak pernah berakhir):

<script type="text/javascript">
while (true) {
    alert('Sekarang jam ' + (new Date()).toUTCString());
}
</script>

Atau mungkin seperti ini:

Web ini bagus.
<script type="text/javascript">
if (confirm('Tapi sayang ada celah keamanannya! Klik OK untuk mempelajari celah keamanan tsb!')) {
  document.location.href = 'http://www.muhammadalvin.net/2012/01/mengenal-cross-site-scripting/';
}
</script>

Yang mengarahkan pengguna ke halaman lain.

Cara mengatasinya cukup sederhana. Jika menggunakan PHP, tambahkan htmlentities() sebelum menampilkan hasil inputan dari pengguna. Misalnya kode berikut:

echo 'Nama : ' . $nama;

Diubah menjadi:

echo 'Nama : ' . htmlentities($nama);

Pastikan Anda menggunakan fungsi tersebut di setiap bagian yang bertugas menampilkan hasil inputan dari pengguna.

Buat yang ingin tahu secara detail tentang XSS, simak pembahasan berikut.

Andaikan Anda membuat halaman HTML (index.html) berikut:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
    <head>
        <title>Demo Cross-Site Scripting</title>
    </head>
    <body>
        <form action="hasil.php" method="post">
            <p><label for="nama">Nama:</label><br />
            <input type="text" name="nama" id="nama" /></p>
            <p><label for="komentar">Komentar:</label><br />
            <textarea name="komentar" id="komentar" cols="40" rows="5"></textarea></p>
            <p><input type="submit" value="Kirim" /></p>
        </form>
    </body>
</html>

Kemudian halaman PHP berikut (hasil.php) yang bertugas memproses hasil input dari halaman index.html:

<?php
$nama = (isset($_POST['nama']) ? $_POST['nama'] : '');
$komentar = (isset($_POST['komentar']) ? $_POST['komentar'] : '');

echo '<p>Nama:<br />' . $nama . '</p>';
echo '<p>Komentar:<br />' . $komentar . '</p>';

Saat Anda menjalankan index.html, akan muncul sebuah form dengan dua field. Jika Anda mengisi nama dengan test dan komentar dengan hello world, maka ketika di-submit (dengan menekan tombol Kirim), hasil.php akan memprosesnya sebagai berikut:

$nama = (isset($_POST['nama']) ? $_POST['nama'] : '');
// maka $nama berisi: test

$komentar = (isset($_POST['komentar']) ? $_POST['komentar'] : '');
// dan $komentar berisi: hello world

echo '<p>Nama:<br />' . $nama . '</p>';
// sesuai dengan nilai di variabel $nama di atas,
// maka akan di-echo: <p>Nama:<br />test</p>

echo '<p>Komentar:<br />' . $komentar . '</p>';
// sesuai dengan nilai di variabel $komentar di atas,
// maka akan di-echo: <p>Komentar:<br />hello world</p>

Di sini tidak ada masalah. Jika Anda coba jalankan, maka hasil sesuai dengan yang diharapkan.

Masalah muncul ketika misalnya komentar yang dimasukkan adalah ini adalah contoh teks <b>bold</b>. Halaman hasil.php akan memprosesnya sebagai berikut:

$komentar = (isset($_POST['komentar']) ? $_POST['komentar'] : '');
// $komentar berisi: ini adalah contoh teks <b>bold</b>

echo '<p>Komentar:<br />' . $komentar . '</p>';
// sesuai dengan nilai di variabel $komentar di atas,
// maka akan di-echo: <p>Komentar:<br />ini adalah contoh teks <b>bold</b></p>

Browser tidak pernah tau bahwa ini adalah contoh teks <b>bold</b> datangnya dari web developer yang membuat halaman atau dari isian pengguna yang iseng. Hasilnya, browser akan memproses kode HTML yang ada di dalamnya, sehingga akan menampilkan tulisan “bold” dalam keadaan bercetak tebal, hasil dari tag HTML <b> dan </b> tersebut.

Hal yang sama terjadi untuk JavaScript. Pengguna yang iseng bisa menyisipkan kode JavaScript yang diapit oleh tag HTML <script type=”text/javascript”> dan </script>. Hasilnya tentu saja kode JavaScript tersebut akan dijalankan oleh browser.

Cara mengatasinya adalah dengan meng-escape karakter-karakter spesial HTML, seperti:

  • & menjadi &amp;
  • < menjadi &lt;
  • > menjadi &gt;
  • ” menjadi &quot;

Anda bisa melakukan find-replace secara manual, atau menggunakan fungsi yang disediakan oleh bahasa pemrograman yang digunakan. Sebagai contoh fungsi htmlentities() yang disediakan oleh PHP.

Nah, XSS ini terjadi saat menampilkan sesuatu ke web browser. Celah keamanan sebaliknya, terjadi saat menyimpan sesuatu dari web browser (hasil input pengguna) ke database biasa dikenal dengan SQL injection. Selain kedua jenis tersebut, masih ada lagi celah keamanan yang lain, misalnya Cross-site Request Forgery (CSRF).

———-

Referensi:

  • Facebook
  • Twitter
  • Delicious
  • Digg
  • Google Buzz
  • StumbleUpon
  • Add to favorites
  • Email
  • RSS

Permanent link to this article: http://www.muhammadalvin.net/2012/01/mengenal-cross-site-scripting/

Des 10 2011

Menggunakan Web API

Postingan kali ini akan membahas bagaimana menggunakan web API. Apabila sudah memahami bagaimana menggunakan web API, maka akan mudah untuk memahami bagaimana menggunakan web service. Pada dasarnya, web service juga merupakan web API. Web service merupakan bentuk khusus dari web API. Ada aturan dan standar tertentu dalam web service.

Web API yang akan kita gunakan adalah web API untuk mengambil data dari Info Billing PLN yang sudah pernah kita bahas di sini. Langsung saja kita lakukan coding.

Pertama, buat halaman HTML berisi form untuk meminta ID pelanggan, misalnya sebagai berikut:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
    <head>
        <title>Cek Tagihan Listrik</title>
    </head>
    <body>
        <form action="" method="post">
            <table border="0">
                <tbody>
                    <tr>
                        <td>ID Pelanggan</td>
                        <td><input type="text" name="id" value="" /></td>
                    </tr>
                    <tr>
                        <td>Tahun</td>
                        <td><input type="text" name="tahun" value="" /></td>
                    </tr>
                    <tr>
                        <td></td>
                        <td><input type="submit" value="Lihat" /></td>
                    </tr>
                </tbody>
            </table>
        </form>
    </body>
</html>

Berikutnya, siapkan skrip PHP untuk membaca input dari halaman tersebut, misalnya seperti ini:

$id = (isset($_POST['id']) ? $_POST['id'] : '');
$tahun = (isset($_POST['tahun']) ? $_POST['tahun'] : date('Y'));

Selanjutnya, lengkapi skrip PHP tersebut menjadi seperti ini:

if ($id != '' && $tahun != '')
{
    // panggil web API dgn membawah data id pelanggan dan tahun.
    // utk sekedar request GET bisa dengan file_get_contents(). utk request yg lebih rumit, pakai CURL.
    $url = 'http://apps.muhammadalvin.net/pln.php?id_pelanggan=' . $id . '&tahun=' . $tahun;
    $hasilApi = @file_get_contents($url);

    // proses response dari hasil pemanggilan web API tsb.
    $hasil = json_decode($hasilApi);
    if (!is_null($hasil))
    {
        if ($hasil->status)
        {
            // kalo 'status' bernilai true, berarti sukses. ambil nama pelanggan dan data tagihannya.

            // apakan ada data tagihan utk tahun yg diminta?
            if (isset($hasil->result->tagihan->{$tahun}))
            {
                $namaBulan = array(
                    '1'  => 'Januari',
                    '2'  => 'Februari',
                    '3'  => 'Maret',
                    '4'  => 'April',
                    '5'  => 'Mei',
                    '6'  => 'Juni',
                    '7'  => 'Juli',
                    '8'  => 'Agustus',
                    '9'  => 'September',
                    '10' => 'Oktober',
                    '11' => 'November',
                    '12' => 'Desember'
                );

                ?>
                <p>
                    Tagihan listrik atas nama <strong><?php echo $hasil->result->nama; ?></strong>
                    untuk tahun <strong><?php echo $tahun; ?></strong> adalah sebagai berikut:
                </p>
                <ul>
                <?php
                foreach ($hasil->result->tagihan->{$tahun} as $bulan => $tagihan)
                {
                    ?><li><?php echo $namaBulan[$bulan]; ?> = Rp <?php echo number_format($tagihan, 0, ',', '.'); ?></li><?php
                }
                ?></ul><?php
            }
            else
            {
                ?><p style="color: #00f">Tidak ada data tagihan untuk tahun ini!</p><?php
            }
        }
        else
        {
            ?><p style="color: #f00">Error <?php echo $hasil->faultCode; ?>: <?php echo $hasil->faultString; ?></p><?php
        }
    }
    else
    {
        ?><p style="color: #f00">Unknown Error: <?php echo htmlentities($hasilApi); ?></p><?php
    }
}

Contoh skrip jadi (halaman berisi form HTML + skrip PHP) bisa dilihat di sini.

Simpan lalu jalankan skrip tersebut. Ini adalah contoh hasilnya:

  • Facebook
  • Twitter
  • Delicious
  • Digg
  • Google Buzz
  • StumbleUpon
  • Add to favorites
  • Email
  • RSS

Permanent link to this article: http://www.muhammadalvin.net/2011/12/menggunakan-web-api/

Des 10 2011

Mengambil Data dari Info Billing PLN

Postingan ini akan menjelaskan proses pengambilan data dari Info Billing PLN. Selanjutnya, proses tersebut akan dibungkus menjadi sebuah web API yang dapat diakses oleh berbagai aplikasi/sistem lain. Saya menyebutnya web API bukan web service, karena yang dikembangkan ini bukan benar-benar web service, seperti SOAP web service ataupun REST web service.

Web service punya standarisasi. Sebagai contoh, REST web service. Web service jenis ini biasanya menggunakan clean URL, yang pada URL tidak lagi terdapat ekstensi file seperti misalnya .php. Selain itu, cara komunikasinya menggunakan HTTP GET, HTTP POST, HTTP POST, HTTP DELETE. Sementara API (Application Programming Interface) merupakan istilah yang lebih umum. API adalah antarmuka (interface) yang mengizinkan aplikasi/program berkomunikasi dengan aplikasi/program/sistem lain. Dalam istilah web: API berarti antarmuka yang mengizinkan web browser atau web server berkomunikasi dengan aplikasi/program/sistem lain.

(akan ditulis kemudian)

Web API yang sudah jadi bisa diakses di sini:

http://apps.muhammadalvin.net/pln.php

Web API ini menerima input dari query string. Jadi, kita bisa mengaksesnya dengan cara seperti ini:

http://apps.muhammadalvin.net/pln.php?id_pelanggan=XXX

Atau dalam pesan HTTP:

GET /pln.php?id_pelanggan=XXX HTTP/1.1
Host: apps.muhammadalvin.net

Ada dua query string yang dapat diberikan, yaitu:

  • id_pelanggan, merupakan ID pelanggan berupa 12 angka
  • tahun, merupakan tahun dalam bentuk 4 angka

Output/response nya dalam bentuk JSON dengan struktur seperti ini:

{
    "status": true,
    "result": (object)
}

Item status bernilai true. Item result merupakan object dengan struktur berikut:

{
    "id_pelanggan": (string),
    "nama": (string),
    "alamat": (string),
    "daya_va": (string),
    "tagihan": (object)
}

Item tagihan merupakan object dengan key berupa string (yaitu tahun) dan item berupa object (kita sebut sebagai “item tagihan per-tahun”). Item tagihan per-tahun tersebut merupakan object dengan key berupa string (yaitu bulan) dan item berupa integer (yaitu besar tagihan dalam rupiah).

Contoh lengkap output adalah sebagai berikut:

{
    "status": true,
    "result": {
        "id_pelanggan": "120130000000",
        "nama": "MUHAMMAD ALVIN",
        "alamat": "JL. MARELAN VII GG. RAHAYU",
        "daya_va": "000000000000000900",
        "tagihan": {
            "2011": {
                "9": 110565,
                "8": 138880,
                "2": 124180,
                "1": 114925
            }
        }
    }
}

Dari contoh di atas, dapat diketahui informasi berikut:

  • ID pelanggan = 120130000000
  • Nama pelanggan = MUHAMMAD ALVIN
  • Alamat = Jl. Marelan VII gg. Rahayu
  • Daya = 900 watt
  • Tagihan September 2011 = Rp 110.565
  • Tagihan Agustus 2011 = Rp 138.880
  • Tagihan Februari 2011 = Rp 124.180
  • Tagihan Januari 2011 = Rp 114.925

Saat terjadi kesalahan, outputnya seperti ini:

{
    "status": false,
    "faultCode": (string),
    "faultString": (string)
}

Item status akan bernilai false. Kemudian, ada dua item yang menjelaskan kesalahan yg terjadi yaitu faultCode dan faultString.

Item faultCode akan bernilai:

  • Client, jika kesalahan terjadi akibat kesalahan client (pemakai web API), misalnya ID pelanggan yg diberikan tidak 12 digit atau bukan angka.
  • Server, jika kesalahan terjadi di sisi server (penyedia layanan).

Item faultString akan berisi penjelasan kesalahan yang terjadi.

Untuk menguji web API ini, lakukan request GET seperti yang ditunjukkan di atas. Cara paling sederhana adalah dengan membuka browser dan mengetikkan URL berikut query string dan datanya di address bar. Lalu, tekan ENTER.

Postingan selanjutnya akan ditulis untuk memberikan contoh penggunaan web service ini dari aplikasi lain yang akan kita buat.

Untuk mengambil source code web service ini, tambahkan query string ?source menjadi:

http://apps.muhammadalvin.net/pln.php?source

  • Facebook
  • Twitter
  • Delicious
  • Digg
  • Google Buzz
  • StumbleUpon
  • Add to favorites
  • Email
  • RSS

Permanent link to this article: http://www.muhammadalvin.net/2011/12/mengambil-data-dari-info-billing-pln/

Des 02 2011

Mengakses Konten Terproteksi (Login Dilakukan oleh Script)

Konten terproteksi yang akan kita gunakan sebagai contoh (sekaligus kelinci percobaan :D ) bisa diakses di sini. Gunakan login dengan username guest dan password 123456. Setelah login, maka akan muncul dua grafik (Contoh Grafik I dan Contoh Grafik II). Coba dapatkan URL ke gambar grafik tersebut, misalnya dengan cara klik kanan di gambar lalu pilih Copy Image Location (menggunakan Firefox).

Jika malas melakukannya, maka URL gambar tersebut adalah sebagai berikut:

Contoh Grafik I:
http://files.muhammadalvin.net/konten-terproteksi/data.php?kode=1

Contoh Grafik II:
http://files.muhammadalvin.net/konten-terproteksi/data.php?kode=2

Coba buka link tersebut di browser. Jika sudah login, akan muncul sebuah grafik. Grafik pada link pertama berwarna biru dan grafik pada link kedua berwarna merah. Jika belum login, akan muncul pesan “Anda harus login untuk melihat grafik data!”.

Sekarang, coba logout dari aplikasi tersebut. Setelah logout, coba refresh gambar grafik. Maka sekarang akan muncul pesan yang meminta kita melakukan login terlebih dulu.

Nah, jika kita sedang mengembangkan suatu aplikasi dan kita ingin menampilkan grafik tersebut di aplikasi kita, kita akan mengalami masalah. Kode HTML berikut:

<img src="http://files.muhammadalvin.net/konten-terproteksi/data.php?kode=1" alt="Grafik I" />

hanya akan menampilkan grafik jika kita sudah login. Jika belum, maka grafik tidak akan ditampilkan. Cobalah!

Apakah masalah tersebut bisa diatasi? Tentu saja bisa. Jika grafik tersebut statik (artinya grafik yang dihasilkan tidak berubah-ubah), maka save saja gambar tersebut. Misalnya grafik tersebut kita simpan sebagai grafik1.png, dan kita letakkan di folder yang sama dengan file HTML yang kita buat. Maka kode HTML untuk menampilkan grafik tersebut bisa kita ganti menjadi:

<img src="grafik1.png" alt="Grafik I" />

Masalah teratasi :-) .

Namun, bagaimana jika grafik tersebut dinamis (artinya grafik yang dihasilkan bisa berubah-ubah, tergantung parameter yang diberikan)? Tentu saja cara di atas tidak bisa dijadikan solusi. Kalau kita kenal dengan pembuat aplikasinya, mungkin bisa meminta akses khusus untuk mengambil grafik tersebut :D . Tetapi jika tidak? Maka satu-satunya cara yang dapat dilakukan adalah dengan melakukan login, mengambil gambar tersebut, kemudian menampilkannya. Pertanyaannya adalah, bagaimana melakukannya dari coding?

Read the rest of this entry »

  • Facebook
  • Twitter
  • Delicious
  • Digg
  • Google Buzz
  • StumbleUpon
  • Add to favorites
  • Email
  • RSS

Permanent link to this article: http://www.muhammadalvin.net/2011/12/mengakses-konten-terproteksi-dengan-login-dilakukan-oleh-script/

Older posts «