PHP და AJAX-ის გამოყენების მარტივი მაგალითი. სატესტო დავალება PHP დეველოპერისთვის პრობაციის დროს ტესტის წარმატების php


OWASP-ის მიხედვით თავდასხმების ათი ყველაზე გავრცელებული ტიპის სიაში პირველ ორ ადგილს იკავებს კოდის ინექცია და XSS (სივრცის სკრიპტირება) შეტევები. ისინი მიდიან ხელჩართული, რადგან XSS, ისევე როგორც სხვა სახის შეტევები, დამოკიდებულია ინექციის შეტევების წარმატებაზე. ეს სახელი მალავს თავდასხმების მთელ კლასს, რომლებშიც მონაცემები ინექცია ხდება ვებ აპლიკაციაში, რათა აიძულოს იგი შეასრულოს ან ინტერპრეტაცია მოახდინოს მავნე კოდის ისე, როგორც თავდამსხმელს სურს. ეს შეტევები მოიცავს, მაგალითად, XSS, SQL ინექცია, სათაურის ინექცია, კოდის ინექცია და სრული ბილიკის გამჟღავნება. და ეს მხოლოდ მცირე ნაწილია.


ინექციის შეტევები ყველა პროგრამისტისთვის საშინელებაა. ისინი ყველაზე გავრცელებული და წარმატებულია მათგან დაცვის მრავალფეროვნების, მასშტაბის და (ზოგჯერ) სირთულის გამო. ყველა აპლიკაციას სჭირდება მონაცემების მიღება სადღაც. XSS და UI Redress განსაკუთრებით ხშირია, ამიტომ მათ ცალკე თავები მივუძღვენი და გამოვყავი ზოგადი კლასისგან.


OWASP გთავაზობთ ინექციის შეტევების შემდეგ განმარტებას:


ინექციის შესაძლებლობები - როგორიცაა SQL, OS და LDAP - წარმოიქმნება, როდესაც თარჯიმანი იღებს არასანდო მონაცემებს, როგორც ბრძანების მოთხოვნის ნაწილი. მავნე მონაცემებმა შეიძლება მოატყუოს თარჯიმანი გარკვეული ბრძანებების შესრულებაში ან არაავტორიზებული მონაცემების წვდომაში.

SQL ინექცია

SQL ინექცია არის ინექციის შეტევის ყველაზე გავრცელებული და უკიდურესად საშიში ფორმა. ძნელია ამ საფრთხის სერიოზულობის გადაჭარბება, ამიტომ ძალზე მნიშვნელოვანია იმის გაგება, თუ რა გავლენას ახდენს თავდასხმების წარმატებაზე და როგორ დავიცვათ თავი მათგან.


ამრიგად, მონაცემები ინექცია ხდება ვებ აპლიკაციაში და შემდეგ გამოიყენება SQL შეკითხვებში. ისინი, როგორც წესი, მოდის არასანდო შეყვანის წყაროებიდან, როგორიცაა ვებ ფორმები. თუმცა, ინექცია შეიძლება სხვა ადგილებიდანაც, ვთქვათ, თავად მონაცემთა ბაზიდან. პროგრამისტებს ხშირად სჯერათ მათი მონაცემთა ბაზის სრული უსაფრთხოების, ვერ აცნობიერებენ, რომ თუ ის უსაფრთხო იყო ერთ შემთხვევაში, ეს საერთოდ არ ნიშნავს იმას, რომ ის მომავალში უსაფრთხო იქნება. მონაცემთა ბაზიდან მიღებული მონაცემები უნდა ჩაითვალოს არასანდო მანამ, სანამ სხვა რამ არ დამტკიცდება, ანუ არ მოხდება მისი შემოწმება.


თუ შეტევა წარმატებულია, თავდამსხმელს შეუძლია SQL მოთხოვნის მანიპულირება ისე, რომ მან შეასრულოს ოპერაციები მონაცემთა ბაზაში, რომლებიც არ არის განკუთვნილი დეველოპერების მიერ.


შეხედე ამ შეკითხვას:


$db = new mysqli("localhost", "username", "password", "storedb"); $result = $db->query("SELECT * FROM ტრანზაქციებიდან WHERE user_id = " . $_POST["user_id"]);

აქ არაერთი ჯამბია. პირველი, ჩვენ არ შევამოწმეთ POST მონაცემების შინაარსი, რათა დავრწმუნდეთ, რომ user_id არის სწორი. მეორეც, არასანდო წყაროს უფლებას ვაძლევთ, გვითხრას, რომელი user_id გამოვიყენოთ: თავდამსხმელს შეუძლია გადაიჩეხოს ნებისმიერი მოქმედი user_id. ის შესაძლოა შეტანილი იყო ფორმის დამალულ ველში, რომელიც ჩვენ ვფიქრობდით, რომ უსაფრთხო იყო, რადგან მისი რედაქტირება შეუძლებელია (თუმცა დავივიწყეთ, რომ თავდამსხმელებს შეეძლოთ ნებისმიერი მონაცემების შეყვანა). მესამე, ჩვენ არ გავურბივართ user_id-ს და არ გადავიტანეთ იგი მოთხოვნაში, როგორც შეკრული პარამეტრი, რაც ასევე საშუალებას აძლევს თავდამსხმელს შეიყვანოს თვითნებური სტრიქონები, რომლებიც მოახდენს მანიპულირებას SQL მოთხოვნით, იმის გათვალისწინებით, რომ თავიდანვე ვერ შევძელით მისი შემოწმება.


ეს სამი გამოტოვება ძალიან ხშირია ვებ აპლიკაციებში.


მონაცემთა ბაზის ნდობასთან დაკავშირებით, წარმოიდგინეთ, რომ ჩვენ ვეძებდით ტრანზაქციებს მომხმარებლის_სახელის ველის გამოყენებით. სახელები ფართოა და შეიძლება შეიცავდეს ბრჭყალებს. ვთქვათ, თავდამსხმელი ინახავს სტრიქონის ინექციურ მნიშვნელობას ერთ-ერთ მომხმარებლის სახელში. როდესაც ამ მნიშვნელობას ხელახლა ვიყენებთ ერთ-ერთ შემდეგ მოთხოვნაში, ის მანიპულირებს შეკითხვის სტრიქონზე, რადგან ჩვენ მივიჩნევთ მონაცემთა ბაზას სანდო წყაროდ და არ გამოვყავით ან შეზღუდავთ კომპრომეტირებული მოთხოვნას.


