2009-11-05 35 views
36

Tôi đã đọc về các cuộc tấn công SQL injection và cách tránh chúng, mặc dù tôi không bao giờ có thể làm cho các ví dụ "khủng khiếp" được cung cấp cho công việc, ví dụ: see this post.SQL Injection có phải là rủi ro hiện nay không?

Tôi đã tạo tệp PHP và bảng trong cơ sở dữ liệu, có giá trị được chuyển qua $_GET và cố gắng xóa bảng bằng cách thực hiện bob'); drop table students; -- và không hoạt động. PHP tự động thoát khỏi \' và truy vấn có lỗi, không có hại gì được thực hiện. Cùng một vấn đề khi cố gắng tái tạo đăng nhập "tấn công" như AND WHERE 1=1, vv

mã ví dụ:

<?php 
$id = $_GET['id']; 

$sql = "INSERT INTO Users (Username) VALUES ($id)"; 
echo $sql; 
mysql_query($sql) or die(mysql_error()); 

Và tôi muốn vượt qua sql.php?id=1); delete from Users; --

Vậy là này một số điều đề ngày được sử dụng để áp dụng trong các ngày của PHP3 hoặc một cái gì đó, và ngày nay thậm chí người mới được bảo vệ khỏi những thứ như dấu ngoặc kép ma thuật?

Tôi đang sử dụng PHP5 trên Ubuntu.

+0

câu hỏi của bạn vẫn còn rất có liên quan. Bạn sẽ thấy câu trả lời một số bài viết trong thẻ PHP. Ví dụ như thế này: http://stackoverflow.com/a/11908119/220060 - chúng xén lại một lần nữa. Có thể với những máy quét dễ bị tổn thương tự động này, chúng sẽ chết như ruồi. Tôi đã gặp phải thành công đầu tiên năm 2010. Trang chủ của công ty chúng tôi đã bị tấn công trong vòng vài phút sau cuộc tấn công. – nalply

+1

@ tereško Tôi không nghĩ đây là bản sao chính xác. Câu hỏi đó đang hỏi * cách * để ngăn ngừa tiêm. Câu hỏi này là hỏi * tại sao * dấu ngoặc kép ma thuật không phải là cách để ngăn ngừa tiêm. – luiscubal

Trả lời

57

Khá ngược lại. Trích dẫn phép thuật không được chấp nhận trong PHP5 và sẽ bị xóa hoàn toàn trong PHP 5.4, vì chúng mang lại nhiều sự nhầm lẫn cho thế giới lập trình hơn là chúng đã làm tốt. Kiểm tra xem các dấu ngoặc kép có hoạt động hay không, và thoát khỏi bất kỳ đầu vào SQL nào một cách thận trọng nếu cần thiết, vẫn rất, rất quan trọng ... Không có lý do gì để cảm thấy xấu, tất cả chúng ta đã ở đó, và ass vô tình của tôi đã được cứu bởi times :)

PHP manual trên báo giá kỳ diệu giải thích mọi thứ.

+0

Tại sao nó quan trọng nếu tôi không thể làm hỏng cơ sở dữ liệu ngay cả khi tôi thử?Tôi có thể thấy SQL gốc, điều này khiến tôi dễ dàng hơn kẻ tấn công. Tôi muốn thấy sự quan trọng của đầu vào thoát nếu các cuộc tấn công thực sự hoạt động. – Richard

+14

Điều quan trọng là vì một ngày nào đó, máy chủ của bạn sẽ chuyển sang PHP 6, bỏ lỡ magic_quotes từ đó, và đột nhiên, các cuộc tấn công là có thể. –

+7

Chỉ vì một lần thất bại không có nghĩa là tất cả sẽ. Bạn cũng đang thiếu điểm của nhận xét này - điều bạn đang tiết kiệm trong trường hợp này đang bị xóa khỏi PHP. – ceejayoz

35

Điều này vẫn rất phù hợp.

Như là XSS và CSRF. Không bao giờ đánh giá thấp tầm quan trọng của việc lọc đầu vào phù hợp.

+2

SQL Injection và Cross-site scripting đều đang tràn lan. –

+0

+1: để tìm các ví dụ không hoạt động với cấu hình cụ thể của bạn. Cứ nhìn. Các tin tặc nghiêm túc đang phân tích nguồn cho PHP5 cố gắng tìm cách thoát khỏi sự trốn thoát. Chỉ vì bạn không độc hại vì chúng không có ý nghĩa nhiều. Họ sẽ tìm thấy lỗ hổng trong PHP. Bạn sẽ muốn bạn đã không thông qua SQL dựa trên đầu vào của người dùng. –

