2011-07-13 34 views
9

Từ trang 113 của O'Reilly Essential ActionScript 3.0 (2007):Làm thế nào không thể sử dụng "cuối cùng" là một vấn đề an ninh?

Phương pháp đó là giúp đỡ chính thức ẩn chi tiết nội bộ của một lớp. Thực hiện lớp học hoặc phương pháp cuối cùng là phương pháp ngăn các lập trình viên khác mở rộng lớp học hoặc ghi đè phương pháp nhằm mục đích kiểm tra cấu trúc nội bộ của lớp học. Việc phòng ngừa như vậy được coi là một trong những cách để bảo vệ đơn đăng ký khỏi bị khai thác độc hại.

Điều này có ám chỉ đến người dùng API của gói đã đóng, được biên dịch và "khai thác độc hại" để tìm hiểu về thiết kế lớp học không? Đây thực sự là một vấn đề?

Đối với một số ngữ cảnh khác, đó là lý do thứ hai trong hai lý do để sử dụng final. Trong ấn bản năm 2007, nó nằm ở trang 113 trong chương Thừa kế theo phụ đề Ngăn các lớp bị mở rộng và phương thức bị ghi đè.

Thuộc tính chính thức được sử dụng vì hai lý do trong ActionScript:

  • Trong một số trường hợp, các phương pháp chính thức thực hiện nhanh hơn so với các phương pháp phi chính thức. Nếu bạn đang tìm cách cải thiện hiệu suất của ứng dụng của bạn theo mọi cách có thể, hãy thử thực hiện các phương pháp cuối cùng. Tuy nhiên, lưu ý rằng trong thời gian chạy Flash trong tương lai, Adobe hy vọng các phương pháp không phải cuối cùng sẽ thực thi nhanh như phương pháp cuối cùng.

  • Phương pháp trợ giúp cuối cùng sẽ ẩn chi tiết nội bộ của lớp học. Thực hiện lớp học hoặc phương pháp cuối cùng là phương pháp ngăn các lập trình viên khác mở rộng lớp học hoặc ghi đè phương pháp nhằm mục đích kiểm tra cấu trúc nội bộ của lớp học. Phòng ngừa như vậy được coi là một trong những cách để bảo vệ một ứng dụng khỏi bị khai thác độc hại.

Trả lời

8

Trong nhiều ngôn ngữ, phương pháp ghi đè được chọn tham gia từ lớp cơ sở. Thông thường, đó là từ khóa virtual cho phép tác giả lớp cơ sở chọn tham gia để có khả năng ghi đè.

Trong AS3, tuy nhiên, khả năng ghi đè phương thức là không tham gia. Đó là điều mà từ khóa final thực hiện. Nó cho phép tác giả lớp cơ sở nói "phương pháp này có thể không bị ghi đè".

Có một số suy nghĩ trường học cũ về đóng gói có thể cho thấy rằng đó là một vấn đề an ninh cho AS3 để làm điều đó theo cách này. Nhưng điều này chủ yếu là trong trường hợp các API công khai mà bạn muốn ẩn nội dung của mình nhưng hiển thị chức năng.

Nhưng, trong thời hiện đại hơn, chúng tôi đã biết rằng việc tháo gỡ và phản chiếu sẽ cho phép nhà phát triển độc hại thực hiện bất kỳ điều gì anh ấy/cô ấy muốn, vì vậy đây là vấn đề ngày hôm nay. Dựa trên final để bảo mật là một cái nạng, theo ý kiến ​​của tôi, và bất kỳ đề nghị của nó nên được miễn nhiệm. An ninh cần phải được suy nghĩ cẩn thận hơn thế.API cần phải được kiến ​​trúc để việc triển khai cho phép các nhà phát triển làm những gì cần làm, nhưng thông tin quan trọng về bảo mật không nên được đưa vào API công khai.

Điều đó không có nghĩa là final không hữu ích. final cho các nhà phát triển biết được từ lớp học của bạn rằng bạn không bao giờ muốn họ ghi đè chức năng. Nó cho phép bạn nói "xin vui lòng chỉ cần gọi chức năng này. Đừng ghi đè lên." Nó là một giao diện hay cơ chế truyền thông nhiều hơn bất kỳ thứ gì khác, IMO.

1

từ khóa cuối cùng không được sử dụng cho loại bảo mật này. Nó không phải là một thay thế cho những gì bình thường sẽ yêu cầu một giải pháp mã hóa. Điều này thường có nghĩa là "bảo mật" trong các loại thảo luận này là khái niệm về một mô hình đối tượng an toàn - đó là để nói một mô hình đối tượng không thể được người tiêu dùng thao tác cho các mục đích ngoài ý muốn của tác giả gốc của lớp.

Đó là sắp xếp, một lớp được xây dựng tốt sẽ đóng gói trạng thái của nó và một lớp chỉ có phương pháp cuối cùng sẽ không cho phép người tiêu dùng ghi đè hành vi của lớp và thay đổi cách trạng thái được đóng gói. Một lớp có thể phơi bày trạng thái của nó (thông qua các trường công cộng chẳng hạn) và không có từ khóa cuối cùng nào có thể bảo vệ tính toàn vẹn của trạng thái đó.

Thông tin thêm về "thay đổi" nội dung thay vì "bảo mật". Các từ khóa cuối cùng chỉ đơn giản là bỏ đi khả năng thay đổi/sửa đổi/mở rộng bất kỳ phương thức nào.