ასევე ყურადღება მიაქციეთ სხვა ფაქტორს SQL განხორციელებისას: მუდმივი შენახვა ყოველთვის არ არის საჭირო სერვერზე შენახვა. HTML 5 მხარს უჭერს კლიენტის მხარის მონაცემთა ბაზის გამოყენებას, სადაც შეგიძლიათ გაგზავნოთ მოთხოვნები SQL-ისა და JavaScript-ის გამოყენებით. ამისათვის არსებობს ორი API: WebSQL და IndexedDB. 2010 წელს W3C-მ არ ურჩია WebSQL-ის არჩევა; მას მხარს უჭერს WebKit ბრაუზერები SQLite-ის გამოყენებით. დიდი ალბათობით, მხარდაჭერა დარჩება ჩამორჩენილი თავსებადობისთვის, მიუხედავად W3C რეკომენდაციისა. როგორც მისი სახელი გვთავაზობს, ეს API იღებს SQL შეკითხვებს, რაც ნიშნავს, რომ ის შეიძლება იყოს საინექციო შეტევების სამიზნე. IndexedDB არის უფრო ახალი ალტერნატივა, NoSQL მონაცემთა ბაზა (არ საჭიროებს SQL მოთხოვნების გამოყენებას).

SQL ინექციის მაგალითები