+0

-1: không giải thích. cf. w/Câu trả lời của Pekka Gaiser, giải thích tại sao cuộc tấn công đặc biệt do OP thực hiện không hoạt động trong cấu hình cụ thể của anh ta. –

7

Đây là một rủi ro rất tích cực, báo giá ma thuật cố gắng cung cấp cho bạn giải pháp nhưng tôi muốn luôn phát triển với dấu ngoặc kép. Bằng cách này tôi phải chắc chắn rằng tôi thực sự thoát khỏi các yếu tố đầu vào bản thân mình. Ai biết được nếu dấu ngoặc kép ma thuật sẽ bật hoặc tắt trên máy chủ nơi tập lệnh thực sự được triển khai.

3

Không, và bạn càng ít lo lắng về SQL Injection, bạn càng có nhiều khả năng bị tấn công bởi nó.

7

Đây vẫn là một vấn đề lớn. Bạn không thể giả định rằng magic_quotes được bật trong mọi cài đặt PHP bạn có thể sử dụng.

Để xem nếu qotes kỳ diệu được bật và dọn dẹp đống lộn xộn từ báo giá ảo thuật:

if (get_magic_quotes_gpc() !== 0) { $foo = stripslashes($foo); } 

Sau đó làm sạch báo cáo của bạn một chút:

$foo = mysql_real_escape_string($foo); 
$sql = "select * from foo where bar='{$foo}'"; 

, vv

Thực tế, bạn nên tắt hoàn toàn việc magic_quotes nếu bạn có khả năng làm như vậy.

Tôi hy vọng điều đó sẽ giúp ích cho bạn.

10

Tấn công cụ thể đó không hoạt động, vì mysql_query sẽ chỉ thực thi một câu lệnh đơn.

Tôi vẫn có thể lạm dụng mã của bạn, ví dụ: nếu tôi sắp xếp cho id là SELECT password FROM Users WHERE Username='admin' Tôi có thể có cơ hội chiến đấu để có thể khiến hệ thống của bạn hiển thị một số thông tin nội bộ. Về cơ bản, nếu bạn cho phép đầu vào chưa được lọc vào SQL của mình, sẽ có một số cách rất sáng tạo của cả việc tạo dữ liệu bạn không mong đợi và hiển thị dữ liệu bạn không có ý định!

+0

Vì vậy, nếu mysql_query chỉ làm một tuyên bố duy nhất tôi cũng an toàn khỏi điều đó ..? – Richard

+0

Bạn được an toàn từ một người nào đó xóa bảng người dùng của bạn. Ở đây bạn dễ bị một số người đăng nhập như bất cứ ai họ muốn. – jmucchiello

+2

Bạn không thể chỉ chắp thêm một câu lệnh thứ hai có mysql_query chạy nó, nhưng bạn có thể tạo một chuỗi chứa một truy vấn phụ, đó là những gì tôi đang lái xe. Truy vấn con này có thể được sử dụng để thăm dò cơ sở dữ liệu của bạn, hoặc thay đổi hiệu ứng trong hành vi của truy vấn dự định. –

3

Các tham số được chuyển tới truy vấn sql từ các trang web ofen có xu hướng là ID số. Ví dụ chúng ta hãy giả sử bạn có một địa chỉ http://foo.com/page.php?section=34 mà từ đó các phần ID được sử dụng trong một truy vấn như thế này:

SELECT content FROM sections WHERE section_id=$section; 

Không dấu ngoặc kép để thoát như trong ví dụ của bạn và bất cứ điều gì bạn sẽ đặt sau số trong URL sẽ được chuyển đến truy vấn ... Vì vậy, nguy cơ của w là có thật.

+0

'intval()' là bạn của bạn. Hoặc phần mở rộng 'filter' gần đây trong PHP. –

+0

@Bill Karwin - Tất nhiên. Quan điểm của tôi là việc tiêm SQL vẫn là một vấn đề nếu bạn bỏ qua các kỹ thuật này vì không có gì tự động bảo vệ bạn. – quosoo

+0

Có, chắc chắn. Tôi đã không đi qua bất kỳ công cụ hoặc kỹ thuật đó là bằng chứng hoàn hảo chống lại SQL injection, ngắn siêng năng truy tìm nguồn gốc của mỗi biến interpolated vào một chuỗi SQL. –