Nó không làm cho mã của bạn an toàn hơn, nó là nhiều hơn cho an toàn chủ đề hơn bất cứ điều gì khác. Nếu một biến được đánh dấu cuối cùng, một giá trị phải được gán cho nó khi đối tượng được tạo. Sau khi tạo đối tượng, biến đó không thể được thực hiện để chỉ một giá trị khác.

Hành vi này cho phép bạn giải thích lý do về trạng thái của một đối tượng và đưa ra các giả định nhất định khi nhiều chuỗi truy cập đồng thời.

Tôi không nghĩ rằng làm cho một lĩnh vực cuối cùng sẽ thêm an ninh chống lại các cuộc tấn công nguy hiểm (nhiều khả năng chống lại những sai lầm và tất nhiên các vấn đề luồng). "Hình thức thực" duy nhất của bảo mật là nếu bạn có một trường liên tục cuối cùng, nó có thể được biên dịch tại biên dịch để thay đổi giá trị của nó trong thời gian chạy sẽ không có tác động.

Tôi đã nghe nói về cuối cùng và bảo mật hơn trong ngữ cảnh thừa kế. Bằng cách tạo ra một lớp cuối cùng, bạn có thể ngăn chặn một người nào đó phân lớp và chạm vào hoặc ghi đè các thành viên được bảo vệ của nó, nhưng một lần nữa tôi sẽ sử dụng nó nhiều hơn để tránh nhầm lẫn hơn để ngăn chặn các mối đe dọa.

+0

'final' thực sự hữu ích để giảm lỗi. Điều khiến mắt tôi bị "khai thác một cách độc hại". Bạn đang nói rằng 'final' không ảnh hưởng đến các cuộc tấn công nguy hiểm? – Tim

+0

Nó không phải là 'an ninh' theo nghĩa 'chịu đựng một cuộc tấn công'. nó giống như 'khó khăn hơn để sai lầm do nhầm lẫn'. Tôi thích từ 'an toàn'; tôi cảm thấy nó giống như ngăn ngừa một tai nạn, không phải là ác ý. –

+0

Tôi đồng ý; loại bảo mật/an toàn đó được cung cấp bởi 'final'. Cuốn sách tuyên bố rằng điều này bảo vệ chống lại các cuộc tấn công nguy hiểm, đó là một cái gì đó khác với những sai lầm không chủ ý. – Tim

0

Giả sử bạn phát hành một số thư viện SWC ưa thích cho công chúng. Trong trường hợp này, bạn có thể ngăn chặn một phương pháp từ ong ghi đè.

package 
{ 
    import flash.display.Sprite; 

    public class FinalDemo extends Sprite 
    { 
     public function FinalDemo() 
     { 
      super(); 
      var someClientInstance:ExtendedAPIClient = new ExtendedAPIClient(); 
      // doSomething is overridden by ExtendedAPIClient 
      someClientInstance.doSomething(); 
      // activate cannot be overridden 
      someClientInstance.activate("mySecretAPIKey"); 

      var myApp:MySupaDupaApplication = new MySupaDupaApplication(someClientInstance); 

     } 
    } 
} 

/** 
* Assume this class is within a swc that you release to the public. 
* You want every developer to get some APIKey 
* */ 
internal class MySupaDupaApplication{ 
    public function MySupaDupaApplication($apiClient:APIClient):void{ 
     if($apiClient.activated)trace("It's a valid user, do something very cool"); 
    } 
} 

/** 
* In order to activate a Client the developer needs to pass a 
* instance of the API Client to the Application. 
* The application checks the activated getter in order to determine 
* if the api key is valid. 
* */ 
internal class APIClient{ 

    private var __activated:Boolean = false; 

    public function APIClient(){   
     trace("APIClient Constructor"); 
    } 

    /** 
    * override possible 
    * */ 
    public function doSomething():void{ 
     trace("doing something"); 
    } 

    /** 
    * override not possible 
    * */ 
    public final function activate($key:String):void{ 
     trace("activate "+$key); 
     if($key == "mySecretAPIKey"){ 
      __activated = true; 
     }else{ 
      __activated = false; 
      throw new Error("Illegal Key"); 
     } 
    } 

    /** 
    * override not possible 
    * */ 
    public final function get activated():Boolean{ 
     return __activated; 
    } 
} 

/** 
* Class within some developers library using MySupaDupaApplication 
* Changes the Client behaviour 
* Exploit of activation not possible 
* */ 
internal class ExtendedAPIClient extends APIClient{ 

    public function ExtendedAPIClient(){ 
     trace("ExtendedAPIClient Constructor"); 
     super(); 
    } 

    override public function doSomething():void{ 
     trace("doing something else"); 
    } 

    /* this will throw a compiler error */ 
    /* 
    override public function activate($key:String):void{ 
     // do nothing 
    } 

    override public function get isActivated($key:String):Boolean{ 
     return true; 
    } 
    */ 
} 
+0

Tôi cho rằng bạn _could_ gọi bảo mật đó :) Dường như không quan trọng để làm việc xung quanh bằng cách giải mã mã byte. – Tim

+0

Vì tôi hiểu báo giá này là vấn đề bảo mật được đề cập. Nhưng bạn đúng, giải mã là một vấn đề an ninh nghiêm trọng, ngay cả khi bạn sử dụng một số scrambler mã. Do đó tất cả các quy trình quan trọng cần được triển khai trên máy chủ web. :-) – goldsource

Các vấn đề liên quan