Kesalahan pelacakan tumpukan di php

Terkadang kita perlu menyebarkan nilai variabel sensitif dan rahasia dalam logika aplikasi kita. Ambil kode login ini sebagai contoh

1<?php

2 

3class AccessBroker

4{

5 public function login(string $username, string $password): void

6 {

7 // Pretend that we're attempting to log the user in, but something throws an exception.

8 throw new \Exception('Oops, something went wrong!');

9 }

10}

11 

12(new AccessBroker)->login($_POST['username'], $_POST['password']);

Saya sengaja menyimpan framework-agnostik dan dasar ini hanya untuk menunjukkan masalahnya. Saat kode di atas dijalankan, kita dapat dengan jelas melihat kata sandi pengguna di jejak tumpukan pengecualian

1Fatal error: Uncaught Exception: Oops, something went wrong! in /in/HhjIr:8

2Stack trace:

3#0 /in/HhjIr(13): AccessBroker->login('chris', 'secret password')

4#1 {main}

5 thrown in /in/HhjIr on line 8

_

Ini mungkin bukan masalah besar bagi Anda, lagipula, Anda harus menonaktifkan rendering jejak tumpukan dalam produksi. Tidak seorang pun akan memiliki kesempatan untuk melihat nilainya, bukan? . Jika pengecualian ini dilaporkan ke layanan eksternal untuk pemantauan kesalahan, seperti Sentry atau Bugsnag, Anda juga akan membocorkan kata sandi pengguna ke layanan orang lain. Paling tidak, Anda mungkin membocorkan nilai sensitif ke dalam file log Anda

Jadi apa yang bisa kita lakukan untuk melindungi rahasia itu? . Kita dapat melakukannya dengan berbagai metode berbeda

zend.exception_ignore_args

PHP 7. 4 memperkenalkan nilai konfigurasi ini baru yang disebut zend.exception_ignore_args. Ini akan berhenti merender pratinjau argumen metode dalam pelacakan tumpukan. Mengaktifkannya, pelacakan tumpukan kami tidak lagi mengungkapkan kata sandi pengguna

1Fatal error: Uncaught Exception: Oops, something went wrong! in /in/TYMID:10

2Stack trace:

3#0 /in/TYMID(14): AccessBroker->login()

4#1 {main}

5 thrown in /in/TYMID on line 10

Namun, ini datang dengan kerugian yang signifikan bahwa kami sekarang tidak akan mendapatkan pratinjau argumen apa pun di seluruh pelacakan tumpukan, dengan pengecualian apa pun yang dilemparkan oleh aplikasi kami. Karena sebagian besar argumen yang akan kami sampaikan dalam aplikasi kami tidak sensitif, menurut saya ini adalah pemecah kesepakatan

Sunting argumen individual secara manual

Kita dapat menulis penangan pengecualian yang dapat mengambil jejak tumpukan pengecualian melalui

1Fatal error: Uncaught Exception: Oops, something went wrong! in /in/HhjIr:8

2Stack trace:

3#0 /in/HhjIr(13): AccessBroker->login('chris', 'secret password')

4#1 {main}

5 thrown in /in/HhjIr on line 8

0, mengulangi bingkai, dan menyunting argumen apa pun yang ingin kita lindungi. Ada banyak jawaban Stack Overflow yang menunjukkan cara melakukannya. Masalah dengan metode ini adalah reaktif dan bukan proaktif. Saat Anda mulai meneruskan argumen rahasia baru lainnya di aplikasi Anda, Anda harus ingat untuk kembali ke penangan pengecualian dan memperbaruinya untuk memperhitungkan argumen baru. Dalam pengalaman saya, ini jarang terjadi 🙂

Maaf menyela

Jika Anda menikmati membaca posting ini, silakan pertimbangkan untuk mengikuti saya di Twitter

Ikuti @cmwhite92

Gunakan array untuk menyimpan nilai rahasia

PHP tidak merender nilai array dalam pelacakan tumpukan secara default. Dengan menggunakan metode ini, kode masuk kami dari sebelumnya dapat terlihat seperti ini

1<?php

2 

3class AccessBroker

4{

5 public function login(array $credentials)

6 {

7 // We can use $credentials['username'] and $credentials['password'].

8 

9 // Pretend that we're attempting to log the user in, but something throws an exception.

10 throw new \Exception('Oops, something went wrong!');

11 }

12}

13 

14(new AccessBroker)->login(['username' => 'chris', 'password' => 'secret password']);

_

dan jejak tumpukan yang diberikan akan menjadi

1Fatal error: Uncaught Exception: Oops, something went wrong! in /in/37rTZ:8

2Stack trace:

3#0 /in/37rTZ(13): AccessBroker->login(Array)

4#1 {main}

5 thrown in /in/37rTZ on line 8

Ini adalah metode yang diambil oleh kerangka Laravel - dan ini bagus. Itu melakukan pekerjaan menyembunyikan argumen sensitif sambil menyimpan sisanya, dan tidak mengharuskan kita untuk menulis kode penanganan pengecualian kita sendiri untuk melakukannya