7

Ví dụ về bảng bobby sẽ không hoạt động với giao diện mysql vì nó không thực hiện nhiều truy vấn trong một cuộc gọi. Giao diện mysqli dễ bị tấn công nhiều truy vấn. Giao diện mysql dễ bị tấn công tăng cường đặc quyền:

Trong mẫu của bạn, tôi nhập tài khoản: admin mật khẩu: ' or 1=1 -- để đăng nhập điển hình của bạn sql: select * from users where user_name = '$admin' and password = '$password'. Hoặc làm cho điều này trở thành sự thật và cho phép bạn đăng nhập.

+0

Tôi có thể thấy cách thức này sẽ hoạt động, tuy nhiên điều này sẽ không ảnh hưởng đến những người mã hóa mật khẩu của họ, hoặc thậm chí nếu không, hãy viết truy vấn dưới dạng mật khẩu chọn từ Người dùng trong đó username = 'blah' và sau đó so sánh mật khẩu vào mật khẩu đã gửi. – Richard

+0

Richard, việc thay đổi dạng của SQL là một kiểu bảo vệ SQL injection. Ngăn chặn SQL injection yêu cầu bạn sử dụng SQL cẩn thận. Giải pháp SQL để xác thực người dùng là thực hiện lựa chọn nếu không tìm thấy nó, người dùng không được xác nhận. Giải pháp đó bỏ qua thực tế của web. Vì vậy, để làm việc, bạn phải sửa đổi SQL của bạn để đối phó với thực tế của web. – jmucchiello

3

Quy tắc đơn giản nhất là giả định rằng tất cả người dùng input đều có thể bị nhiễm độc. Kiểm tra xem loại dữ liệu có phải là những gì bạn mong đợi hay không, các biến nằm trong phạm vi chiều dài/kích thước bạn mong đợi, các tệp có kích thước và loại bạn cho phép, v.v. Các kiểm tra khác về dữ liệu ngoài không được bảo hành - trước khi bạn gọi một số quản trị viên quan trọng chức năng -level, làm một số kiểm tra - ($userlevel != ADMIN)?die():important_function();

Luôn luôn có một con cá lớn hơn, hoặc người nào đó lớn hơn bạn. Tránh các giả định về dữ liệu và bạn đã có một khởi đầu.

+0

kiểm tra quản trị thực sự nên được bên trong chức năng quan trọng của bạn – Kris

+0

@ Kris: Bây giờ bạn đề cập đến nó ... đó là cách tôi làm điều đó. Tôi đã nghĩ đến việc kiểm tra tôi làm trong mã, nhưng quên rằng tôi làm điều đó ở đầu của hàm. Bạn đúng 100%. –

4

Có rất nhiều cách khác nhau để thực hiện SQL Injection và khá nhiều cách để bỏ qua các biện pháp phòng ngừa an toàn cơ bản.