SQL მოთხოვნების მანიპულირებას შეიძლება ჰქონდეს შემდეგი მიზნები:

  • მონაცემთა გაჟონვა.
  • შენახული ინფორმაციის გამჟღავნება.
  • შენახული ინფორმაციის მანიპულირება.
  • ავტორიზაციის შემოვლითი გზა.
  • კლიენტის მხრიდან SQL ინექცია.
  • SQL ინექციის დაცვა

    SQL ინექციისგან დაცვა ეშელონირების პრინციპს ეფუძნება. სანამ გამოიყენებთ მონაცემებს მოთხოვნაში, უნდა შეამოწმოთ, რომ მისი ფორმა სწორია. ასევე აუცილებელია მონაცემების იზოლირება მოთხოვნაში ჩართვის ან გადასვლის პარამეტრად ჩართვამდე.

    ექსპერტიზა

    მე ვიმეორებ: ყველა მონაცემი, რომელიც აშკარად არ იყო შექმნილი მიმდინარე მოთხოვნის PHP წყაროს კოდში, არასანდოა. შეამოწმეთ ისინი მკაცრად და უარყოთ ყველაფერი, რაც არ გაივლის ჩეკებს. ნუ ეცდებით მონაცემების „გამოსწორებას“ მხოლოდ მცირე, კოსმეტიკური ცვლილებების შეტანა.


    TO საერთო შეცდომებიეს მოიცავს მონაცემების ვალიდაციას მუდმივი გამოყენებისთვის (მაგალითად, ჩვენებისთვის ან გამოთვლებისთვის) და მონაცემთა ბაზის ველების არ დამოწმებას, რომლებშიც საბოლოოდ შეინახება ინფორმაცია.

    დამცავი

    mysqli გაფართოების გამოყენებით, შეგიძლიათ იზოლირება ყველა მონაცემი, რომელიც შედის SQL მოთხოვნაში. mysqli_real_escape_string() ფუნქცია ამას აკეთებს. pgsql გაფართოება PostgresSQL-ისთვის გთავაზობთ pg_escape_bytea() , pg_escape_identifier() , pg_escape_literal() და pg_escape_string() ფუნქციებს. mssql გაფართოებაში (Microsoft SQL სერვერი) არ არსებობს იზოლაციის ფუნქციები და addslashes() მიდგომა არაეფექტურია - დაგჭირდებათ საბაჟო .


    კიდევ უფრო გართულდეს თქვენი ცხოვრება, გეტყვით, რომ თქვენ არ გაქვთ უფლება დაუშვათ შეცდომა მოთხოვნაში შეტანილი მონაცემების იზოლირებისას. ერთი გამოტოვება და დაუცველი ხარ თავდასხმისთვის.


    შევაჯამოთ. ფარი - არა საუკეთესო ვარიანტიდაცვა. ის უნდა იქნას გამოყენებული როგორც უკანასკნელი საშუალება. ეს შეიძლება დაგჭირდეთ, თუ მონაცემთა ბაზის ბიბლიოთეკა, რომელსაც იყენებთ აბსტრაქციისთვის, საშუალებას მოგცემთ დააკონფიგურიროთ შიშველი SQL მოთხოვნები ან მოთხოვნის ნაწილები პარამეტრების შეკვრის იძულების გარეშე. სხვა შემთხვევაში, უმჯობესია თავი აარიდოთ იზოლაციას. ეს მიდგომა რთულია, შეცდომებისადმი მიდრეკილი და განსხვავდება მონაცემთა ბაზის გაფართოების მიხედვით.

    პარამეტრიზებული მოთხოვნები (მომზადებული გამონათქვამები)

    პარამეტრიზაცია, ან პარამეტრის დაკავშირება, არის რეკომენდებული გზა SQL მოთხოვნების შესაქმნელად. ყველა კარგი ბიბლიოთეკები DB-ები იყენებენ მას ნაგულისხმევად. აქ არის PDO გაფართოების გამოყენების მაგალითი PHP-სთვის:


    if(ctype_digit($_POST["id"]) && is_int($_POST["id"])) ($validatedId = $_POST["id"]; $pdo = ახალი PDO ("mysql:store.db") $stmt = $pdo->prepare("SELECT * FROM ტრანზაქცია" WHERE user_id = :id" ; id ღირებულება და შეატყობინეთ მომხმარებელს შეცდომის შესახებ)

    bindParam() მეთოდი, რომელიც ხელმისაწვდომია PDO გამონათქვამებისთვის, საშუალებას აძლევს პარამეტრების მიბმას წინასწარ მომზადებულ გამონათქვამში მოწოდებულ „placeholders“-თან. ეს მეთოდი იღებს მონაცემთა ძირითადი ტიპების პარამეტრებს, როგორიცაა PDO::PARAM_INT, PDO::PARAM_BOOL, PDO::PARAM_LOB და PDO::PARAM_STR. ეს არის ნაგულისხმევი PDO::PARAM_STR-ისთვის, თუ სხვაგვარად არ არის მითითებული, ასე რომ დაიმახსოვრეთ სხვა მნიშვნელობებიც!


    ხელით იზოლაციისგან განსხვავებით, პარამეტრის დაკავშირება (ან ნებისმიერი მეთოდი, რომელსაც იყენებს თქვენი მონაცემთა ბაზის ბიბლიოთეკა) სწორად იზოლირებს ავტომატურად შეკრულ მონაცემებს, ასე რომ თქვენ არ დაგჭირდებათ გახსოვდეთ რომელი ფუნქცია გამოიყენოთ. გარდა ამისა, პარამეტრის თანმიმდევრული დაკავშირება ბევრად უფრო საიმედოა, ვიდრე იმის მცდელობა, რომ დაიმახსოვროთ, რომ თქვენ გჭირდებათ ყველაფრის ხელით იზოლირება.

    მინიმალური პრივილეგიის პრინციპის განხორციელება

    წარმატებული SQL ინექციის შეწყვეტა ისეთივე მნიშვნელოვანია, როგორც მისი მთლიანად პრევენცია. როდესაც თავდამსხმელი იძენს SQL მოთხოვნების შესრულების უნარს, ის ამას გააკეთებს, როგორც მონაცემთა ბაზის კონკრეტული მომხმარებელი. მინიმალური პრივილეგიის პრინციპს შეუძლია უზრუნველყოს, რომ ყველა მომხმარებელს ჰქონდეს მხოლოდ ის პრივილეგიები, რომლებიც აბსოლუტურად აუცილებელია მათი ამოცანების შესასრულებლად.


    თუ მომხმარებელს აქვს მაღალი პრივილეგიები, თავდამსხმელს შეუძლია ჩამოაგდოს ცხრილები და შეცვალოს სხვა მომხმარებლების პრივილეგიები მათი სახელით ახალი SQL ინექციების შესრულებით. ამის თავიდან ასაცილებლად, არასოდეს შეხვიდეთ მონაცემთა ბაზაში ვებ აპლიკაციიდან, როგორც root, ადმინისტრატორი ან სხვა მაღალი პრივილეგიების მქონე მომხმარებელი.


    პრინციპის კიდევ ერთი გამოყენება არის მონაცემთა ბაზაში წაკითხვისა და ჩაწერის როლების გამიჯვნა. აირჩიეთ ერთი მომხმარებელი მხოლოდ ჩაწერის ნებართვით და მეორე მხოლოდ წაკითხვის ნებართვით. თუ თავდასხმა მიმართულია „კითხულ“ მომხმარებელზე, მაშინ თავდამსხმელი ვერ შეძლებს ცხრილის მონაცემებით მანიპულირებას ან დაწერას. თქვენ შეგიძლიათ კიდევ უფრო ვიწრო შეზღუდოთ წვდომა, რითაც შეამციროთ წარმატებული SQL ინექციის შეტევების გავლენა.


    ბევრი ვებ აპლიკაცია, განსაკუთრებით ის, ვისაც აქვს ღია წყარო, შექმნილია მონაცემთა ბაზის მხოლოდ ერთი მომხმარებლის გამოსაყენებლად, რომლის პრივილეგიის დონე თითქმის არასოდეს შემოწმდება. ასე რომ, არ დაივიწყოთ ეს წერტილი და ნუ ეცდებით აპლიკაციების გაშვებას ადმინისტრატორის ანგარიშის ქვეშ.

    კოდის ინექცია (ცნობილია როგორც დისტანციური ფაილის ჩართვა)

    კოდის ინექცია არის ნებისმიერი ტექნიკა, რომელიც საშუალებას აძლევს თავდამსხმელს დაემატოს ვებ აპლიკაციას წყარო კოდიმისი ინტერპრეტაციისა და შესრულების უნარით. ამ შემთხვევაში, ჩვენ არ ვსაუბრობთ კოდის შეტანას კლიენტის ნაწილში, მაგალითად JavaScript-ში აქ უკვე გამოიყენება XSS შეტევები.


    თქვენ შეგიძლიათ შეიყვანოთ წყაროს კოდი პირდაპირ არასანდო შეყვანის წყაროდან, ან აიძულოთ ვებ აპლიკაცია ჩატვირთოს ის ადგილობრივი ფაილური სისტემიდან ან გარე რესურსიდან, როგორიცაა URL. როდესაც კოდის ინექცია ხდება ჩართვის შედეგად გარე წყარო, ამას ჩვეულებრივ მოიხსენიებენ როგორც დისტანციური ფაილის ჩართვას (RFI), თუმცა თავად RFI ყოველთვის განკუთვნილია კოდის ინექციისთვის.


    კოდის შემოღების ძირითადი მიზეზები:

    • შეყვანის მონაცემების შემოწმების გვერდის ავლით,
    • არასანდო შეყვანის ინექცია ნებისმიერ კონტექსტში, სადაც ის განიხილება როგორც PHP კოდი,
    • წყაროს კოდის საცავების უსაფრთხოების გატეხვა,
    • გამორთეთ გაფრთხილებები მესამე მხარის ბიბლიოთეკების ჩატვირთვის შესახებ,
    • სერვერის ხელახლა კონფიგურაცია ისე, რომ ის გადასცემს არა PHP ფაილებს PHP თარჯიმანს.

    განსაკუთრებული ყურადღება მიაქციეთ ბოლო პუნქტს: ამ შემთხვევაში, არასანდო მომხმარებლებს შეუძლიათ ატვირთონ ნებისმიერი ფაილი სერვერზე.

    კოდის ინექციის მაგალითები

    IN PHP კომპლექტიკოდის ინექციისთვის განკუთვნილი სამიზნეები, ასე რომ, ამ ტიპის შეტევა ლიდერობს ნებისმიერი პროგრამისტის საყურადღებო სიაში.

    ფაილის ჩათვლით

    კოდის ინექციის ყველაზე აშკარა მიზნებია მოიცავს ფუნქციებს() , include_once() , request() და request_once() . თუ არასანდო შეყვანის მონაცემები საშუალებას გაძლევთ განსაზღვროთ ამ ფუნქციებზე გადაცემული ბილიკის პარამეტრი, მაშინ შეგიძლიათ დისტანციურად აკონტროლოთ რომელი ფაილი შეიტანოთ. უნდა აღინიშნოს, რომ ჩართული ფაილი არ უნდა იყოს რეალური PHP ფაილი, შეიძლება გამოყენებულ იქნას ნებისმიერი ფაილის ფორმატი, რომელსაც შეუძლია შეინახოს ტექსტური მონაცემები (ანუ თითქმის შეზღუდვების გარეშე).


    ბილიკის პარამეტრი ასევე შეიძლება იყოს დაუცველი Directory Traversal ან დისტანციური ფაილის ჩართვის შეტევების მიმართ. ../ ან... სიმბოლოების კომბინაციების გამოყენება გზაზე თავდამსხმელს საშუალებას აძლევს გადახტეს თითქმის ნებისმიერ ფაილზე, რომელზეც PHP პროცესს აქვს წვდომა. ამავდროულად, ნაგულისხმევი PHP კონფიგურაციაში, ზემოაღნიშნული ფუნქციები იღებენ URL-ს, თუ allow_url_include არ არის გამორთული.

    ექსპერტიზა

    PHP eval() ფუნქცია იღებს PHP კოდის ხაზს შესასრულებლად.

    რეგულარული გამონათქვამების განხორციელება

    PCRE (Perl Compatible Regular Expression) ფუნქცია preg_replace() PHP-ში იძლევა e მოდიფიკატორის (PREG_REPLACE_EVAL) გამოყენების საშუალებას. ეს ნიშნავს შემცვლელ სტრიქონს, რომელიც ჩანაცვლების შემდეგ ჩაითვლება PHP კოდით. და თუ ამ ხაზში არის არასანდო შეყვანა, მაშინ ისინი შეძლებენ შესრულებადი PHP კოდის შეყვანას.

    დეფექტური ფაილის ჩართვის ლოგიკა

    ვებ აპლიკაციები, განსაზღვრებით, მოიცავს ფაილებს, რომლებიც საჭიროა ნებისმიერი მოთხოვნის შესასრულებლად. თუ თქვენ იყენებთ დეფექტებს მარშრუტიზაციის ლოგიკაში, დამოკიდებულების მენეჯმენტში, ავტომატურ ჩატვირთვაში და სხვა პროცესებში, მაშინ მოთხოვნის ბილიკით ან მისი პარამეტრებით მანიპულირება სერვერს აიძულებს შეიტანოს კონკრეტული ადგილობრივი ფაილები. ვინაიდან ვებ აპლიკაცია არ არის შექმნილი ასეთი მანიპულაციების მოსაგვარებლად, შედეგები შეიძლება იყოს არაპროგნოზირებადი. მაგალითად, აპლიკაცია უნებურად ხაზს უსვამს მარშრუტებს, რომლებიც განკუთვნილია მხოლოდ გამოსაყენებლად ბრძანების ხაზი. ან გააფართოვებს სხვა კლასებს, რომელთა კონსტრუქტორები ასრულებენ დავალებებს ( უკეთესი კლასებიეს არ არის დიზაინის გზა, მაგრამ ეს მაინც ხდება). ნებისმიერმა ამ სცენარმა შეიძლება ხელი შეუშალოს აპლიკაციის უკანა ოპერაციებს, დაუშვას მონაცემთა მანიპულირება ან DOS შეტევები რესურსზე ინტენსიურ ოპერაციებზე, რომლებიც არ მოიცავს პირდაპირ წვდომას.

    კოდის ინექციის გამოწვევები

    ამოცანების დიაპაზონი უკიდურესად ფართოა, რადგან ამ ტიპის შეტევა საშუალებას გაძლევთ შეასრულოთ ნებისმიერი PHP კოდი თავდამსხმელის მიერ არჩეული.

    დაცვა Code InjectionCommand Injection-ის მაგალითები Command Injection თავდაცვის წინააღმდეგ Command InjectionLog Injection (ცნობილი, როგორც Log File Injection)

    ბევრი აპლიკაცია აგროვებს ჟურნალებს და ავტორიზებული მომხმარებლები ხშირად ნახულობენ მათ HTML ინტერფეისის საშუალებით. მაშასადამე, ჟურნალები არის თავდამსხმელთა ერთ-ერთი მთავარი სამიზნე, რომელთაც სურთ შენიღბონ სხვა შეტევები, მოატყუონ ისინი, ვინც ნახულობენ ჟურნალებს და შემდეგ კი თავს დაესხნენ მონიტორინგის აპლიკაციის მომხმარებლებს, რომლითაც ჟურნალები იკითხება და ანალიზდება.


    ჟურნალების დაუცველობა დამოკიდებულია ჟურნალის ჩაწერაზე კონტროლის მექანიზმებზე, ასევე ჟურნალის მონაცემების არასანდო წყაროდ განხილვაზე ჟურნალების ნახვისა და ანალიზის დროს.


    მარტივი ჟურნალის სისტემას შეუძლია ჩაწეროს ფაილში ტექსტის სტრიქონები file_put_contents() გამოყენებით. მაგალითად, პროგრამისტი იწერს ავტორიზაციის წარუმატებელ მცდელობებს შემდეგი ფორმატის სტრიქონების სახით:


    sprintf("%s-ის მიერ შესვლის მცდელობა წარუმატებელი", $username);

    რა მოხდება, თუ თავდამსხმელი გამოიყენებს სახელს „Adminnწარმატებული შესვლა ადმინისტრატორის მიერ“ ფორმაში?


    თუ ეს ხაზი ჩასმულია ჟურნალში არასანდო შეყვანის მონაცემებიდან, მაშინ თავდამსხმელი წარმატებით ფარავს წარუმატებელ ავტორიზაციის მცდელობას ადმინისტრატორის პაროლის შეყვანის უდანაშაულო მარცხის გამოყენებით. მონაცემების საეჭვოობა კიდევ უფრო შემცირდება, თუ დაამატებთ ავტორიზაციის წარმატებულ მცდელობას.


    აქ მთავარი ის არის, რომ თავდამსხმელს შეუძლია ყველა სახის ჩანაწერის დამატება ჟურნალში. თქვენ ასევე შეგიძლიათ შეიყვანოთ XSS ვექტორები და სიმბოლოებიც კი, რომლებიც ართულებენ ჟურნალში ჩანაწერების წაკითხვას კონსოლში.

    ჟურნალის ინექციის ამოცანები

    განხორციელების ერთ-ერთი მიზანია ჟურნალის ფორმატის ინტერპრეტატორები. თუ ანალიზის ინსტრუმენტი იყენებს რეგულარული გამონათქვამებიჟურნალის ჩანაწერების გასაანალიზებლად, რათა დაყოთ ისინი ნაწილებად და გაფანტოთ ისინი სხვადასხვა ველებში, შეგიძლიათ შექმნათ და შეიყვანოთ ხაზი, რომელიც აიძულებს რეგულარულ გამონათქვამებს შეარჩიონ ჩაშენებული ველები სწორის ნაცვლად. მაგალითად, ამ ჩანაწერმა შეიძლება გამოიწვიოს რამდენიმე პრობლემა:


    $username = "iamnothacker! ორ იან 01 00:00:00 +1000 2009"; sprintf("%s-ის მიერ %s-ზე შესვლის მცდელობა წარუმატებელი", $username,)

    ჟურნალის უფრო დახვეწილი ინექციის შეტევები ეყრდნობა დირექტორიაში გადაკვეთის შეტევებს, რათა აჩვენოს ჟურნალი ბრაუზერში. სწორ პირობებში, PHP კოდის შეყვანა ჟურნალის შეტყობინებაში და ჟურნალის ფაილის გახსნა ბრაუზერში გამოიწვევს კოდის წარმატებულ ინექციას, რომელიც კარგად არის ფორმატირებული და შესრულებულია თავდამსხმელის მოთხოვნით. და თუ საქმე ეხება მავნე PHP-ს სერვერზე შესრულებას, მაშინ მხოლოდ თავდაცვის ფენის ეფექტურობის იმედი გვაქვს, რამაც შეიძლება ზიანის შემცირება.

    ჟურნალის ინექციის დაცვა

    გარე ჟურნალის შეტყობინებების გაფილტვრის უმარტივესი გზა არის თეთრი სიის გამოყენება. ვთქვათ, ჩვენ შევზღუდავთ სიმბოლოების კომპლექტს მხოლოდ ციფრებით, ასოებით და სივრცეებით. არაავტორიზებული სიმბოლოების შემცველი შეტყობინებები ითვლება დაზიანებულად. შემდეგ ჟურნალში გამოჩნდება ჩანაწერი ჟურნალის ფაილის შეყვანის პოტენციური მცდელობის შესახებ. ეს არის მარტივი უსაფრთხოების მეთოდი მარტივი ტექსტური ჟურნალებისთვის, სადაც შეტყობინებების თავიდან აცილება შეუძლებელია არასანდო შეყვანის მონაცემების ჩათვლით.


    დაცვის მეორე მეთოდი არის არასანდო შეყვანის მონაცემების ნაწილაკების კონვერტაცია ისეთი სისტემის გამოყენებით, როგორიცაა base64, რომელიც მხარს უჭერს სიმბოლოების შეზღუდულ კომპლექტს, ხოლო შესანახად საშუალებას იძლევა ტექსტის ფორმასხვადასხვა ინფორმაცია.

    ბილიკის გავლა (ცნობილია როგორც დირექტორიაში გავლა)

    ბილიკის გავლის შეტევები არის მცდელობები, გავლენა მოახდინოს ფაილის წაკითხვის ან ჩაწერის ოპერაციებზე ვებ აპლიკაციის უკანა მხარეს. ეს კეთდება იმ პარამეტრების შემოღებით, რომლებიც საშუალებას გაძლევთ მანიპულიროთ ფაილების ბილიკებით, რომლებიც ჩართულია backend ოპერაციებში. ასე რომ, ამ ტიპის შეტევა ხელს უწყობს ინფორმაციის გამჟღავნებას და ადგილობრივი/დისტანციური ფაილის ინექციას.


    ასეთ თავდასხმებს ცალკე განვიხილავთ, მაგრამ მათი წარმატების საფუძველი სწორედ გზის გავლაა. ვინაიდან ქვემოთ აღწერილი ფუნქციები სპეციფიკურია ფაილების ბილიკების მანიპულირებისთვის, აზრი აქვს აღვნიშნოთ, რომ ბევრი PHP ფუნქცია არ იღებს ფაილის ბილიკებს ამ სიტყვის ჩვეულებრივი გაგებით. ამის ნაცვლად, ფუნქციები, როგორიცაა include() ან file() იღებენ URI-ს.


    სრულიად არაბუნებრივი გამოიყურება. მაგრამ ეს ნიშნავს, რომ შემდეგი ორი ფუნქციის გამოძახება ექვივალენტურია, რომლებიც იყენებენ აბსოლუტურ ბილიკებს (მაგალითად, ფარდობითი ბილიკების ავტომატური დატვირთვის გარეშე).


    მოიცავს('/var/www/vendor/library/Class.php'); მოიცავს ('file:///var/www/vendor/library/Class.php');

    საქმე იმაშია, რომ ფარდობითი გზა დამუშავებულია გვერდით (include_path პარამეტრი php.ini-ში და ხელმისაწვდომი ავტოჩამტვირთველები). ასეთ შემთხვევებში, PHP ფუნქციები განსაკუთრებით დაუცველია პარამეტრის მანიპულირების მრავალი ფორმის მიმართ, მათ შორის, File URI Scheme Substitution, სადაც თავდამსხმელს შეუძლია HTTP ან FTP URI-ის ინექცია, თუ არასანდო მონაცემები ჩაშენებულია ფაილის გზის დასაწყისში. ამაზე უფრო დეტალურად ვისაუბრებთ დისტანციური ფაილების ჩართვის თავდასხმების განყოფილებაში, მაგრამ ახლა ჩვენ ყურადღებას გავამახვილებთ ფაილური სისტემის ბილიკების გვერდის ავლით.


    ეს დაუცველობა გულისხმობს სხვა ფაილზე წვდომის გზის შეცვლას. ეს ჩვეულებრივ მიიღწევა არგუმენტში ../ მიმდევრობების სერიის შეყვანით, რომელიც შემდეგ დაემატება ფუნქციებს ან მთლიანად ჩასმულია ისეთ ფუნქციებში, როგორიცაა include() , require() , file_get_contents() , და კიდევ ნაკლებად საეჭვო (ზოგიერთი) ფუნქციები. მოსწონს DODocument: :load() .


    ../ მიმდევრობის გამოყენებით, თავდამსხმელი აიძულებს სისტემას დაბრუნდეს მშობლის დირექტორიაში. ასე რომ, გზა /var/www/public/../vendor რეალურად მიდის /var/www/vendor-ზე. თანმიმდევრობა ..//public-ის შემდეგ გვაბრუნებს მშობელ დირექტორიაში, ანუ /var/www. ეს საშუალებას აძლევს თავდამსხმელს, მოიპოვოს წვდომა იმ ფაილებზე, რომლებიც მდებარეობს ვებ სერვერიდან ხელმისაწვდომი / საჯარო დირექტორიას გარეთ.


    რა თქმა უნდა, გზის გავლა მხოლოდ დაბრუნებით არ შემოიფარგლება. თქვენ შეგიძლიათ დანერგოთ ახალი ბილიკის ელემენტები, რათა მიიღოთ წვდომა შვილობილ კატალოგებებზე, რომლებიც მიუწვდომელია ბრაუზერიდან .htaccess-ში შეზღუდვების პარამეტრების გამო. PHP ფაილური სისტემის ოპერაციებს არ აინტერესებთ ვებ სერვერზე არასაჯარო ფაილების და დირექტორიების წვდომის კონტროლის კონფიგურაცია.

    Path TraversalDefenses-ის მაგალითები Path TraversalXML ინექციის წინააღმდეგ

    JSON-ის, როგორც სერვერსა და კლიენტს შორის მონაცემთა გადაცემის მსუბუქ საშუალებად დანერგვის მიუხედავად, XML რჩება პოპულარულ ალტერნატივად და ვებ სერვისების API-ები ხშირად მხარს უჭერენ მას JSON-ის პარალელურად. XML ასევე გამოიყენება მონაცემთა გაცვლისთვის XML სქემების გამოყენებით: RSS, Atom, SOAP და RDF და ა.შ.


    XML ყველგან არის გავრცელებული: ის შეიძლება მოიძებნოს ვებ აპლიკაციის სერვერებში, ბრაუზერებში (როგორც სასურველი ფორმატი XMLHttpRequest მოთხოვნებისა და პასუხებისთვის) და ბრაუზერის გაფართოებებში. იმის გათვალისწინებით, რომ მისი გავრცელება და ნაგულისხმევი დამუშავება პოპულარული პარსერების მიერ, როგორიცაა libxml2, გამოიყენება PHP-ის მიერ DOM-ში და SimpleXML და XMLReader გაფართოებებში, XML გახდა საინექციო შეტევების სამიზნე. როდესაც ბრაუზერი აქტიურად მონაწილეობს XML გაცვლაში, გასათვალისწინებელია, რომ XSS-ის მეშვეობით ავტორიზებულ მომხმარებლებს შეუძლიათ გადასცენ XML მოთხოვნები, რომლებიც რეალურად შეიქმნა თავდამსხმელების მიერ.

    XML გარე ერთეულის ჩაშენება (XXE)

    ეს თავდასხმები არსებობს ბიბლიოთეკების გამო XML ანალიზიხშირად მხარს უჭერენ საბაჟო ერთეულებზე მითითებების გამოყენებას. თქვენ გაეცნობით სტანდარტული XML ერთეულის დასრულებას, რომელიც გამოიყენება წარმოსაჩენად სპეციალური პერსონაჟებიმარკირება, როგორიცაა > , < და '. XML საშუალებას გაძლევთ გააფართოვოთ სტანდარტული ერთეულების ნაკრები თავად XML დოკუმენტის მეშვეობით მორგებული ერთეულების განსაზღვრით. მათი განსაზღვრა შესაძლებელია არჩევით DOCTYPE-ში მათი უშუალოდ ჩართვის გზით. გაფართოებული მნიშვნელობა, რომელსაც ისინი წარმოადგენენ, შეიძლება ეხებოდეს გარე რესურსს, რომელიც უნდა იყოს ჩართული. XXE შეტევები პოპულარული გახდა ზუსტად ჩვეულებრივი XML-ის უნარის გამო, შეინახოს მორგებული ბმულები, რომლებიც შეიძლება გაფართოვდეს გარე რესურსების შინაარსის გამო. ნორმალურ პირობებში, არასანდო შენატანები არასოდეს უნდა იმოქმედოს ჩვენს სისტემასთან მოულოდნელი გზებით. და XXE პროგრამისტების უმეტესობა თითქმის არ ითვალისწინებს XXE შეტევებს, რაც განსაკუთრებულ შეშფოთებას იწვევს.


    მოდით, მაგალითად, განვსაზღვროთ ახალი საბაჟო ერთეული, უვნებელი:



    XML დოკუმენტს ამ განმარტებით ახლა შეუძლია მიმართოს ერთეულს, სადაც ერთეულები ზოგადად დაშვებულია:


    ეს შედეგი არის

    როდესაც XML პარსერი, როგორიცაა PHP DOM, განმარტავს ამ XML-ს, ის დაამუშავებს ამ მორგებულ ერთეულს, როგორც კი დოკუმენტი ჩაიტვირთება. ამიტომ, შესაბამისი ტექსტის მოთხოვნისას, ის დააბრუნებს შემდეგს:


    ეს შედეგი სრულიად უვნებელია


    ცხადია, მორგებულ ერთეულებს აქვთ უპირატესობა იმისა, რომ წარმოადგენენ განმეორებით ტექსტს და XML-ს უფრო მოკლე ერთეულების სახელებით. ხშირია შემთხვევა, როდესაც XML უნდა დაიცვას გარკვეული გრამატიკა, და მორგებული პირები აადვილებენ რედაქტირებას. თუმცა, გარე შეყვანის მიმართ ჩვენი უნდობლობის გათვალისწინებით, ძალიან ფრთხილად უნდა ვიყოთ ნებისმიერი XML-ის მიმართ, რომელსაც ჩვენი აპლიკაცია მოიხმარს. მაგალითად, ეს საერთოდ არ არის უსაფრთხო ჯიში:


    &harmless;

    მოთხოვნილი შინაარსის მიხედვით ადგილობრივი ფაილიმონაცემები შეიძლება გამოყენებულ იქნას ერთეულის გაფართოებისას. შემდეგ კი გაფართოებული კონტენტი შეიძლება ამოღებულ იქნეს XML პარსერიდან და შევიდეს ვებ აპლიკაციის გამავალ მონაცემებში თავდამსხმელის მიერ ანალიზისთვის. მაგალითად, ინფორმაციის გამჟღავნება. ამოღებული ფაილი განიმარტება როგორც XML, თუმცა არ არსებობს სპეციალური სიმბოლოები ამ ინტერპრეტაციის გასააქტიურებლად. ეს ზღუდავს ლოკალური ფაილის შიგთავსის გამოვლენას. თუ ფაილი ინტერპრეტირებულია როგორც XML, მაგრამ არ შეიცავს მოქმედ XML-ს, მაშინ, სავარაუდოდ, მივიღებთ შეცდომას, რომელიც ხელს შეუშლის შინაარსის გამოვლენას. თუმცა, PHP-ში ხელმისაწვდომია ზუსტი ხრიკი, რათა გადალახოს ფარგლების ლიმიტი ისე, რომ დისტანციური HTTP მოთხოვნები იმოქმედოს ვებ აპლიკაციაზე, მაშინაც კი, თუ დაბრუნებული პასუხი ვერ გადაეცემა თავდამსხმელს.


    PHP-ში XML-ის ანალიზისა და გამოყენების სამი ხშირად გამოიყენება მეთოდი: PHP DOM, SimpleXML და XMLReader. ისინი ყველა იყენებენ libxml2 გაფართოებას და გარე ერთეულების მხარდაჭერა ნაგულისხმევად ჩართულია. შედეგად, PHP ნაგულისხმევად დაუცველია XXE შეტევების მიმართ, რაც ძალიან ადვილია გამოტოვოთ ვებ აპლიკაციის ან ბიბლიოთეკის უსაფრთხოების განხილვისას, რომელიც იყენებს XML-ს.


    ასევე არ დაგავიწყდეთ, რომ XHTML და HTML 5 შეიძლება იყოს სერიული, როგორც მოქმედი XML. ეს ნიშნავს, რომ ზოგიერთი XHTML გვერდი ან XML სერიული HTML 5 შეიძლება გაანალიზდეს როგორც XML, DOMDocument::loadXML()-ის გამოყენებით DOMDocument::loadHTML()-ის ნაცვლად. XML პარსერის ეს გამოყენება ასევე დაუცველია გარე XML ერთეულების ინექციის მიმართ. გახსოვდეთ, რომ libxml2 ჯერ ვერც კი ცნობს HTML 5 DOCTYPE-ს, ამიტომ ვერ ამოწმებს მას, როგორც XHTML DOCTYPES.

    გარე XML ერთეულების განხორციელების მაგალითებიფაილის შინაარსი და გამჟღავნება

    ჩვენ გადავხედეთ ინფორმაციის გამჟღავნების მაგალითს ზემოთ და აღვნიშნეთ, რომ მორგებულ XML ერთეულს შეუძლია მიმართოს გარე ფაილს.


    &harmless;

    ამ შემთხვევაში, მორგებული ერთეული გაფართოვდება ფაილების შინაარსით. ვინაიდან ყველა ასეთი მოთხოვნა შესრულებულია ადგილობრივად, ეს საშუალებას იძლევა გამოავლინოს ყველა ფაილის შინაარსი, რომლის წაკითხვაც აპლიკაციას შეუძლია. ანუ, როდესაც გაფართოებული ერთეული შედის აპლიკაციის გამავალ მონაცემებში, თავდამსხმელს შეეძლება შეამოწმოს ფაილები, რომლებიც მიუწვდომელია. თუმცა, ამ შემთხვევაში არსებობს სერიოზული შეზღუდვა: ფაილები უნდა იყოს ან XML ფორმატში ან ისეთი ფორმატით, რომელიც არ გამოიწვევს შეცდომას XML პარსერზე. მაგრამ საქმე იმაშია, რომ ეს შეზღუდვა შეიძლება სრულიად იგნორირებული იყოს PHP-ში:


    &harmless;

    PHP უზრუნველყოფს წვდომას wrapper-ზე, როგორც URI, ერთ-ერთი პროტოკოლი, რომელიც მიღებულია სტანდარტული ფაილური სისტემის ფუნქციებით: file_get_contents(), require(), require_once(), file(), copy() და მრავალი სხვა. PHP wrapper მხარს უჭერს უამრავ ფილტრს, რომლებიც შეიძლება გამოყენებულ იქნას კონკრეტულ რესურსზე, რათა შედეგები დაბრუნდეს ფუნქციის გამოძახებით. ზემოთ მოყვანილ მაგალითში ჩვენ ვიყენებთ convert.base-64-encode ფილტრს სამიზნე ფაილზე, რომლის წაკითხვაც გვინდა.


    ეს ნიშნავს, რომ თავდამსხმელს შეუძლია წაიკითხოს ნებისმიერი ხელმისაწვდომი PHP ფაილი, ტექსტის ფორმატის მიუხედავად. საკმარისია უბრალოდ აპლიკაციიდან შემოსული მონაცემების გაშიფვრა და შემდეგ დაუსჯელად ამოკვეთა. მიუხედავად იმისა, რომ ეს პირდაპირ ზიანს არ აყენებს საბოლოო მომხმარებლებს ან აპლიკაციის უკანა ნაწილს, ის საშუალებას აძლევს თავდამსხმელებს საფუძვლიანად შეისწავლონ აპლიკაციის სტრუქტურა სხვა მოწყვლადების პოვნის მიზნით. უფრო მეტიც, თავდამსხმელების გამოვლენის რისკი მინიმალურია.

    წვდომის კონტროლის შემოვლითი გზა

    წვდომა კონტროლირებადი სხვადასხვა გზით. ვინაიდან XXE თავდასხმები განხორციელდება ვებ აპლიკაციის უკანა მხარეს, შეუძლებელი იქნება მიმდინარე მომხმარებლის სესიის გამოყენება. მაგრამ თავდამსხმელს მაინც შეუძლია გვერდის ავლით წვდომის კონტროლი ბექენდზე ადგილობრივი სერვერის მოთხოვნის გამოყენებით. განვიხილოთ ეს პრიმიტიული წვდომის კონტროლი:


    if (isset($_SERVER["HTTP_CLIENT_IP"] || isset($_SERVER["HTTP_X_FORWARDED_FOR"]) || !in_array(@$_SERVER["REMOTE_ADDR"], მასივი ("127.0.0.1", "::1 ",))) ( header ("HTTP/1.0 403 აკრძალულია"); exit ("ამ ფაილზე წვდომის უფლება არ გაქვთ"); )

    PHP-ის ეს ნაწილი, ისევე როგორც უამრავი სხვა მსგავსი, ზღუდავს წვდომას გარკვეულ PHP ფაილებზე ლოკალური სერვერი, ანუ ლოკალური მასპინძელი. თუმცა, XXE შეტევა აპლიკაციის წინა ბოლოზე თავდამსხმელს აძლევს ზუსტ სერთიფიკატებს, რომლებიც საჭიროა ამ წვდომის კონტროლის გვერდის ავლით, რადგან ყველა HTTP მოთხოვნა XML პარსერზე შესრულდება ლოკალური ჰოსტიდან.


    &harmless;

    მაშინაც კი, თუ ჟურნალის ნახვა შემოიფარგლება ლოკალური მოთხოვნებით, თავდამსხმელს მაინც შეეძლება ჟურნალების მიღება. იგივე ეხება ტექნიკური ან ადმინისტრირების ინტერფეისებს, რომლებზე წვდომა შეზღუდულია ამ გზით.

    DOS შეტევები

    თითქმის ყველაფერი, რაც კარნახობს სერვერის რესურსების მოხმარებას, შეიძლება გამოყენებულ იქნას DOS შეტევებისთვის. გარე XML ერთეულის ინექციით, თავდამსხმელს შეუძლია განახორციელოს თვითნებური HTTP მოთხოვნები, რომლებიც, სწორ პირობებში, აცლიან სერვერის რესურსებს.


    ჩვენ მოგვიანებით ვისაუბრებთ XXE შეტევების DOS-ის სხვა პოტენციურ გამოყენებაზე XML ერთეულის გაფართოების თვალსაზრისით.

    გარე XML ერთეულების ინექციისგან დაცვა

    ეს თავდასხმები ძალიან პოპულარულია, ამიტომ გაგიკვირდებათ, რამდენად ადვილია მათგან დაცვა. ვინაიდან DOM, SimpleXML და XMLReader ეყრდნობა libxml2-ს, შეგიძლიათ უბრალოდ გამოიყენოთ libxml_disable_entity_loader() ფუნქცია გარე ერთეულების გამოყენების გამორთვისთვის. თუმცა, ეს არ გამორთავს მორგებულ ერთეულებს, რომლებიც წინასწარ არის განსაზღვრული DOCTYPE-ში, რადგან ისინი არ იყენებენ გარე რესურსებს, რომლებიც საჭიროებენ HTTP მოთხოვნას ან ოპერაციას ფაილური სისტემა.


    $oldValue = libxml_disable_entity_loader(true); $dom = new DODocument(); $dom->loadXML($xml); libxml_disable_entity_loader($oldValue);

    ეს უნდა გაკეთდეს ყველა ოპერაციისთვის, რომელიც მოიცავს XML ჩატვირთვას სტრიქონებიდან, ფაილებიდან ან დისტანციური URI-ებიდან.


    სადაც აპლიკაცია არასოდეს მოითხოვს გარე ერთეულებს და მისი მოთხოვნების უმეტესობისთვის, გარე რესურსების ჩატვირთვა შეიძლება საერთოდ გამორთოთ უფრო გლობალურ დონეზე. უმეტეს შემთხვევაში, ეს ბევრად სასურველია ყველა XML ჩატვირთვის წერტილის განსაზღვრისთვის, იმის გათვალისწინებით, რომ ბევრ ბიბლიოთეკას აქვს თანდაყოლილი დაუცველობა XXE შეტევების მიმართ:


    libxml_disable_entity_loader(true);

    უბრალოდ დაიმახსოვრე TRUE დაბრუნება გარე რესურსების ჩატვირთვის ყოველი დროებითი ჩართვის შემდეგ. შეიძლება დაგჭირდეთ ის ისეთი უვნებელი რამისთვის, როგორიც არის Docbook XML HTML-ად გადაქცევა, სადაც XSL სტილის გამოყენება დამოკიდებულია გარე ერთეულებზე.


    თუმცა, libxml2 გამორთვის ფუნქცია არ არის პანაცეა. გაანალიზეთ სხვა გაფართოებები და PHP ბიბლიოთეკები, რომლებიც აანალიზებენ ან სხვაგვარად ამუშავებენ XML-ს, რათა იპოვოთ მათი „გამრთველები“ ​​გარე ერთეულების გამოსაყენებლად.


    თუ ეს შეუძლებელია, მაშინ დამატებით შეამოწმეთ არის თუ არა XML დოკუმენტი აცხადებს DOCTYPE. თუ ასეა, და თუ გარე ერთეულები გამორთულია, მაშინ უბრალოდ გადაყარეთ XML დოკუმენტი, უარი თქვით არასანდო XML წვდომაზე პოტენციურად დაუცველ პარსერზე და ჩაწერეთ იგი, როგორც სავარაუდო თავდასხმა. ეს აუცილებელი ნაბიჯია, რადგან სხვა ნიშნები არ იქნება - არანაირი შეცდომა, გამონაკლისი. შეიტანეთ ეს შემოწმება თქვენს რეგულარულ შეყვანის ვალიდაციაში. მაგრამ ეს მეთოდი შორს არის იდეალურისგან, ამიტომ რეკომენდებულია გარე პირების პრობლემის ფუნდამენტურად გადაჭრა.


    /** * სწრაფი გამოვლენის მცდელობა */ $collapsedXML = preg_replace("/[:space:]/", "", $xml); if(preg_match("/