SPIS TREŚCI

• iOS 15

• Co każdy Programista wiedzieć powinien




Android Studio


• Wprowadzenie do Android Studio

• Pierwsze kroki z Android Studio

• Podstawy Android Studio

• Narzędzia Android Studio

• Debuggowanie




Abecadło Shellcodera



• Zanim zaczniesz …

• Stack Overflows

• Kod Powłoki

• Wprowadzenie do błędów w ciągach formatujących

• Wprowadzenie do przepełnień sterty

• Inne platformy - Windows, Solaris, OS/X i Cisco

• Kod powłoki systemu Windows

• Przepełnienie Windows

• Pokonywanie filtrów

• Wprowadzenie do Solaris Exploitation

• Zaawansowana eksploatacja Solaris

• Kod powłoki systemu OS X

• Wykorzystanie Cisco IOS

• Mechanizmy ochronne

• Tworzenie środowiska pracy

• Wstrzykiwanie błędów

• Sztuka Fuzzingu

• Audyt kodu źródłowego

• Instrumentalne dochodzenie: podejście ręczne

• Śledzenie pod kątem luk

• Audyt binarny

• Alternatywne strategie ładowności

• Pisanie exploitów, które działają na wolności

• Atakowanie oprogramowania bazodanowegoo

• Przepełnienia jądra Unix

• Wykorzystywanie luk w jądrze systemu Unix

• Hakowanie jądra systemu Windows



Programowanie iOS 15

Część 1, Zapoznanie się z Xcode [KOD], zawiera prezentację Xcode i omawia wszystkie różne panele, których będziesz używać.

Część 2, Proste wartości i typy [KOD], dotyczy sposobu implementacji wartości i typów w języku Swift.

Część 3, Warunki i opcje [KOD] pokazuje, w jaki sposób implementowane są instrukcje if i switch oraz jak implementować zmienne, które mogą, ale nie muszą mieć wartości.

Część 4, Operatory i pętle zakresów, [KOD] pokazuje, jak pracować z zakresami i różne sposoby implementacji pętli w Swift.

Część 5, Typy kolekcji  [KOD], omawia popularne typy kolekcji, którymi są tablice, słowniki i zestawy.

Część 6, Funkcje i domknięcia  [KOD], opisuje, w jaki sposób można grupować instrukcje za pomocą funkcji i zamknięć.

Część 7, Klasy, struktury i wyliczenia,  [KOD] , mówi o tym, jak złożone obiekty zawierające stan i zachowanie są reprezentowane w Swift.

Część 8, Protokoły, rozszerzenia i obsługa błędów,  [KOD] mówi o tworzeniu protokołów, które mogą przyjąć złożone typy danych, rozszerzaniu możliwości istniejących typów oraz o tym, jak radzić sobie z błędami w kodzie.

Część 9, Konfiguracja interfejsu użytkownika, [KOD] dotyczy tworzenia aplikacji Let′s Eat, dodawania zasobów graficznych i konfigurowania początkowego ekranu, który będą widzieć użytkownicy.

Część 10, Budowanie interfejsu użytkownika, [KOD] obejmuje konfigurację głównego ekranu aplikacji Let&prie;s Eat.

Część 11, Wykańczanie interfejsu użytkownika, [KOD] obejmuje konfigurację pozostałych ekranów aplikacji Let′s Eat.

Część 12, Modyfikowanie i konfigurowanie komórek, [KOD] dotyczy dostosowywania komórek widoku tabeli i kolekcji w scenorysie.

Część 13, Pierwsze kroki z widokami MVC i kolekcji, [KOD] dotyczy pracy z widokami kolekcji i tego, jak można ich używać do wyświetlania siatki elementów.

Część 14, Wprowadzanie danych do widoków kolekcji, [KOD] dotyczy włączania danych do widoków kolekcji.

Część 15, Pierwsze kroki z widokami tabel, [KOD] nauczy Cię, jak pracować z widokami tabel i szczegółowo przyjrzy się dynamicznym widokom tabel.

Część 16, Pierwsze kroki z MapKit, [KOD] dotyczy pracy z MapKit i dodawania adnotacji do mapy. Utworzysz także niestandardowe adnotacje do swojej mapy.

Część 17, Pierwsze kroki z plikami JSON, [KOD] obejmuje naukę korzystania z menedżera danych do odczytywania pliku JSON i korzystania z danych w aplikacji.

Część 18, Wyświetlanie danych w statycznym widoku tabeli, [KOD] uczy, jak wypełnić statyczny widok tabeli danymi przekazywanymi z jednego kontrolera widoku do drugiego za pomocą przejść.

Część 19, Pierwsze kroki z niestandardowymi elementami sterującymi  [KOD], pokazuje, jak tworzyć własne widoki niestandardowe.

Część 20, Pierwsze kroki z aparatami i bibliotekami zdjęć, [KOD] omawia pracę z aparatem i biblioteką zdjęć urządzenia.

Część 21, Zrozumienie danych podstawowych, [KOD] obejmuje podstawy korzystania z danych podstawowych oraz sposób zapisywania recenzji i zdjęć restauracji.

Część 22, Pierwsze kroki z Mac Catalyst, [KOD] dotyczy modyfikowania aplikacji, aby działała dobrze na większym ekranie iPada i aby działała na Macu.

Część 23, Pierwsze kroki z SwiftUI, [KOD] dotyczy tworzenia aplikacji przy użyciu nowej technologii SwiftUI firmy Apple.

Część 24, Pierwsze kroki z Swift Concurrency,  [KOD] przedstawia koncepcje programowania równoległego i asynchronicznego oraz pokazuje, jak można je zaimplementować w swojej aplikacji.

Część 25, Pierwsze kroki z SharePlay,  [KOD] pokazuje, jak możesz zaimplementować wspólne doświadczenia dla użytkowników przy użyciu SharePlay i struktury działań grupowych.

Część 26, Testowanie i przesyłanie aplikacji do App Store, dotyczy testowania i przesyłania aplikacji do App Store.




Podręcznik hakera aplikacji internetowych

Część 1  "(nie)zabezpieczenie aplikacji internetowych" : opisuje obecny stan zabezpieczeń aplikacji internetowych w Internecie. Pomimo powszechnych zapewnień, większość aplikacji jest niepewna i może zostać w jakiś sposób skompromitowana przy skromnym poziomie umiejętności. Luki w aplikacjach internetowych wynikają z jednego podstawowego problemu: użytkownicy mogą wprowadzać dowolne dane wejściowe. Omówimy kluczowe czynniki, które przyczyniają się do słabego stanu bezpieczeństwa współczesnych aplikacji. Opisuje również, w jaki sposób defekty w aplikacjach internetowych mogą narazić szerszą infrastrukturę techniczną organizacji na bardzo podatną na ataki.

Część 2 , "Podstawowe mechanizmy obronne" : opisuje kluczowe mechanizmy bezpieczeństwa stosowane przez aplkacje internetowe w celu rozwiązania podstawowego problemu, jakim jest niezaufanie wszystkich danych wprowadzanych przez użytkownika. Te mechanizmy są środkiem, za pomocą którego aplikacja zarządza dostępem użytkownika, obsługuje dane wejściowe użytkownika i reaguje na atakujących. Mechanizmy te obejmują również funkcje udostępniane administratorom do zarządzania i monitorowania samej aplikacji. Podstawowe mechanizmy bezpieczeństwa aplikacji reprezentują również jej główną powierzchnię ataku, więc musisz zrozumieć, jak te mechanizmy mają działać, zanim będziesz mógł je skutecznie zaatakować.

Część 3  "Technologie aplikacji internetowych" : jest krótkim wprowadzeniem do kluczowych technologii, z którymi możesz się spotkać podczas atakowania aplikacji internetowych. Obejmuje wszystkie istotne aspekty protokołu HTTP, technologie powszechnie używane po stronie klienta i serwera oraz różne schematy używane do kodowania danych. Jeśli znasz już główne technologie sieciowe, możesz przejrzeć tą część.

Część 4  "Mapowanie aplikacji" : opisuje pierwsze ćwiczenie, które należy wykonać, gdy atakujesz nową aplikację - zebranie jak największej ilości informacji w celu zmapowania powierzchni ataku i sformułowania planu ataku. Proces ten obejmuje eksplorację i sondowanie aplikacji w celu skatalogowania całej jej zawartości i funkcjonalności, identyfikację wszystkich punktów wejścia dla danych wejściowych użytkownika oraz wykrywanie używanych technologii.