Các cuộc tấn công đó nằm trong 10 lỗ hổng ứng dụng web hàng đầu (thứ hạng # 2) theo OWASP.

Để biết thêm thông tin, vui lòng tham khảo Top 10 2007-Injection Flaws.

7

PHP không thể thực hiện các tham số truy vấn? Nếu nó có thể (như tôi sẽ ngạc nhiên nếu nó không), đó là một trong những giải pháp giảm nhẹ tất cả các cuộc tấn công SQL injection.

+1

Phần mở rộng mysql mà hầu hết mọi người sử dụng trong PHP không thể thực hiện các tham số truy vấn. Phần mở rộng mysqli nâng cao hơn một chút, và trình điều khiển mysql PDO * làm * hỗ trợ các tham số truy vấn, nhưng phần mở rộng mysql cũ hơn vẫn được sử dụng rộng rãi hơn. –

+0

tiếc là Bill Karwin là đúng, do đó, ngừng giảng dạy những người cũ và lỗi thời giao diện người dùng mysql! – Kris

+0

Xin lỗi, tôi không có ý định bắt đầu một cuộc chiến tranh lửa. Tôi thành thật ngạc nhiên. – erikkallen

15

Trích dẫn kỳ diệu không tính đến mã hóa ký tự và do đó dễ bị tấn công dựa trên các ký tự multi-byte.

Vì ngày nay nó là một rủi ro, tìm kiếm của Google có vô số trang web dễ bị tổn thương. Lỗ hổng SQL Injection đã được báo cáo cho Bugzilla vào khoảng ngày 10 tháng 9. Vì vậy, có, các trang web vẫn có nguy cơ.Họ có nên không? Các công cụ ở đó để ngăn ngừa tiêm, vì vậy không.

+0

+1 để liên kết bài viết của Chris Shiflett về các bộ ký tự kỳ lạ. –

+0

+1 cho cùng lý do đó từ tôi quá – Kris

20

Việc đánh cắp nhận dạng lớn nhất trong lịch sử đã đạt được trong năm 2007 bằng cách khai thác lỗ hổng SQL injection: xem "SQL injection attacks led to Heartland, Hannaford breaches" (ComputerWorld, 8/18/2009).

OWASP reported in 2007 rằng các cuộc tấn công tiêm (trong đó SQL injection là một ví dụ) tiếp tục là một trong những vấn đề bảo mật phần mềm phổ biến nhất.

Bạn cũng có thể tìm kiếm SQL injection News gần đây và tìm thấy nhiều trường hợp được báo cáo mỗi tháng.

Tuy nhiên, ví dụ trong phim hoạt hình XKCD không nhất thiết phải là loại phổ biến nhất của khai thác. Việc bỏ một bảng bằng cách thực hiện một câu lệnh SQL thứ hai trong một yêu cầu có thể sẽ không thu hút được nhiều kẻ tấn công theo cách dữ liệu có giá trị, nó sẽ chỉ là phá hoại.

Ngoài ra, một số giao diện truy vấn không cho phép multi-query theo mặc định anyway. Tức là, API máy khách cơ sở dữ liệu chỉ thực hiện một câu lệnh duy nhất cho chuỗi SQL, bất kể dấu chấm phẩy. Điều này đánh bại ví dụ thể hiện trong phim hoạt hình.

lưu ý: Phương pháp query() PDO được biết đến hỗ trợ đa truy vấn theo mặc định. Vì vậy, nó là dễ bị tấn công XKCD kiểu.

Như folks khác đã chỉ ra, nguy cơ nhiều khả năng là một SQL injection sẽ làm thay đổi logic của biểu thức SQL, và áp dụng các truy vấn của bạn đến hàng thêm ngoài những người bạn dự định.

Ví dụ:

$sql = "UPDATE Users SET PASSWORD = MD5('" . $_POST["password"] . "'||salt) " . 
     "WHERE user_id = " . $_POST["userid"]; 

gì xảy ra khi tôi gửi một yêu cầu với tham số userid đặt thành chuỗi 123 OR userid=456? Tôi sẽ thiết lập lại mật khẩu của riêng tôi (userid 123) cũng như mật khẩu của userid 456. Ngay cả khi băm mật khẩu với muối cho mỗi người dùng sẽ không bảo vệ chống lại điều này. Bây giờ tôi có thể đăng nhập vào một trong hai tài khoản.

Có rất nhiều cách để tiêm SQL có thể được khắc phục.

5

Như tôi đã đề cập nhiều lần về stackoverflow trước đây, tôi là người ủng hộ mạnh mẽ PDO, chỉ cần ngừng sử dụng mysql cũ, tự làm và khách hàng của bạn một ưu tiên lớn và học PDO (thật sự dễ dàng) và tận dụng các câu lệnh chuẩn bị và các thông số ràng buộc. Ngay cả khi bạn không cần chuẩn bị báo cáo hiệu suất khôn ngoan, bạn vẫn nhận được những lợi ích bảo mật.

Ngoài ra, tôi sẽ khuyên bạn nên làm rơi toàn bộ ứng dụng của bạn trong khuôn mặt khách hàng nếu báo giá ma thuật được đặt thành bật. Nó chỉ là một cống trên các nguồn lực được thiết kế để bảo vệ câm và làm phiền thông minh. (nó sử dụng nhiều CPU hơn thoát bằng tay, vì nó mã hóa mọi thứ, ngay cả khi bạn không cần nó)

+0

+1 Có để sử dụng PDO trong các ứng dụng PHP! –

9

Oh my .. SQL Injection không phải là rủi ro, nó là lỗ hổng bảo mật gaping. Nó chủ yếu tồn tại trong php bởi vì API làm cho bạn muốn nội suy bất kỳ dữ liệu cũ vào các truy vấn SQL của bạn.

Khi tôi nhìn thấy một trang web viết bằng PHP hay ASP, tôi chỉ có thể ngửi thấy các vectơ SQL injection rằng họ reek của. Mọi người cố gắng để bảo đảm các ứng dụng PHP của họ với mysql_real_escape_string()intval() và làm tương tự như trong các ngôn ngữ khác. Đây là một sai lầm.Nó giống như mã hóa trong C thay vì Java hoặc Python, ở nơi trước đây, bạn mắc phải một sai lầm và bạn đã chết, nhưng trong trường hợp thứ hai, chỉ có các sai sót ngữ nghĩa mới có thể tồn tại.

Tôi khuyến khích mọi người sử dụng mysqli với các câu lệnh đã chuẩn bị hoặc bất kỳ thứ gì khác được tham số, thay thế văn bản thành mã và sau đó giải thích nó chỉ là thực hành không tốt ở nơi đầu tiên IMHO.

Một lưu ý khác, dấu ngoặc kép kỳ diệu của PHP chỉ là ngớ ngẩn, và may mắn là không được dùng nữa. Nó chỉ có thể gây hại nhiều hơn là tốt. Nếu bạn dựa vào dấu ngoặc kép ma thuật, điều đó có nghĩa là ứng dụng của bạn sẽ được sở hữu khi báo giá phép thuật bị tắt. Tương tự, nó có thể phá vỡ các ứng dụng khác mà không mong đợi chuỗi thoát trong đầu vào.

+2

Tôi hỗ trợ đề xuất sử dụng tham số truy vấn. Nhưng tôi nghĩ rằng đó là sai để tuyên bố rằng SQL injection xảy ra chủ yếu trong PHP hoặc ASP. Nó có thể và không xảy ra tràn lan trong tất cả các ngôn ngữ, bao gồm các thủ tục lưu sẵn SQL. –

+1

Xin lỗi, tôi chỉ muốn cung cấp cho PHP và ASP làm ví dụ, vì chúng thường được sử dụng với cơ sở dữ liệu SQL. Thật buồn cười khi thấy những người đang cố gắng sử dụng nhạy cảm đầu vào và printf trong C, khi họ có thể vừa mới sử dụng các câu lệnh chuẩn bị sẵn sàng. –

+1

o_O Tôi không nhớ viết "nhạy cảm", và tôi không uống ... –

0

Bất cứ khi nào xây dựng SQL từ chuỗi, SQL injection là một mối nguy hiểm thực sự.

Tôi cũng phát hiện ra rằng cố gắng tránh xây dựng SQL từ chuỗi là một nỗ lực vô nghĩa. Sớm hay muộn hình thức đầy đủ của SQL của bạn (không chỉ những thứ có thể là các tham số) phải được tạo ra khi chạy.

0

Tôi phải phát triển cho một máy chủ không có cách nào để tôi tắt magic_quotes! Tôi bao gồm điều này trên mỗi trang để hoàn tác các hiệu ứng của dấu ngoặc kép, vì vậy tôi có thể tự mình thoát đúng cách mà không cần \ 'thoát kép'. Mặc dù tôi có thể nếm được chất nôn chỉ vì đọc cái này, tôi đã không tìm được một giải pháp tốt hơn.

if (get_magic_quotes_gpc()) { 

    $process = array(&$_GET, &$_POST, &$_COOKIE, &$_REQUEST); 

    while (list($key, $val) = each($process)) { 

     foreach ($val as $k => $v) { 

      unset($process[$key][$k]); 

      if (is_array($v)) { 

       $process[$key][stripslashes($k)] = $v; 

       $process[] = &$process[$key][stripslashes($k)]; 

      } else { 

       $process[$key][stripslashes($k)] = stripslashes($v); 

      } 

     } 

    } 

    unset($process); 

} 
0

Theo OWASP 2017 Top 10, vẫn Tiêm là cuộc tấn công nguy hiểm nhất và nguy hiểm.

"SQL injection luôn là rủi ro số một. Đó là phản ánh chỉ có bao nhiêu sự cố xảy ra ở đó, cũng như các yếu tố khác khiến nó rất cao" Troy Hunt - người sáng lập trang web vi phạm hasibeenpwned năm

Chỉ cần nhớ, sử dụng SQL injection chúng ta có thể đổ toàn bộ cơ sở dữ liệu, kiểm soát máy chủ web bằng cách tải lên vỏ web, vv

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