Gunakan objek untuk membungkus nilai sensitif

Sebagus metode di atas adalah memiliki satu kelemahan. Anda tidak lagi mendapatkan pelengkapan otomatis atau analisis statis untuk larik

1Fatal error: Uncaught Exception: Oops, something went wrong! in /in/HhjIr:8

2Stack trace:

3#0 /in/HhjIr(13): AccessBroker->login('chris', 'secret password')

4#1 {main}

5 thrown in /in/HhjIr on line 8

1 di dalam metode

1Fatal error: Uncaught Exception: Oops, something went wrong! in /in/HhjIr:8

2Stack trace:

3#0 /in/HhjIr(13): AccessBroker->login('chris', 'secret password')

4#1 {main}

5 thrown in /in/HhjIr on line 8

2 karena Anda mengirimkan larik PHP umum. Kita bisa mengatasi masalah itu dengan mengganti array dengan objek

1Fatal error: Uncaught Exception: Oops, something went wrong! in /in/HhjIr:8

2Stack trace:

3#0 /in/HhjIr(13): AccessBroker->login('chris', 'secret password')

4#1 {main}

5 thrown in /in/HhjIr on line 8

3 yang kita buat sendiri. Kode login kita dari sebelumnya adalah sekarang

1<?php

2 

3class ObfuscatedValue

4{

5 private $value;

6 

7 public function __construct($value)

8 {

9 $this->value = $value;

10 }

11 

12 public function value()

13 {

14 return $this->value;

15 }

16}

17 

18class AccessBroker

19{

20 public function login(string $username, ObfuscatedValue $password)

21 {

22 // We can use $password->value() to get the real password value.

23 

24 // Pretend that we're attempting to log the user in, but something throws an exception.

25 throw new \Exception('Oops, something went wrong!');

26 }

27}

28 

29(new AccessBroker)->login('chris', new ObfuscatedValue('secret password'));

_

dan sekali lagi, jejak tumpukan kami menyembunyikan kata sandi

1Fatal error: Uncaught Exception: Oops, something went wrong! in /in/Dnf3b:25

2Stack trace:

3#0 /in/Dnf3b(29): AccessBroker->login('chris', Object(ObfuscatedValue))

4#1 {main}

5 thrown in /in/Dnf3b on line 25

Gunakan perpustakaan

@julesjanssen menunjukkan di Twitter bahwa perpustakaan ada untuk melakukan hal ini yang sudah disebut string-tersembunyi. Ini terlihat sangat lengkap dan bahkan menggunakan metode ajaib yang saya tidak tahu disebut

1Fatal error: Uncaught Exception: Oops, something went wrong! in /in/HhjIr:8

2Stack trace:

3#0 /in/HhjIr(13): AccessBroker->login('chris', 'secret password')

4#1 {main}

5 thrown in /in/HhjIr on line 8

4. Anda dapat menggunakannya dengan cara yang sama seperti yang saya tunjukkan di atas, dan karena perpustakaan mengimplementasikan metode ajaib

1Fatal error: Uncaught Exception: Oops, something went wrong! in /in/HhjIr:8

2Stack trace:

3#0 /in/HhjIr(13): AccessBroker->login('chris', 'secret password')

4#1 {main}

5 thrown in /in/HhjIr on line 8

5 Anda tidak perlu memperlakukan

1Fatal error: Uncaught Exception: Oops, something went wrong! in /in/HhjIr:8

2Stack trace:

3#0 /in/HhjIr(13): AccessBroker->login('chris', 'secret password')

4#1 {main}

5 thrown in /in/HhjIr on line 8

6 seperti objek sama sekali

Apa itu kesalahan pelacakan tumpukan?

Stack trace error adalah istilah umum yang sering diasosiasikan dengan pesan error yang panjang . Informasi pelacakan tumpukan mengidentifikasi di mana kesalahan terjadi dalam program dan sangat membantu pemrogram. Untuk pengguna, informasi trek tumpukan panjang mungkin tidak terlalu berguna untuk memecahkan masalah kesalahan web.

Bagaimana cara mendapatkan jejak tumpukan di PHP?

Pengecualian PHP Metode getTrace() . Pelacakan tumpukan berisi informasi tentang semua fungsi yang berjalan pada saat tertentu. Pelacakan tumpukan yang disediakan oleh metode ini memiliki informasi tentang tumpukan pada saat pengecualian dilemparkan.

Apa yang menyebabkan kesalahan pelacakan tumpukan?

Biasanya, pelacakan tumpukan ditampilkan saat Pengecualian tidak ditangani dengan benar dalam kode . (Pengecualian adalah apa yang digunakan lingkungan runtime untuk memberi tahu Anda bahwa ada kesalahan dalam kode Anda. ) Ini mungkin salah satu tipe Pengecualian bawaan, atau Pengecualian khusus yang dibuat oleh program atau pustaka.

Bagaimana cara melacak kesalahan PHP?

Tampilkan Semua Kesalahan PHP dengan Cepat . ini_set('display_errors', 1);