Część 5  "Omijanie kontroli po stronie klienta" : obejmuje pierwszy obszar rzeczywistej luki w zabezpieczeniach, która pojawia się, gdy aplikacja polega na mechanizmach kontroli zaimplementowanych po stronie klienta w celu zapewnienia bezpieczeństwa. Takie podejście zwykle jest wadliwe, ponieważ można oczywiście obejść wszelkie kontrole po stronie klienta. Dwa główne sposoby, w jakie aplikacje stają się podatne na ataki, to przesyłanie danych przez klienta przy założeniu, że nie zostaną one zmodyfikowane, oraz poleganie na sprawdzaniu danych wejściowych użytkownika po stronie klienta. W tym rozdziale opisano szereg interesujących technologii, w tym lekkie kontrolki zaimplementowane w HTML, HTTP i JavaScript oraz bardziej zaawansowane kontrolki wykorzystujące aplety Java, kontrolki ActiveX, obiekty Silverlight i Flash.

Część 6  "Atak na uwierzytelnianie" : analizuje różne funkcje, dzięki którym aplikacje uzyskują pewność tożsamości swoich użytkowników. Obejmuje to główną funkcję logowania, a także funkcje związane z uwierzytelnianiem urządzeń peryferyjnych, takie jak rejestracja użytkownika, zmiana hasła i odzyskiwanie konta. Mechanizmy uwierzytelniania zawierają wiele różnych luk, zarówno w projekcie, jak i implementacji, które atakujący może wykorzystać w celu uzyskania nieautoryzowanego dostępu. Obejmują one od oczywistych wad, takich jak złe hasła i podatność na ataki typu brute-force, po bardziej niejasne problemy w logice uwierzytelniania. Badamy również szczegółowo typy wieloetapowych mechanizmów logowania używanych w wielu aplikacjach o krytycznym znaczeniu dla bezpieczeństwa i opisujemy nowe rodzaje luk w zabezpieczeniach, które często zawierają.

Część 7  "Zarządzanie sesją atakowania" : analizuje mechanizm, za pomocą którego większość aplikacji uzupełnia bezstanowy protokół HTTP o koncepcję sesji stanowej, umożliwiając im jednoznaczną identyfikację każdego użytkownika w kilku różnych żądaniach. Mechanizm ten jest kluczowym celem, gdy atakujesz aplikację internetową, ponieważ jeśli uda ci się ją złamać, możesz skutecznie ominąć logowanie i podszywać się pod innych użytkowników bez znajomości ich danych uwierzytelniających. Przyglądamy się różnym typowym defektom w generowaniu i przesyłaniu tokenów sesji i opisujemy kroki, które można podjąć, aby je wykryć i wykorzystać.

Część 8  "Atakowanie kontroli dostępu" : przedstawia sposoby, w jakie aplikacje faktycznie wymuszają kontrolę dostępu, opierając się w tym celu na mechanizmach uwierzytelniania i zarządzania sesjami. Opisujemy różne sposoby łamania kontroli dostępu oraz sposoby wykrywania i wykorzystywania tych słabości.

Część 9  "Atakowanie magazynów danych" : rozpoczyna się od szczegółowego zbadania podatności na wstrzykiwanie SQL. Obejmuje pełen zakres ataków, od najbardziej oczywistych i trywialnych po zaawansowane techniki eksploatacji obejmujące kanały pozapasmowe, wnioskowanie i opóźnienia czasowe. Dla każdego rodzaju luki i techniki ataku opisujemy istotne różnice między trzema popularnymi typami baz danych: MS-SQL, Oracle i MySQL. Następnie przyjrzymy się szeregowi podobnych ataków na inne magazyny danych, w tym NoSQL, XPath i LDAP.

Część 10  "Atak na komponenty zaplecza" : opisuje kilka innych kategorii luk w zabezpieczeniach, w tym wstrzykiwanie poleceń systemu operacyjnego, wstrzykiwanie do języków skryptów internetowych, ataki z przechodzeniem ścieżek plików, luki w zabezpieczeniach dołączania plików, wstrzykiwanie do XML, SOAP, zakończenie żądań HTTP i usługi poczty e-mail.

Część 11  "Atak na logikę aplikacji" : analizuje istotny i często pomijany obszar powierzchni ataku każdej aplikacji: wewnętrzną logikę, która jest wykorzystywana do implementacji jej funkcjonalności. Defekty w logice aplikacji są niezwykle zróżnicowane i trudniej je scharakteryzować niż typowe luki, takie jak wstrzyknięcie SQL i skrypty między witrynami. Z tego powodu przedstawiamy serię rzeczywistych przykładów, w których wadliwa logika naraziła aplikację na niebezpieczeństwo. Ilustrują one różnorodność błędnych założeń, które przyjmują projektanci i programiści aplikacji. Z tych różnych indywidualnych wad wyprowadzamy serię konkretnych testów, które można przeprowadzić w celu zlokalizowania wielu rodzajów błędów logicznych, które często pozostają niewykryte.

Część 12  "Atakowanie użytkowników : Cross-Site Scripting" : analizuje najbardziej widoczną lukę tego rodzaju - ogromnie powszechną lukę, która ma wpływ na ogromną większość aplikacji internetowych w Internecie. Szczegółowo badamy różne rodzaje luk XSS i opisujemy skuteczną metodologię wykrywania i wykorzystywania nawet najbardziej niejasnych ich przejawów.

Część 13  "Atakowanie użytkowników: inne techniki" : omawia kilka innych rodzajów ataków na innych użytkowników, w tym wywoływanie działań użytkownika poprzez fałszowanie żądań i odzyskiwanie interfejsu użytkownika, przechwytywanie danych między domenami przy użyciu różnych technologii po stronie klienta, różne ataki na te same zasady pochodzenia, wstrzykiwanie nagłówka HTTP, wstrzykiwanie plików cookie i utrwalanie sesji, otwarte przekierowanie, wstrzykiwanie SQL po stronie klienta, lokalne ataki na prywatność i wykorzystywanie błędów w formantach ActiveX. Rozdział kończy się omówieniem szeregu ataków na użytkowników, które nie są zależne od luk w żadnej konkretnej aplikacji internetowej, ale mogą zostać przeprowadzone za pośrednictwem dowolnej złośliwej witryny internetowej lub odpowiednio ustawionego atakującego.

Część 14  "Automatyzacja ataków dostosowanych" : nie wprowadza żadnych nowych kategorii luk w zabezpieczeniach. Zamiast tego opisuje kluczową technikę, którą musisz opanować, aby skutecznie atakować aplikacje internetowe. Ponieważ każda aplikacja internetowa jest inna, większość ataków jest w jakiś sposób dostosowywana, dostosowana do konkretnego zachowania aplikacji i odkrytych sposobów manipulowania nią na swoją korzyść. Często wymagają też wysłania dużej liczby podobnych żądań i monitorowania odpowiedzi aplikacji. Ręczne wykonywanie tych żądań jest niezwykle pracochłonne i podatne na błędy. Aby stać się naprawdę doświadczonym hakerem aplikacji internetowych, musisz zautomatyzować jak najwięcej tej pracy, aby niestandardowe ataki były łatwiejsze, szybsze i skuteczniejsze. Tu szczegółowo opisano sprawdzoną metodologię osiągnięcia tego celu. Badamy również różne typowe bariery w korzystaniu z automatyzacji, w tym obronne mechanizmy obsługi sesji i kontrole CAPTCHA. Ponadto opisujemy narzędzia i techniki, których możesz użyć do pokonania tych barier.

Część 15  "Wykorzystywanie ujawniania informacji" : omawia różne sposoby, w jakie aplikacje ujawniają informacje podczas aktywnego ataku. Kiedy przeprowadzasz wszystkie inne rodzaje ataków opisane tu, powinieneś zawsze monitorować aplikację, aby zidentyfikować dalsze źródła ujawnienia informacji, które możesz wykorzystać. Opisujemy, w jaki sposób można zbadać nietypowe zachowanie i komunikaty o błędach, aby lepiej zrozumieć wewnętrzne działanie aplikacji i dostroić atak. Omówimy również sposoby manipulowania wadliwą obsługą błędów w celu systematycznego pobierania poufnych informacji z aplikacji.

Część 16,  "Atakowanie aplikacji skompilowanych natywnie" : omawia zestaw ważnych luk w zabezpieczeniach, które pojawiają się w aplikacjach napisanych w natywnych językach kodu, takich jak C i C++. Te luki obejmują przepełnienia bufora, luki związane z liczbami całkowitymi oraz wady ciągu formatującego. Ponieważ jest to potencjalnie obszerny temat, skupiamy się na sposobach wykrywania tych luk w aplikacjach internetowych i przyglądamy się kilku rzeczywistym przykładom ich powstawania i wykorzystywania.

