Security trong lập trình với Android

Updated: 01/2/2019

Giới thiệu

Em mới vào công ty nên đây cũng là lần đầu tiền post bài. Mong được mọi người feedback và ủng hộ.

Security trong lập trình Android

Nghe có vẻ đao to búa lớn quá nhỉ 😃 . Em đoán là mọi người chắc đều biết cả rồi, viết ra đây để được mọi người feedback xem phần hiểu của mình có đúng hay không.

  • Đặt vấn đề :

Giả sử trong Activity chúng ta có một xử lý set một giá trị nào đó rồi phía sau sẽ dùng nó để làm công việc tiếp. Phía sau ở đây có thể là api hoặc một usecase nào đó chẳng hạn
Source code:

fun setOrderMethod(orderMethod: String) {
    // orderMethod giả sử có 2 kiểu là Immediate và Booking . 
    // Tức là loại order tức thì hoặc order có hẹn lịch 
    
    orderUseCase.sendRequest(orderMethod)
}

Kotlin rất mạnh trong việc kiểm tra null và khống chế việc gán nullable vào.
Vì thế nhìn vào đây mình thấy mọi thứ có vẻ OK phải không?

  • Phân tích vấn đề :

Mình lại đưa ra 2 pattern thế này :

  1. Nếu orderMethod là 1 String nhận từ phía server vào -> Mình sẽ viết vấn đề này ở bài tiếp theo.
  2. Nếu orderMethod là 1 String được quyết định từ phía client ( Ví dụ nhận vào từ một xử lý chọn dropdown nào đó )

Giả sử mình đi tìm hiểu pattern số 2 nhé.
Do việc quyết định truyền orderMethod là giá trị gì sẽ là phía client quyết định, nói cách khác là do developer chúng ta. Như đã nói do phía client quyết định nên khi code chúng ta đều sẽ phải cover được là cái orderMethod này sẽ có những loại giá trị nào rồi phải không ? Giả sử như phía trên nó chỉ có 2 loại là immediate hoặc booking thì developer chúng ta thường sẽ define ra 1 enum class để dùng .

enum class OrderMethod(val method: String) {
    IMMEDIATE("immediate"),
    BOOKING("booking")
}

Khi có enum class như vậy rồi thì cứ theo như bình thường ta sẽ truyền vào tuỳ theo case đúng không?

  setOrderMethod(OrderMethod.IMMEDIATE.method)
  hoặc là 
  setOrderMethod(OrderMethod.BOOKING.method)

Đến đây vẫn thấy có vẻ ngon lành nhỉ ? Tuy nhiên như đã nói ở phía trên, do param truyền vào mình để là kiểu String nên có thể truyền bất cứ String nào vào cũng được. ( Nó có vẻ hơi tựa tựa kiểu hack sql injection ngày xưa nhỉ ).
Nghe thì có vẻ ít xảy ra nhưng khi mà một dự án có nhiều người cùng làm, mỗi người sẽ code theo một tư duy , khi không có một architecture chung để mọi người flow theo thì rất rẽ có bug.

Vì thế phải làm sao để giảm thiểu rủi ro chỗ này. Và cũng chính là mục đích của chủ đề là sẽ làm sao cho sai sót hoặc bug xảy ra thấp nhất có thể. Đó cũng là vấn đề về security trong lập trình.

  • Giải quyết vấn đề :

Ở đây để hạn chế phía ngoài truyền tuỳ ý String vào đây, chúng ta phải làm cho nó có tính cưỡng chế hơn, bảo mật hơn bằng cách thay vì dùng String ta có thể dùng Object .
Ở đây có 2 cách , một là dùng sealed class hoặc dùng chính enum class đang có sẵn. Trong case này thì cả 2 cái đều giống nhau nên mình lấy ví dụ luôn với sealed class nhé. ( Kotlin mà ).

  1. Sửa lại kiểu truyền vào là OrderMethod
fun setOrderMethod(orderMethod: OrderMethod) {
    orderUseCase.sendRequest(orderMethod)
}
  1. Tạo class OrderMethod.kt như sau:
sealed class OrderMethod(val method: String) {
    object Immediate(): OrderMethod(method = "immediate")
    object Booking(): OrderMethod(method = "booking")
}

Như vậy chúng ta đã giảm khả năng truyền lung tung vào method setOrderMethod rồi phải không? Giờ sẽ phải truyền vào là :

  setOrderMethod(OrderMethod.Immediate)
  hoặc là 
  setOrderMethod(OrderMethod.Booking)

Tất nhiên, phía useCase sẽ phải lấy giá trị method ra từ object để sử dụng :

fun sendRequest(orderMethod: OrderMethod) {
   when(orderMethod){
      is OrderMethod.Immediate -> {// make order immeidatelly}
      is OrderMethod.Booking -> {// make booking order}
   }
}

Làm như này source code sẽ trở nên dễ control hơn và khi có dev mới vào thì khả năng làm hỏng logic cũng ít đi. Vì bắt buộc phải truyền vào là 1 object OrderMethod .
Tuy chỉ là vấn đề nhỏ và chắc mọi người đều biết rồi, nhưng hi vọng với bài viết này các dev mới vào như mình sẽ ngày càng nâng cao skill hơn.