Część 17  "Atak na architekturę aplikacji" : omawia ważny, często pomijany obszar bezpieczeństwa aplikacji internetowych. Wiele aplikacji wykorzystuje architekturę warstwową. Niepowodzenie w prawidłowym oddzieleniu różnych warstw często powoduje, że aplikacja jest podatna na ataki, co umożliwia osobie atakującej, która znalazła defekt w jednym komponencie, szybkie złamanie zabezpieczeń całej aplikacji. W środowiskach współdzielonych hostingu pojawia się inny zakres zagrożeń, w których defekty lub złośliwy kod w jednej aplikacji mogą czasami zostać wykorzystane do naruszenia samego środowiska i innych działających w nim aplikacji. Przyjrzymy się również szeregowi zagrożeń, które pojawiają się w rodzajach współdzielonych środowisk hostingowych, które stały się znane jako "przetwarzanie w chmurze".

Część 18  "Atakowanie serwera aplikacji" : opisuje różne sposoby, w jakie można zaatakować aplikację sieciową, atakując serwer sieciowy, na którym jest uruchomiona. Luki w serwerach sieci Web składają się w dużej mierze z wad w ich konfiguracji i luk w zabezpieczeniach oprogramowania serwera sieci Web. Ten temat znajduje się na granicy tematów poruszanych w tej książce, ponieważ serwer WWW jest zupełnie innym elementem stosu technologicznego. Jednak większość aplikacji internetowych jest ściśle powiązana z serwerem sieciowym, na którym działają. Dlatego też w książce uwzględniono ataki na serwer sieciowy, ponieważ często można ich użyć do bezpośredniego złamania zabezpieczeń aplikacji, a nie pośredniego, polegającego na pierwszym złamaniu podstawowego hosta.

Część 19  "Znajdowanie luk w kodzie źródłowym" : opisuje zupełnie inne podejście do znajdowania luk w zabezpieczeniach niż te opisane w innych miejscach. W wielu sytuacjach możliwe jest przejrzenie kodu źródłowego aplikacji, z których nie wszystkie wymagają współpracy ze strony właściciela aplikacji. Przeglądanie kodu źródłowego aplikacji często może być bardzo skuteczne w wykrywaniu luk w zabezpieczeniach, których wykrycie przez badanie działającej aplikacji byłoby trudne lub czasochłonne. Opisujemy metodologię i udostępniamy ściągawkę język po języku, aby umożliwić Ci przeprowadzenie efektywnego przeglądu kodu, nawet jeśli masz ograniczone doświadczenie w programowaniu.

Część 20  "Zestaw narzędzi dla hakerów aplikacji internetowych" : zestawia różne. Są to te same narzędzia, których używa się do atakowania aplikacji internetowych w świecie rzeczywistym. Badamy kluczowe cechy tych narzędzi i szczegółowo opisujemy rodzaj przepływu pracy, który zazwyczaj trzeba zastosować, aby uzyskać z nich jak najwięcej korzyści. Badamy również, w jakim stopniu każde w pełni zautomatyzowane narzędzie może skutecznie wykrywać luki w aplikacjach internetowych. Na koniec przedstawiamy kilka wskazówek i porad, jak najlepiej wykorzystać swój zestaw narzędzi.

Część 21  "Metodologia hakera aplikacji internetowych" : to obszerne i uporządkowane zestawienie wszystkich procedur i technik opisanych w tym tekście. Są one zorganizowane i uporządkowane zgodnie z logicznymi zależnościami między zadaniami, gdy przeprowadzasz rzeczywisty atak. Jeśli przeczytałeś i zrozumiałeś wszystkie luki w zabezpieczeniach i techniki opisane w tej książce, możesz wykorzystać tę metodologię jako kompletną listę kontrolną i plan pracy podczas przeprowadzania ataku na aplikację internetową.




Sieci neuronowe w C++

Część 1 zawiera przegląd terminologii i nazewnictwa sieci neuronowych. Odkrywasz, że sieci neuronowe są w stanie rozwiązywać złożone problemy za pomocą równoległych architektur obliczeniowych. W tym rozdziale przedstawiono sieć Hopfield i sieć feedforward.

Część 2 wprowadza C++ i orientację obiektową. Poznajesz zalety programowania obiektowego i jego podstawowe koncepcje.

Część 3 przedstawia logikę rozmytą, technologię, która jest dość synergiczna z rozwiązywaniem problemów z sieciami neuronowymi. Dowiesz się o matematyce z zestawami rozmytymi, a także o tym, jak zbudować prosty fuzzifier w C++.

Część 4 przedstawia dwa najprostsze, ale bardzo reprezentatywne modele: sieci Hopfield, sieci Perceptron i ich implementacji w C++.

Część 5 to przegląd modeli sieci neuronowych. Opisuje cechy kilku modeli, opisuje funkcje progowe i rozwija koncepcje w sieciach neuronowych.

Część 6 koncentruje się na paradygmatach uczenia się i szkolenia. Wprowadza pojęcia nadzorowanego i nienadzorowanego uczenia się, samoorganizacji oraz zagadnienia obejmujące wsteczną propagację błędów, sieci radialnych funkcji bazowych i metody gradientów sprzężonych.

W Części 7 omówiono budowę symulatora wstecznej propagacji błędów. Ten symulator przyda się również w dalszych częściach. Klasy i funkcje C++ są szczegółowo opisane tu.

Część 8 dotyczy pamięci dwukierunkowych asocjacyjnych do kojarzenia par wzorców.

Część 9 wprowadza pamięci skojarzeniowe rozmyte do kojarzenia par zbiorów rozmytych.

Część 10 obejmuje adaptacyjną teorię rezonansu Grossberga. Będziesz miał okazję poeksperymentować z programem ilustrującym działanie tej teorii.

Części 11 i 12 omawiają samoorganizującą się mapę Teuvo Kohonena i jej zastosowanie do rozpoznawania wzorców.

Część 13 kontynuuje dyskusję na temat symulatora propagacji wstecznej, z ulepszeniami wprowadzonymi do symulatora, aby uwzględnić pęd i hałas podczas treningu.

Część 14 stosuje propagację wsteczną do problemu prognozowania finansowego, omawia tworzenie sieci propagacji wstecznej z 15 zmiennymi wejściowymi i 200 przypadkami testowymi do przeprowadzenia symulacji. Do problemu podchodzi się za pomocą systematycznego 12-etapowego podejścia do wstępnego przetwarzania danych i konfigurowania problemu. W literaturze można znaleźć szereg przykładów prognozowania finansowego. Dołączono przewodnik po sieciach neuronowych w finansach dla osób, które chciałyby uzyskać więcej informacji na ten temat.

Część 15 zajmuje się optymalizacją nieliniową z dokładnym omówieniem problemu Travelling Salesperson. Poznasz sformułowanie Hopfielda i podejście Kohonena.

Część 16 omawia dwa obszary zastosowań logiki rozmytej: rozmyte systemy sterowania i rozmyte bazy danych. W tym rozdziale omówiono również kilka przykładów relacji rozmytych i teorii zbiorów rozmytych.




Hackowanie Przeglądarki

Część 1: Bezpieczeństwo przeglądarki internetowej : Ta Część rozpoczyna Twoją przygodę z hakowaniem przeglądarki. Pierwszym krokiem jest poznanie ważnych koncepcji przeglądarki i niektórych podstawowych problemów związanych z bezpieczeństwem przeglądarki. Badasz paradygmat mikroobwodów potrzebny do obrony dzisiejszych organizacji i zastanawiasz się nad pewnymi błędami, które nadal propagują niebezpieczne praktyki. W tym rozdziale omówiono również metodologię określającą, w jaki sposób można przeprowadzać ataki z wykorzystaniem przeglądarki. Obejmuje obszar ataku prezentowany przez przeglądarkę oraz sposób, w jaki zwiększa ekspozycję zasobów wcześniej uznanych za chronione.

Część 2: Inicjowanie kontroli : Za każdym razem, gdy przeglądarka internetowa łączy się z siecią, prosi o instrukcje. Przeglądarka następnie sumiennie realizuje polecenia, które zostały jej przekazane przez serwer sieciowy. Nie trzeba dodawać, że granice istnieją, ale przeglądarka zapewnia potężne środowisko do wykorzystania przez atakujących. Ta Część przeprowadzi Cię przez pierwszą fazę ataków na przeglądarkę, badając, jak wykonać kod w docelowej przeglądarce. Poznajesz zalety luk w zabezpieczeniach Cross-Site Scripting, ataków Man-in-the-Middle, socjotechniki i nie tylko.

Część 3: Zachowanie kontroli : Techniki inicjacji omówione do tej pory pozwalają na wykonanie instrukcji tylko raz. Tu przedstawiono sposób utrzymywania komunikacji i trwałości, dając interaktywną kontrolę z możliwością wykonywania wielu rund poleceń. Podczas typowej sesji hakerskiej będziesz chciał zachować kanał komunikacji z przeglądarką i, tam gdzie to możliwe, zachować kontrolę podczas ponownego uruchamiania. Bez tego szybko znajdziesz się z powrotem w punkcie wyjścia, próbując zachęcić cel do ciągłego łączenia się. Dowiesz się, jak używać ładunku do utrzymywania komunikacji z przeglądarką, umożliwiając wysyłanie wielu iteracji instrukcji. Zapewni to, że nie zmarnujesz żadnych okazji po otrzymaniu tego najważniejszego początkowego połączenia. Uzbrojony w tę wiedzę, jesteś teraz gotowy do przeprowadzenia różnych ataków przedstawionych w kolejnych Częściach.

Część 4: Obchodzenie zasad tego samego pochodzenia : W bardzo podstawowych terminach, polityka tego samego pochodzenia (SOP) ogranicza interakcję jednej witryny z inną. Jest to prawdopodobnie najbardziej podstawowa koncepcja bezpieczeństwa przeglądarki internetowej. W związku z tym można by oczekiwać, że przewidywanie skutków wspólnych działań będzie spójne we wszystkich komponentach przeglądarki i trywialne. Ta Część pokazuje, że tak nie jest. Twórcy stron internetowych niemal na każdym kroku są nękani kijem SOP; istnieje różnica między sposobem zastosowania SOP do samej przeglądarki, rozszerzeń, a nawet wtyczek. Ten brak spójności i zrozumienia zapewnia atakującym możliwości wykorzystania skrajnych przypadków. Omówiono omijanie różnych elementów sterujących SOP w przeglądarce. Odkrywasz nawet problemy z przeciąganiem i upuszczaniem oraz różnymi atakami naprawiającymi interfejs użytkownika i synchronizacją. Jedną z bardziej zaskakujących rzeczy, których dowiesz się w tym rozdziale, jest to, że przy odpowiednim kodowaniu obejścia SOP mogą przekształcić przeglądarkę w proxy HTTP.

Część 5: Atakowanie użytkowników : Ludzie są często określani jako najsłabsze ogniwo bezpieczeństwa. Ten Część koncentruje się na atakach wymierzonych w oprogramowanie typu wetware niczego niepodejrzewającego użytkownika. Niektóre ataki dodatkowo wykorzystują taktyki socjotechniki omówione w Części 2. Inne ataki wykorzystują cechy przeglądarek i ich zaufanie do otrzymanego kodu. W tym rozdziale zapoznasz się z deanonimizacją i ukrytym włączaniem kamery internetowej, a także uruchamianiem złośliwych plików wykonywalnych z lub bez żadnej jawnej interwencjai użytkownika.

Część 6: Atakowanie przeglądarek : Podczas gdy cały tekst dotyczy atakowania przeglądarki i obchodzenia jej kontroli bezpieczeństwa, ta Część koncentruje się na czymś, co można nazwać przeglądarką typu barebone. Czyli przeglądarka bez rozszerzeń i wtyczek . Poznasz proces bezpośredniego atakowania przeglądarki. Zagłębiasz się w odciski palców przeglądarki, aby odróżnić dostawców i wersje. Dowiesz się również, jak przeprowadzać ataki i włamywać się do komputera, na którym działa przeglądarka.

Część 7: Atakowanie rozszerzeń : Ta Część koncentruje się na wykorzystywaniu luk w rozszerzeniach przeglądarki. Rozszerzenie to oprogramowanie, które dodaje (lub usuwa) funkcje do (lub z) przeglądarki internetowej. Rozszerzenie nie jest samodzielnym programem w przeciwieństwie do ich drugich kuzynów, wtyczek. Być może znasz rozszerzenia takie jak LastPass, Firebug, AdBlock i NoScript. Rozszerzenia wykonują kod w zaufanych strefach ze zwiększonymi uprawnieniami i pobierają dane z mniej zaufanych stref, takich jak Internet. Włączy się alarm dla doświadczonych specjalistów od bezpieczeństwa. Istnieje realne ryzyko ataków wstrzykiwania, a w praktyce niektóre z tych ataków prowadzą do zdalnego wykonania kodu. Poznasz anatomię ataków rozciągających. Zagłębiasz się w exploity eskalacji uprawnień, które dają dostęp do uprzywilejowanej strefy przeglądarki (lub chrome://) i powodują wykonanie polecenia.

Część 8: Atakowanie wtyczek : Ta Część koncentruje się na atakowaniu wtyczek do przeglądarek internetowych, które są częściami oprogramowania, które dodają określone funkcje do przeglądarek internetowych. W większości przypadków oprogramowanie wtyczki może działać niezależnie bez przeglądarki internetowej. Popularne wtyczki to Acrobat Reader, Flash Player, Java, QuickTime, RealPlayer, Shockwave i Windows Media Player. Niektóre z nich są niezbędne do przeglądania, a niektóre do funkcji biznesowych. Flash jest potrzebny w przypadku witryn takich jak YouTube (który potencjalnie przechodzi na HTML5) i Java jest wymagana dla funkcji biznesowych, takich jak WebEx. Wtyczki są nękane lukami w zabezpieczeniach i nadal stanowią bogate źródło exploitów. Jak się przekonasz, luki w zabezpieczeniach wtyczek pozostają jednym z najbardziej niezawodnych sposobów przejęcia kontroli nad przeglądarką. Poznasz analizowanie i wykorzystywanie wtyczek przeglądarki za pomocą popularnych, ogólnodostępnych narzędzi. Dowiesz się o omijaniu mechanizmów ochronnych, takich jak Click to Play i przejmowaniu kontroli nad celem poprzez luki w wtyczkach.

Część 9: Atakowanie aplikacji internetowych : Twoja codzienna przeglądarka internetowa może przeprowadzać potężne ataki internetowe, nadal przestrzegając przyjętych kontroli bezpieczeństwa. Przeglądarki internetowe są zaprojektowane do komunikowania się z serwerami internetowymi za pomocą protokołu HTTP. Te funkcje HTTP można obrócić przeciwko sobie, aby osiągnąć kompromis w celu, który nie znajduje się nawet w bieżącym źródle. Ta Część koncentruje się na atakach, które można uruchomić z przeglądarki bez naruszania SOP. Nauczysz się różnych sztuczek, które pozwalają na odciski palców zasobów między źródłami, a nawet identyfikację wspólnych luk w aplikacjach internetowych. Możesz być zaskoczony, gdy dowiesz się, że podczas korzystania z przeglądarki można wykryć i wykorzystać cross-origin Cross-site Scripting i SQL również luki w zabezpieczeniach wtrysku. Pod koniec Części zrozumiesz, jak osiągnąć zdalne wykonanie kodu cross-origin. Odkryjesz również ataki Cross-Site Request Forgery, wyliczanie opóźnień na podstawie czasu, uwierzytelnianie ataków i ataki typu "odmowa usługi".

Część 10: Atakowanie sieci : Ta ostatnia Część dotyczący ataków obejmuje identyfikowanie powierzchni ataku intranetu poprzez skanowanie portów w celu wykrycia nieznanych wcześniej hostów. Eksploracja jest kontynuowana poprzez prezentację technik, takich jak przypinanie NAT. Odkryjesz również ataki wykorzystujące przeglądarkę internetową do bezpośredniego komunikowania się z usługami innymi niż internetowe. Dowiesz się, jak wykorzystać moc techniki Interprotocol Exploitation, aby złamać cele w intranecie przeglądarki.




XV Podstawowych Skrótów w Windows 10

1. Ctrl + A: Ctrl + A, podświetla lub zaznacza wszystko, co masz w środowisku, w którym pracujesz. Jeśli myślisz sobie: "Wow, zawartość tego dokumentu jest obszerna i nie ma czasu, aby ją wybrać, a poza tym wywrze presję na moim komputerze?" Używanie myszy do tego jest przestarzałą metodą obsługi zadania, takiego jak wybieranie wszystkich, Ctrl + A zajmie się tym w zaledwie kilka sekund.

2. Ctrl + C: Ctrl + C kopiuje dowolny podświetlony lub wybrany element w środowisku pracy. Oszczędza czas i stres, który zostałby użyty do kliknięcia prawym przyciskiem myszy i ponownego kliknięcia tylko w celu skopiowania. Użyj Ctrl + C.

3. Ctrl + N: Ctrl + N otwiera nowe okno lub plik. Zamiast klikać Plik, Nowy, pusty / szablon i kolejne kliknięcie, po prostu naciśnij Ctrl + N, a nowe okno lub plik pojawi się natychmiast.

4. Ctrl + O: Ctrl + O otwiera istniejący plik. Użyj Ctrl + O, gdy chcesz zlokalizować / otworzyć plik lub program.

5. Ctrl + P: Ctrl + P drukuje aktywny dokument. Zawsze używaj tego do zlokalizowania okna dialogowego drukarki i drukowania.

6. Ctrl + S: Ctrl + S zapisuje nowy dokument lub plik i zmiany wykonane przez użytkownika. Dotykasz teraz myszy? Proszę przestań! Nie używaj myszy. Po prostu naciśnij Ctrl + S, a wszystko zostanie zapisane.

7. Ctrl + V: Ctrl + V wkleja skopiowane elementy do aktywnego obszaru używanego programu. Użycie ctrl + V w takim przypadku Oszczędza czas i stres związany z kliknięciem prawym przyciskiem myszy i ponownym kliknięciem tylko po to, aby wkleić.

8. Ctrl + W: Ctrl + W służy do zamykania strony, na której pracujesz, gdy chcesz opuścić środowisko pracy. "Jest sposób, w jaki Peace robi to bez użycia myszy. O mój Boże, dlaczego się tego nie nauczyłem? " Nie martw się, mam odpowiedź: Peace naciska Ctrl + W, aby zamknąć aktywne okna.

9. Ctrl + X: Ctrl + X tnie elementy (sprawiając, że elementy znikają z ich pierwotnego miejsca). Różnica między wycinaniem a usuwaniem elementów polega na tym, że w wycinaniu wycinane elementy nie giną na stałe, ale przygotowuje się do wklejenia w innym miejscu wybranym przez użytkownika. Użyj Ctrl + X, gdy myślisz "To nie powinno być tutaj i nie mogę znieść stresu związanego z przepisywaniem lub przeprojektowywaniem tego we właściwym miejscu".

10. Ctrl + Y: Ctrl + Y ponawia cofniętą czynność. Ctrl + Z przywróciło to, czego nie potrzebujesz? Naciśnij Ctrl + Y, aby ponownie go usunąć.

11. Ctrl + Z: Ctrl + Z cofa akcje. Nie możesz znaleźć tego, co wpisałeś teraz lub wstawionego obrazu, nagle zniknął lub omyłkowo go usunąłeś? Naciśnij Ctrl + Z, aby go przywrócić.

12. Alt + F4: Alt + F4 zamyka aktywne okna lub elementy. Nie musisz poruszać myszą, aby zamknąć aktywne okno, po prostu naciśnij Alt + F4, jeśli skończysz lub nie chcesz, aby ktoś, kto przychodził, zobaczył, co robisz.

13. Ctrl + F6: Control plus F6 Nawigacja między otwartymi oknami, umożliwiając użytkownikowi zobaczenie, co dzieje się w aktywnych oknach. Pracujesz w programie Microsoft Word i chcesz się dowiedzieć, czy inne aktywne okno, w którym Twoja przeglądarka ładuje stronę, nadal się rozwija? Użyj Ctrl + F6.

14. F1: Wyświetla okno pomocy. Czy Twój komputer działa nieprawidłowo? Użyj F1, aby znaleźć pomoc, gdy nie wiesz, co dalej zrobić.

15. F12: Umożliwia użytkownikowi wprowadzanie zmian w już zapisanym dokumencie. F12 to skrót do użycia, gdy chcesz zmienić format, w którym zapisałeś istniejący dokument, wpisać hasło, zmienić jego nazwę, zmienić lokalizację pliku lub miejsce docelowe lub wprowadzić inną zmianę












Numer 08 (68) / 2022

Odwiedzin: 51936
Dzisiaj: 8
On-line: 1
Strona istnieje: 2093 dni
Ładowanie: 0.075 sek


[ 6705 ]











Co każdy programista wiedzieć powinien



Działaj z rozwagą

Cokolwiek podejmiesz, działaj z rozwagą i rozważ konsekwencje.- Anonim

Bez względu na to, jak wygodny wygląda harmonogram na początku iteracji, nie możesz uniknąć presji przez pewien czas. Jeśli okaże się, że musisz wybierać między "zrobić to dobrze" a "zrobić to szybko", często atrakcyjne jest "zrób to szybko" ze zrozumieniem, że wrócisz i naprawisz to później. Kiedy składasz tę obietnicę sobie, swojemu zespołowi i klientowi, masz to na myśli. Ale zbyt często następna iteracja przynosi nowe problemy i skupiasz się na nich. Ten rodzaj odroczonej pracy jest znany jako dług techniczny i nie jest twoim przyjacielem. W szczególności Martin Fowler nazywa ten celowy dług techniczny w swojej taksonomii długu technicznego i nie należy go mylić z nieumyślnym długiem technicznym. Dług techniczny jest jak pożyczka: czerpiesz z niego korzyści w krótkim okresie, ale musisz płacić od niego odsetki, dopóki nie zostanie w pełni spłacony. Skróty w kodzie utrudniają dodawanie funkcji lub refaktoryzację kodu. Są pożywką dla wad i kruchych przypadków testowych. Im dłużej go zostawisz, tym gorzej. Zanim zajmiesz się oryginalną poprawką, może istnieć cały stos nie do końca właściwych wyborów projektowych nałożonych na oryginalny problem, co znacznie utrudnia refaktoryzację i poprawianie kodu. W rzeczywistości często tylko wtedy, gdy sprawy mają się tak źle, że musisz naprawić pierwotny problem, naprawdę wracasz, aby go naprawić. A do tego czasu często jest tak trudno naprawić, że naprawdę nie możesz sobie pozwolić na czas ani ryzyko. Bywają sytuacje, w których musisz zaciągnąć dług techniczny, aby dotrzymać terminu lub zaimplementować cienką część funkcji. Staraj się nie być w tej sytuacji, ale jeśli sytuacja absolutnie tego wymaga, śmiało. Ale (i to jest duże ale) musisz śledzić dług techniczny i szybko go spłacać, w przeciwnym razie sprawy szybko się pogorszą. Gdy tylko podejmiesz decyzję o kompromisie, napisz kartę zadań lub zarejestruj ją w swoim systemie śledzenia problemów, aby mieć pewność, że nie zostanie zapomniana. Jeśli zaplanujesz spłatę długu w kolejnej iteracji, koszt będzie minimalny. Pozostawienie niespłaconego długu spowoduje naliczanie odsetek, które należy śledzić, aby koszty były widoczne. Podkreśli to wpływ zadłużenia technicznego projektu na biznesową wartość i umożliwi odpowiednią priorytetyzację spłaty. Wybór sposobu obliczania i śledzenia zainteresowania będzie zależeć od konkretnego projektu, ale musisz go śledzić. Spłać jak najszybciej dług techniczny. Byłoby nieroztropnie postąpić inaczej.

Zastosuj zasady funkcjonalne

Programowanie funkcjonalne cieszy się ostatnio odnowionym zainteresowaniem społeczności programistów głównego nurtu. Częściowo jest to spowodowane tym, że pojawiające się właściwości paradygmatu funkcjonalnego są dobrze przygotowane do sprostania wyzwaniom związanym z przejściem w naszej branży w kierunku wielordzeniowości. Jednak, chociaż jest to z pewnością ważna aplikacja, nie jest to powód, dla którego ten artykuł upomina cię, abyś znał swoje programowanie funkcjonalne. Opanowanie paradygmatu programowania funkcyjnego może znacznie poprawić jakość kodu, który piszesz w innych kontekstach. Jeśli dogłębnie zrozumiesz i zastosujesz paradygmat funkcjonalny, Twoje projekty będą wykazywać znacznie wyższy stopień przejrzystości referencyjnej. Przejrzystość referencyjna jest bardzo pożądaną właściwością: oznacza, że funkcje konsekwentnie dają te same wyniki przy tych samych danych wejściowych, niezależnie od tego, gdzie i kiedy są wywoływane. Oznacza to, że ocena funkcji zależy mniej - najlepiej, wcale nie od skutków ubocznych stanu mutowalnego. Główną przyczyną błędów w kodzie imperatywnym są zmienne zmienne. Każdy, kto to czyta, zbada, dlaczego niektóre wartości nie są zgodne z oczekiwaniami w określonej sytuacji. Semantyka widoczności może pomóc złagodzić te podstępne defekty lub przynajmniej drastycznie zawęzić ich lokalizację, ale ich prawdziwym winowajcą może być w rzeczywistości opatrzność projektów wykorzystujących nadmierną zmienność. I z pewnością nie otrzymujemy w tym zakresie dużej pomocy od branży. Wprowadzenia do orientacji obiektowej milcząco promują takie projektowanie, ponieważ często pokazują przykłady złożone z grafów stosunkowo długowiecznych obiektów, które radośnie wywołują na sobie metody mutatorów, co może być niebezpieczne. Jednak dzięki wnikliwemu projektowi opartemu na testach, szczególnie gdy upewnisz się, że "naśladujesz role, a nie obiekty", niepotrzebną zmienność można zaprojektować. Wynik netto to projekt, który zazwyczaj ma lepszą alokację odpowiedzialności z liczniejszymi, mniejszymi funkcjami, które działają na argumentach przekazanych do nich, zamiast odwoływać się do zmiennych składowych. Będzie mniej defektów, a ponadto będą one często prostsze do debugowania, ponieważ łatwiej jest zlokalizować, gdzie w tych projektach wprowadzana jest nieuczciwa wartość, niż w inny sposób wywnioskować konkretny kontekst, który skutkuje błędnym przypisaniem. To przekłada się na znacznie wyższy stopień przejrzystości referencyjnej i na pewno nic nie wbije tych pomysłów tak głęboko w twoje kości, jak nauka funkcjonalnego języka programowania, w którym ten model obliczeń jest normą. Oczywiście takie podejście nie jest optymalne we wszystkich sytuacjach. Na przykład w systemach zorientowanych obiektowo ten styl często daje lepsze wyniki przy opracowywaniu modelu domeny (tj. tam, gdzie współpraca służy do przełamania złożoności reguł biznesowych) niż przy opracowywaniu interfejsu użytkownika. Opanuj paradygmat programowania funkcjonalnego, aby móc rozsądnie zastosować wyciągnięte wnioski w innych dziedzinach. Twoje systemy obiektów (na przykład) będą rezonować z referencyjną dobrocią przezroczystości i będą znacznie bliższe swoim funkcjonalnym odpowiednikom, niż wielu by ci uwierzyło. W rzeczywistości niektórzy twierdzą nawet, że na swoim szczycie programowanie funkcjonalne i orientacja obiektowa są jedynie wzajemnym odbiciem, formą obliczeniowego yin i yang.

Zapytaj: "Co zrobiłby użytkownik?" (Nie jesteś użytkownikiem)

Wszyscy mamy skłonność do zakładania, że inni ludzie myślą tak jak my. Ale tak nie jest. Psychologowie nazywają to fałszywym uprzedzeniem konsensusu. Kiedy ludzie myślą lub działają inaczej niż my, jest całkiem prawdopodobne, że w jakiś sposób oznaczymy ich (podświadomie) jako wadliwych. To uprzedzenie wyjaśnia, dlaczego programistom tak trudno jest postawić się w sytuacji użytkowników. Użytkownicy nie myślą jak programiści. Po pierwsze, spędzają znacznie mniej czasu na komputerach. Nie wiedzą ani nie dbają o to, jak działa komputer. Oznacza to, że nie mogą korzystać z żadnej z baterii technik rozwiązywania problemów, które są tak dobrze znane programistom. Nie rozpoznają wzorców i wskazówek używanych przez programistów do pracy z interfejsem, za jego pośrednictwem i wokół niego. Najlepszym sposobem, aby dowiedzieć się, jak myśli użytkownik, jest jego obejrzenie. Poproś użytkownika o wykonanie zadania przy użyciu oprogramowania podobnego do tego, które tworzysz. Upewnij się, że zadanie jest prawdziwe: "Dodaj kolumnę liczb" jest OK; "Oblicz swoje wydatki za ostatni miesiąc" jest lepsze. Unikaj zadań, które są zbyt szczegółowe, takie jak "Czy możesz wybrać te komórki arkusza kalkulacyjnego i wprowadzić poniżej formułę SUMA?" - w tym pytaniu jest duża wskazówka. Poproś użytkownika, aby omówił swoje postępy. Nie przerywaj. Nie próbuj pomagać. Zadaj sobie pytanie: "Dlaczego on to robi?" i "Dlaczego ona tego nie robi?" Pierwszą rzeczą, którą zauważysz, jest to, że użytkownicy robią wiele rzeczy w podobny sposób. Starają się wykonywać zadania w tej samej kolejności - i popełniają te same błędy w tym samym miejsca. Powinieneś projektować wokół tego podstawowego zachowania. Różni się to od spotkań projektowych, na których ludzie mają tendencję do słuchania, gdy ktoś mówi: "A co, jeśli użytkownik chce…?" Prowadzi to do rozbudowanych funkcji i zamieszania co do tego, czego chcą użytkownicy. Oglądanie użytkowników eliminuje to zamieszanie. Zobaczysz, że użytkownicy utkną. Kiedy utkniesz, rozglądasz się. Gdy użytkownicy utkną, zawężają swoją uwagę. Trudniej jest im zobaczyć rozwiązania w innym miejscu na ekranie. To jeden z powodów, dla których tekst pomocy jest słabym rozwiązaniem problemu złego projektu interfejsu użytkownika. Jeśli potrzebujesz instrukcji lub tekstu pomocy, zlokalizuj go tuż obok problematycznych obszarów. Wąski zakres uwagi użytkownika sprawia, że podpowiedzi są bardziej przydatne niż menu pomocy. Użytkownicy mają tendencję do przedzierania się. Znajdą sposób, który zadziała i będą się go trzymać, bez względu na to, jak zawiłe. Lepiej podać jeden naprawdę oczywisty sposób robienia rzeczy niż dwa lub trzy skróty. Przekonasz się również, że istnieje przepaść między tym, czego chcą użytkownicy, a tym, co faktycznie robią. To niepokojące, ponieważ normalnym sposobem zbierania wymagań użytkowników jest ich zapytanie. Dlatego najlepszym sposobem na uchwycenie wymagań jest obserwowanie użytkowników. Spędzenie godziny na oglądaniu użytkowników jest bardziej pouczające niż spędzenie dnia na zgadywaniu, czego chcą.

Zautomatyzuj swój standard kodowania

Prawdopodobnie też tam byłeś. Na początku projektu każdy ma wiele dobrych intencji - nazwijmy je "postanowieniami nowego projektu". Dość często wiele z tych rezolucji jest spisywanych w dokumentach. Te o kodzie trafiają do standardu kodowania projektu. Podczas spotkania inauguracyjnego główny programista przegląda dokument i, w najlepszym przypadku, wszyscy zgadzają się, że spróbują postępować zgodnie z nimi. Jednak po rozpoczęciu projektu te dobre intencje są porzucane, pojedynczo. Kiedy projekt jest w końcu dostarczany, kod wygląda jak bałagan i wydaje się, że nikt nie wie, jak do tego doszło. Kiedy coś poszło nie tak? Prawdopodobnie już na spotkaniu inauguracyjnym. Niektórzy członkowie projektu nie zwracali na to uwagi. Inni nie rozumieli, o co chodzi. Co gorsza, niektórzy się nie zgodzili i już planowali swój standardowy bunt kodowania. W końcu niektórzy zrozumieli i zgodzili się, ale kiedy presja w projekcie była zbyt duża, musieli coś odpuścić. Dobrze sformatowany kod nie zapewnia punktów u klienta, który chce większej funkcjonalności. Co więcej, przestrzeganie standardu kodowania może być dość nudnym zadaniem, jeśli nie jest zautomatyzowane. Po prostu spróbuj ręcznie wciąć niechlujną klasę, aby się przekonać. Ale jeśli to jest taki problem, dlaczego chcemy standardu kodowania w pierwszym miejsce? Jednym z powodów formatowania kodu w jednolity sposób jest to, że nikt nie może "posiadać" fragmentu kodu tylko poprzez formatowanie go na swój prywatny sposób. Możemy chcieć uniemożliwić programistom korzystanie z niektórych antywzorców, aby uniknąć niektórych typowych błędów. Podsumowując, standard kodowania powinien ułatwiać pracę w projekcie i utrzymywać tempo rozwoju od początku do końca. Wynika z tego, że wszyscy powinni również zgodzić się na standard kodowania - nie pomaga, jeśli jeden programista używa trzech spacji do wcięcia kodu, a inny używa czterech. Istnieje wiele narzędzi, które można wykorzystać do tworzenia raportów dotyczących jakości kodu oraz dokumentowania i utrzymywania standardu kodowania, ale to nie jest całe rozwiązanie. Powinna być zautomatyzowana i egzekwowana tam, gdzie to możliwe. Oto kilka przykładów:

•  Upewnij się, że formatowanie kodu jest częścią procesu kompilacji, tak aby wszyscy uruchamiali je automatycznie za każdym razem, gdy kompilują kod.
•  Użyj narzędzi do statycznej analizy kodu, aby przeskanować kod w poszukiwaniu niechcianych antywzorców. Jeśli jakieś zostaną znalezione, przerwij kompilację.
•  Naucz się konfigurować te narzędzia, aby móc skanować w poszukiwaniu własnych, specyficznych dla projektu antywzorców.
•  Nie tylko mierz pokrycie testowe, ale także automatycznie sprawdzaj wyniki. Ponownie przerwij kompilację, jeśli pokrycie testowe jest zbyt niskie.
Spróbuj zrobić to dla wszystkiego, co uważasz za ważne. Nie będziesz w stanie zautomatyzować wszystkiego, na czym naprawdę Ci zależy. Jeśli chodzi o rzeczy, których nie możesz automatycznie oznaczyć lub naprawić, potraktuj je jako zestaw wytycznych uzupełniających standard kodowania, który jest zautomatyzowany, ale zaakceptuj, że Ty i Twoi współpracownicy możecie nie przestrzegać ich tak pilnie. Wreszcie standard kodowania powinien być dynamiczny, a nie statyczny. Wraz z rozwojem projektu zmieniają się jego potrzeby, a to, co mogło wydawać się inteligentne na początku, niekoniecznie musi być mądre kilka miesięcy później.

Piękno tkwi w prostocie

Jest jeden cytat z Platona, który moim zdaniem jest szczególnie dobry dla wszystkich programistów, aby znać i trzymać się blisko ich serc:

Piękno stylu i harmonia, wdzięk i dobry rytm zależą od prostoty.

W jednym zdaniu podsumowuje to wartości, do których my, programiści, powinniśmy dążyć. W naszym kodzie dążymy do kilku rzeczy:

•  Czytelność
•  Łatwość utrzymania
•  Szybkość rozwoju
•  Nieuchwytna jakość piękna

Platon mówi nam, że czynnikiem umożliwiającym wszystkie te cechy jest prostota. Czym jest piękny kod? To potencjalnie bardzo subiektywne pytanie. Postrzeganie piękna w dużej mierze zależy od indywidualnego pochodzenia, tak jak wiele z naszego postrzegania czegokolwiek zależy od naszego pochodzenia. Osoby z wykształceniem artystycznym inaczej postrzegają (a przynajmniej podchodzą do) piękno niż osoby wykształcone w naukach ścisłych. Kierunki artystyczne mają tendencję do podejścia do piękna w oprogramowaniu, porównując oprogramowanie do dzieł sztuki, podczas gdy kierunki ścisłe mają tendencję do mówienia o symetrii i złotym podziale, próbując zredukować rzeczy do formuł. Z mojego doświadczenia wynika, że prostota jest podstawą większości argumentów obu stron. Pomyśl o kodzie źródłowym, który przestudiowałeś. Jeśli nie spędziłeś czasu na studiowaniu kodu innych ludzi, przestań to czytać w tej chwili i znajdź jakiś kod open source do przestudiowania. Na serio! Mam to na myśli! Poszukaj w Internecie kodu w wybranym przez Ciebie języku, napisanego przez znanego, uznanego eksperta. Jesteś z powrotem? Dobrze. Gdzie byliśmy? Ach, tak… Odkryłem, że kod, który współbrzmi ze mną i który uważam za piękny, ma wiele cech wspólnych. Najważniejszym z nich jest prostota. Uważam, że bez względu na to, jak złożona jest cała aplikacja lub system, poszczególne części muszą być proste: proste obiekty z jedną odpowiedzialnością zawierające podobnie proste, ukierunkowane metody z opisowymi nazwami. Niektórzy uważają, że pomysł posiadania krótkich metod składających się z 5-10 linijek kodu jest ekstremalny, a niektóre języki bardzo to utrudniają, ale myślę, że taka zwięzłość jest jednak pożądanym celem. Najważniejsze jest to, że piękny kod to prosty kod. Każda pojedyncza część jest prosta, z prostymi obowiązkami i prostymi relacjami z innymi częściami systemu. W ten sposób możemy utrzymać nasze systemy podatne na konserwację w czasie, z czystym, prostym i testowalnym kodem, zapewniając dużą szybkość rozwoju przez cały okres użytkowania systemu. Piękno rodzi się i znajduje w prostocie.

Zanim dokonasz restrukturyzacji

W pewnym momencie każdy programista będzie musiał dokonać resrukturyzacjii istniejącego kodu. Ale zanim to zrobisz, pomyśl o następujących rzeczach, ponieważ może to zaoszczędzić Tobie i innym dużo czasu (i bólu):

•  Najlepsze podejście do restrukturyzacji zaczyna się od podsumowania istniejącego kodu i testów napisanych na podstawie tego kodu. Pomoże Ci to zrozumieć mocne i słabe strony kodu w jego obecnej formie, dzięki czemu możesz zachować mocne strony, jednocześnie unikając błędów. Wszyscy myślimy, że możemy zrobić coś lepszego niż istniejący system… dopóki nie otrzymamy czegoś nie lepszego - lub nawet gorszego - niż poprzednie wcielenie, ponieważ nie nauczyliśmy się na błędach istniejącego systemu.

•  Unikaj pokusy pisania wszystkiego od nowa. Najlepiej jest ponownie wykorzystać jak najwięcej kodu. Bez względu na to, jak brzydki jest kod, został on już przetestowany, zrecenzowany itp. Wyrzucanie starego kodu - zwłaszcza jeśli był w produkcji - oznacza, że wyrzucasz miesiące (lub lata) przetestowanego, zahartowanego w boju kodu, który może mieć pewne obejścia i poprawki błędów, o których nie wiesz. Jeśli nie weźmiesz tego pod uwagę, nowy kod, który napiszesz, może skończyć się wyświetlaniem tych samych tajemniczych błędów, które zostały naprawione w starym kodzie. Zmarnuje to dużo czasu, wysiłku i wiedzy zdobytej przez lata.

•  Wiele stopniowych zmian jest lepszych niż jedna ogromna zmiana. Zmiany przyrostowe pozwalają łatwiej ocenić wpływ na system dzięki informacjom zwrotnym, takim jak testy. Nie jest zabawne widzieć setki niepowodzeń w testach po wprowadzeniu zmian. Może to prowadzić do frustracji i presji, które z kolei mogą prowadzić do złych decyzji. Łatwiej jest poradzić sobie z kilkoma niepowodzeniami testów na raz, co prowadzi do łatwiejszego podejścia.

•  Po każdej iteracji programistycznej ważne jest, aby upewnić się, że istniejące testy przeszły pomyślnie. Dodaj nowe testy, jeśli istniejące testy nie są wystarczające, aby uwzględnić wprowadzone zmiany. Nie wyrzucaj testów ze starego kodu bez należytego rozważenia. Na pierwszy rzut oka niektóre z tych testów mogą nie mieć zastosowania do twojego nowego projektu, ale warto byłoby zagłębić się w powody, dla których ten konkretny test został dodany.

•  Osobiste preferencje i ego nie powinny przeszkadzać. Jeśli coś nie jest zepsute, po co to naprawiać? To, że styl lub struktura kodu nie odpowiada Twoim osobistym preferencjom, nie jest ważnym powodem do restrukturyzacji. Myślenie, że mógłbyś wykonać lepszą pracę niż poprzedni programista, również nie jest uzasadnionym powodem.

•  Nowa technologia jest niewystarczającym powodem do refaktoryzacji. Jednym z najgorszych powodów do refaktoryzacji jest to, że obecny kod jest daleko w tyle za całą fajną technologią, którą mamy dzisiaj, i wierzymy, że nowy język lub framework może robić rzeczy o wiele bardziej elegancko. O ile analiza kosztów i korzyści nie wykaże, że nowy język lub framework przyniesie znaczną poprawę funkcjonalności, łatwości konserwacji lub produktywności, najlepiej pozostawić to bez zmian.

•  Pamiętaj, że ludzie popełniają błędy. Restrukturyzacja nie zawsze zagwarantuje, że nowy kod będzie lepszy, a nawet tak dobry, jak poprzednia próba. Widziałem i brałem udział w kilku nieudanych próbach restrukturyzacji. To nie było ładne, ale było ludzkie.

Uważaj na współudział

To był mój pierwszy projekt w firmie. Właśnie skończyłem studia i chciałem się wykazać, codziennie spóźniając się, przeglądając istniejący kod. Kiedy pracowałem nad moją pierwszą funkcją, bardzo uważałem, aby umieścić wszystko, czego się nauczyłem - komentowanie, logowanie, wyciąganie współdzielonego kodu do bibliotek tam, gdzie to możliwe, prace. Przegląd kodu, na który czułem się tak gotowy, przyszedł jako niegrzeczne przebudzenie - ponowne użycie było mile widziane! Jak to możliwe? Przez cały czas trwania studiów ponowne użycie było uważane za uosobienie wysokiej jakości inżynierii oprogramowania. Wszystkie artykuły, które przeczytałem, podręczniki, doświadczeni specjaliści od oprogramowania, którzy mnie nauczyli - czy to wszystko było złe? Okazuje się, że brakowało mi czegoś krytycznego. Kontekstu. Fakt, że dwie szalenie różne części systemu wykonały pewną logikę w ten sam sposób znaczyło mniej, niż myślałem. Dopóki nie wyciągnąłem tych bibliotek współdzielonego kodu, te części nie były od siebie zależne. Każdy mógł ewoluować niezależnie. Każdy może zmienić swoją logikę, aby dopasować ją do potrzeb zmieniającego się otoczenia biznesowego systemu. Te cztery linijki podobnego kodu były przypadkowe - anomalia czasowa, zbieg okoliczności. To znaczy, dopóki się nie pojawiłem. Biblioteki współdzielonego kodu, które stworzyłem, wiązały sznurowadła każdej stopy z drugą. Nie można było wykonać kroków według jednej domeny biznesowej bez uprzedniej synchronizacji z drugą. Koszty utrzymania tych niezależnych funkcji były kiedyś znikome, ale wspólna biblioteka wymagała o rząd wielkości więcej testów. Podczas gdy zmniejszyłem bezwzględną liczbę linii kodu w systemie, zwiększyłem liczbę zależności. Kontekstem tych zależności jest krytyczne - gdyby zostały zlokalizowane, udostępnienie mogło być uzasadnione i mieć pewną pozytywną wartość. Kiedy te zależności nie są utrzymywane w ryzach, ich wąsy oplatają większe problemy systemu, mimo że sam kod wygląda dobrze. Te błędy są podstępne, ponieważ w istocie brzmią jak dobry pomysł. Techniki te, zastosowane w odpowiednim kontekście, są cenne. W niewłaściwym kontekście zwiększają koszt, a nie wartość. Wchodząc do istniejącej bazy kodu bez wiedzy o tym, gdzie będą używane różne części, obecnie jestem znacznie bardziej ostrożny w kwestii tego, co jest udostępniane. Strzeż się akcji. Sprawdź swój kontekst. Dopiero wtedy kontynuuj.

Zasada skauta

Skauci mają zasadę: "Zawsze zostawiaj pole namiotowe czystsze, niż je znalazłeś". Jeśli znajdziesz bałagan na ziemi, posprzątasz go bez względu na to, kto mógł to zrobić. Celowo poprawiasz otoczenie dla kolejnej grupy obozowiczów. (Właściwie pierwotna forma tej zasady, napisana przez Roberta Stephensona Smytha Baden-Powella, ojca harcerstwa, brzmiała: "Spróbuj opuścić ten świat trochę lepszym, niż go znalazłeś"). Kod: "Zawsze sprawdzaj moduł w czystszym niż podczas sprawdzania"? Bez względu na to, kim był pierwotny autor, co jeśli zawsze staraliśmy się ulepszyć moduł, bez względu na to, jak mały? Jaki byłby wynik? Myślę, że gdybyśmy wszyscy postępowali zgodnie z tą prostą zasadą, zobaczylibyśmy koniec nieustannego pogarszania się naszych systemów oprogramowania. Zamiast tego nasze systemy stopniowo stawały się coraz lepsze w miarę ewolucji. Widzielibyśmy również zespoły dbające o system jako całość, a nie tylko osoby dbające o swoją małą część. Nie sądzę, aby ta zasada była zbyt duża, by prosić. Nie musisz dopracowywać każdego modułu przed zaewidencjonowaniem. Po prostu musisz uczynić go trochę lepszym niż wtedy, gdy go zaewidencjonowałeś. Oczywiście oznacza to, że każdy kod dodany do modułu musi być czysty. Oznacza to również, że przed ponownym zaewidencjonowaniem modułu wyczyścisz co najmniej jedną inną rzecz. Możesz po prostu poprawić nazwę jednej zmiennej lub podzielić jedną długą funkcję na dwie mniejsze. Możesz przerwać zależność cykliczną lub dodać interfejs, aby oddzielić zasady od szczegółów. Szczerze mówiąc, brzmi to dla mnie jak zwykła przyzwoitość - jak mycie rąk po skorzystaniu z toalety lub wyrzucanie śmieci do kosza zamiast upuszczania ich na podłogę. Rzeczywiście, pozostawienie bałaganu w kodeksie powinno być społecznie niedopuszczalne, podobnie jak zaśmiecanie. Powinno to być coś, czego się po prostu nie robi. Ale to coś więcej. Dbanie o własny kod to jedno. Dbanie o kod zespołu to zupełnie inna sprawa. Zespoły pomagają sobie nawzajem i sprzątają po sobie. Przestrzegają zasady Boy Scout, ponieważ jest to dobre dla wszystkich, a nie tylko dla nich samych.

Sprawdź swój kod, zanim zaczniesz obwiniać innych

Deweloperzy - wszyscy z nas ! - często mają problem z uwierzeniem, że nasz własny kod jest zepsuty. To po prostu tak nieprawdopodobne, że choć raz musi to być uszkodzony kompilator. Jednak w rzeczywistości bardzo (bardzo) niezwykłe jest to, że kod jest łamany przez błąd w kompilatorze, interpreterze, systemie operacyjnym, serwerze aplikacji, bazie danych, menedżerze pamięci lub jakimkolwiek innym oprogramowaniu systemowym. Tak, te błędy istnieją, ale są znacznie mniej powszechne, niż moglibyśmy sądzić. Kiedyś miałem prawdziwy problem z błędem kompilatora, który optymalizował zmienną pętli, ale wyobrażałem sobie, że mój kompilator lub system operacyjny ma błąd wiele razy. Zmarnowałem dużo czasu, czasu wsparcia i czasu zarządzania, tylko po to, by czuć się trochę głupio za każdym razem, gdy okazywało się to moim błędem. Zakładając, że narzędzia są powszechnie używane, dojrzałe i wykorzystywane w różnych stosach technologicznych, nie ma powodu, aby wątpić w jakość. Oczywiście, jeśli narzędzie jest wczesną wersją lub jest używane tylko przez kilka osób na całym świecie, lub jest rzadko pobieranym oprogramowaniem w wersji 0.1 o otwartym kodzie źródłowym, może być dobry powód, aby podejrzewać to oprogramowanie. (Podobnie, wersja alfa komercyjnego oprogramowania może być podejrzana.) Biorąc pod uwagę, jak rzadkie są błędy kompilatora, znacznie lepiej poświęcasz swój czas i energię na znalezienie błędu w swoim kodzie niż na udowodnienie, że kompilator jest zły. Obowiązują wszystkie zwykłe porady dotyczące debugowania, więc wyizoluj problem, stłum wywołania i otocz go testami; sprawdź konwencje wywoływania, biblioteki współdzielone i numery wersji; wyjaśnij to komuś innemu; zwracaj uwagę na uszkodzenie stosu i niezgodności typów zmiennych; i wypróbuj kod na różnych komputerach i różnych konfiguracjach kompilacji, takich jak debugowanie i wydanie. Kwestionuj własne założenia i założenia innych. Narzędzia od różnych dostawców mogą mieć wbudowane różne założenia - tak samo mogą być różne narzędzia od tego samego dostawcy. Kiedy ktoś inny zgłasza problem, którego nie możesz powielić, idź i zobacz, co robi. Mogą robić coś, o czym nigdy nie pomyślałeś lub robią coś w innej kolejności. Moją osobistą zasadą jest to, że jeśli mam błąd, którego nie mogę określić i zaczynam myśleć, że to kompilator, to czas poszukać uszkodzenia stosu. To jest szczególnie prawdziwe, jeśli dodanie kodu śledzenia powoduje, że problem się porusza. Problemy wielowątkowe to kolejne źródło błędów, które siwieją włosy i wywołują krzyki na maszynę. Wszystkie zalecenia dotyczące prostego kodu są mnożone, gdy system jest wielowątkowy. Nie można polegać na debugowaniu i testach jednostkowych w celu znalezienia takich błędów o jakiejkolwiek spójności, więc prostota projektu jest najważniejsza. Tak więc, zanim zaczniesz obwiniać kompilatora, pamiętaj o radzie Sherlocka Holmesa: "Kiedy wyeliminujesz niemożliwe, wszystko, co pozostanie, bez względu na to, jak nieprawdopodobne, musi być prawdą" i zdecyduj się na to zamiast zdania Dirka Gently′ego: "Gdy wyeliminujesz nieprawdopodobne , cokolwiek pozostaje, bez względu na to, jak niemożliwe, musi być prawdą."