Okna.  Wirusy.  Laptopy.  Internet.  Biuro.  Narzędzia.  Kierowcy

Opis

Znacznik przeznaczony jest do opisu skryptów i może zawierać odnośnik do programu lub jego tekst w określonym języku. Skrypty można umieścić w pliku zewnętrznym i powiązać z dowolnym dokumentem HTML.

Takie podejście pozwala na korzystanie z tych samych ogólnych funkcji na wielu stronach internetowych i przyspiesza ich ładowanie, ponieważ plik zewnętrzny jest buforowany przy pierwszym załadowaniu, a skrypt jest wywoływany szybciej przy kolejnych wywołaniach.

mogą znajdować się w nagłówku lub treści dokumentu HTML w nieograniczonej ilości. W większości przypadków lokalizacja skryptu nie wpływa w żaden sposób na działanie programu. Jednak skrypty, które należy najpierw wykonać, są zwykle umieszczane w nagłówku dokumentu.

Składnia ... Atrybuty Ładuje skrypt asynchronicznie.

Opóźnia wykonanie skryptu do momentu pełnego załadowania całej strony.

Ustawia język programowania, w którym napisany jest skrypt.

Adres skryptu z pliku zewnętrznego do zaimportowania do bieżącego dokumentu.

Określa typ zawartości tagu.

Zamykanie tagu

Wymagany.

HTML 4.01 IE Cr Op Fx

Dokument znacznika SCRIPT.write("

"); for (i=1; iElements i

Różne technologie wspomagające będą wykorzystywać jako część etykiety etykietę wszystkich elementów w obrębie pliku . Na przykład czytniki ekranu, takie jak Jaws lub NVDA, wypowiadają tytuł formularza przed wypowiedzeniem nazwy etykiety elementu.

Mały przykład:

Ze względu na swój wpływ na technologie wspomagające element ten jest jednym z kluczowych elementów budowania dostępnych form; jednak nie należy go nadużywać. Jeśli to możliwe, spróbuj przetestować, jak Narrator interpretuje Twój formularz.

_element">Element

Rozważmy ten przykład:

*.

Imię: * Imię: * Imię: *

Akapit u góry określa regułę dla wymaganych elementów. Już na początku należy upewnić się, że technologie wspomagające, takie jak czytniki ekranu, wyświetlą to lub zasygnalizują użytkownikowi, zanim ten znajdzie wymagany element. Dzięki temu będą wiedzieć, co oznacza gwiazdka. Czytnik ekranu wypowie gwiazdę jako „ gwiazda"Lub" wymagany", w zależności od ustawień czytnika ekranu - w każdym razie to, co zostanie powiedziane, jest wyjaśnione w pierwszym akapicie).

  • W pierwszym przykładzie etykieta nie jest w ogóle odczytywana przy wprowadzaniu danych - po prostu pojawia się komunikat „edytuj pusty tekst”, a rzeczywiste etykiety są odczytywane oddzielnie. Wiele elementów myli czytnik ekranu.
  • W drugim przykładzie sytuacja jest nieco jaśniejsza - etykieta odczytywana wraz z danymi wejściowymi to „nazwa gwiazdki nazwa edytuj tekst”, a etykiety nadal są odczytywane osobno. Sytuacja jest nadal nieco zagmatwana, ale tym razem jest trochę lepiej, ponieważ z danymi wejściowymi jest powiązana etykieta.
  • Trzeci najlepszy jest przykład - rzeczywista etykieta jest odczytywana w całości, a etykieta odczytywana wraz z wejściem to „tekst edycji nazwy gwiazdki”.

Uwaga: w zależności od czytnika ekranu możesz uzyskać nieco inne wyniki. Zostało to przetestowane w VoiceOver (i NVDA zachowuje się podobnie). Chętnie też dowiemy się o Twoich doświadczeniach.

Uwaga: ten przykład można znaleźć na GitHubie jako wymagany-labels.html (zobacz go także na żywo). nie uruchamiaj przykładu z 2 lub 3 wersjami bez komentarza – czytniki ekranu na pewno się zdezorientują, jeśli masz wiele etykiet ORAZ wiele wejść z tym samym identyfikatorem!

Typowe struktury HTML używane w formularzach

Poza strukturami charakterystycznymi dla formularzy HTML warto pamiętać, że formularze to tylko HTML. Oznacza to, że możesz wykorzystaj całą moc HTML do ustrukturyzowania formularza HTML.

Jak widać na przykładach, powszechną praktyką jest owijanie elementu etykietą i jej widżetem.

elementy są również powszechnie używane, podobnie jak listy HTML (ta ostatnia jest najczęściej używana do tworzenia wielu pól wyboru lub przycisków opcji).

Oprócz elementu powszechną praktyką jest również używanie tytułów HTML (np. ) i sekcji (np. ) w celu ustrukturyzowania złożonego formularza.

Przede wszystkim od Ciebie zależy, czy znajdziesz styl, w którym będziesz czuł się komfortowo w kodowaniu, a który jednocześnie zapewni dostępne i użyteczne formy.

Ma to każdą oddzielną sekcję funkcjonalności zawartą w elementach i zawierającą przyciski opcji.

Aktywne uczenie się: budowanie struktury formularza

Wprowadźmy te pomysły w życie i zbudujmy nieco bardziej zaawansowaną strukturę formularza – formularz płatności. Ten formularz będzie zawierał wiele typów widżetów, których możesz jeszcze nie rozumieć – na razie się tym nie martw; dowiesz się, jak one działają w następnym artykule (Natywne widżety formularzy). Na razie przeczytaj uważnie opisy, postępując zgodnie z poniższymi instrukcjami i zacznij doceniać, jakich elementów opakowania używamy do struktury formularza i dlaczego.

  • Na początek utwórz lokalną kopię naszego pustego pliku szablonu i kodu CSS naszego formularza płatności w nowym katalogu na swoim komputerze.
  • Przede wszystkim zastosuj CSS do kodu HTML, dodając poniższe linia wewnątrz kodu HTML:
  • Następnie rozpocznij formularz, dodając element zewnętrzny:
  • Wewnątrz tagów zacznij od dodania nagłówka i akapitu informującego użytkowników o sposobie oznaczenia wymaganych pól: Formularz płatności

    Po polach wymaganych następuje *.

  • Następnie dodamy większą część kodu do formularza, poniżej naszego poprzedniego wpisu. Tutaj zobaczysz, że pola informacji kontaktowych zawijamy w odrębny element. Co więcej, mamy zestaw dwóch przycisków opcji, z których każdy umieszczamy na własnej liście (
  • ) elementu. Na koniec mamy dwa standardowe teksty i powiązane z nimi elementy, każdy zawarty wewnątrz a

    , plus hasło umożliwiające wprowadzenie hasła. Dodaj teraz ten kod do swojego formularza: Informacje kontaktowe Tytuł

    • Pan
    • Chybić

    Nazwa: *

    E-mail: *

    Hasło: *

  • Teraz przejdziemy do drugiej części naszego formularza – informacji o płatności. Tutaj mamy trzy różne widżety wraz z ich etykietami, każdy zawarty w

    Pierwsze to menu rozwijane (

  • Aby opisać istotę problemu muszę opowiedzieć jak ogólnie działa HTML. Prawdopodobnie masz ogólne pojęcie, ale nadal krótko omówię główne punkty, które będą potrzebne do zrozumienia. Jeśli ktoś jest niecierpliwy, proszę przejść od razu do rzeczy.


    HTML jest hipertekstowym językiem znaczników. Aby mówić w tym języku, musisz przestrzegać jego formatu, w przeciwnym razie ten, kto czyta to, co jest napisane, nie będzie w stanie cię zrozumieć. Na przykład w HTML tagi mają atrybuty:



    Oto nazwa atrybutu i jego wartość. W całym artykule będę używał nawiasów kwadratowych wokół kodu, aby było jasne, gdzie się zaczyna i kończy. Po nazwie znajduje się znak równości, a po niej wartość ujęta w cudzysłów. Wartość atrybutu rozpoczyna się bezpośrednio po pierwszym cudzysłowie i kończy bezpośrednio przed kolejnym cudzysłowem, niezależnie od tego, gdzie się on pojawi. Oznacza to, że jeśli zamiast tego napiszesz, to wartość atrybut nazwy będzie , a twój element będzie miał także trzy inne atrybuty z nazwami: [horns], [and] i [hooves."] , ale bez wartości.


    Jeśli nie jest to oczekiwane, musisz w jakiś sposób zmienić wartość atrybutu, tak aby nie zawierał cudzysłowu. Najprostszą rzeczą, jaką możesz wymyślić, to po prostu wyciąć cytaty.


    Wtedy parser HTML poprawnie odczyta wartość, ale problem jest taki, że będzie to inna wartość. Chciałeś tego, ale masz to. W niektórych przypadkach taka różnica może być krytyczna.


    Aby umożliwić określenie dowolnego ciągu znaków jako wartości, format języka HTML oferuje możliwość ucieczki od wartości atrybutów. Zamiast cudzysłowu w ciągu wartości możesz wpisać ciąg znaków ["], a parser zrozumie, że w tym miejscu w oryginalna linia, którego chcesz użyć jako wartości atrybutu, był cytatem. Takie sekwencje nazywane są jednostkami HTML.


    Jednocześnie, jeśli Twój oryginalny ciąg faktycznie zawierał ciąg znaków ["] , nadal masz możliwość jego zapisania, aby parser nie zamienił go w cudzysłów - w tym celu musisz zastąpić [& ] z ciągiem znaków [&] , to zamiast ["] będziesz musiał wpisać ["] w surowym tekście.


    Okazuje się, że konwersja z oryginalnego ciągu na ten, który zapiszemy pomiędzy dwoma cudzysłowami jest jednoznaczna i odwracalna. Dzięki tym przekształceniom można zapisać i odczytać dowolny ciąg znaków jako atrybut znacznika HTML, bez wchodzenia w istotę jego zawartości. Wystarczy postępować zgodnie z formatem i działa.


    Właściwie tak działa większość formatów, z którymi się spotykamy: istnieje składnia, istnieje sposób na uniknięcie treści z tej składni oraz sposób na uniknięcie znaków ucieczki, jeśli taka sekwencja występuje w ciągu źródłowym. Większość, ale nie...

    Etykietka

    Znacznik służy do osadzania w kodzie HTML fragmentów napisanych w innych językach. Dziś w 99% przypadków jest to Javascript. Skrypt rozpoczyna się bezpośrednio po tagu otwierającym i kończy bezpośrednio przed tagiem zamykającym. Parser HTML nie zagląda do wnętrza tagu, jest to po prostu jakiś tekst, który następnie wysyła do parsera JavaScript.


    Z kolei JavaScript jest niezależnym językiem z własną składnią, ogólnie rzecz biorąc, nie jest on w żaden specjalny sposób zaprojektowany do osadzenia w HTML. Podobnie jak każdy inny język, ma literały łańcuchowe, które mogą zawierać wszystko. I, jak powinieneś się domyślić, może istnieć ciąg znaków oznaczający znacznik zamykający.


    var s = "niespodzianka!alert("ups!")";

    Co powinno się tutaj wydarzyć: zmiennej s należy przypisać nieszkodliwy ciąg znaków.


    O co tu naprawdę chodzi: Skrypt deklarujący zmienną s kończy się tak: , co powoduje błąd składniowy. Cały tekst po nim jest interpretowany jako czysty kod HTML i można w nim osadzić dowolne znaczniki. W tym przypadku otwiera się nowy znacznik i wykonywany jest złośliwy kod.


    Otrzymujemy taki sam efekt jak wtedy, gdy w wartości atrybutu znajduje się cudzysłów. Jednak w przeciwieństwie do wartości atrybutów, tag nie ma możliwości ominięcia oryginalnej treści. Encje HTML wewnątrz tagu nie działają, zostaną przekazane do parsera JavaScript w niezmienionej postaci, czyli albo doprowadzą do błędu, albo zmienią jego znaczenie. Standard HTML wyraźnie stwierdza, że ​​treść tagu nie może zawierać ciągu znaków w żadnej formie. Standard JavaScript nie zabrania umieszczania takiej sekwencji w dowolnym miejscu w literałach łańcuchowych.


    Otrzymujemy paradoksalną sytuację: po osadzeniu prawidłowego JavaScriptu w poprawnym dokumencie HTML przy użyciu absolutnie poprawnych środków, możemy otrzymać nieprawidłowy wynik.


    Moim zdaniem jest to luka w znacznikach HTML, która prowadzi do luk w rzeczywistych aplikacjach.

    Sposób wykorzystania luki

    Oczywiście, gdy dopiero piszesz jakiś kod, trudno wyobrazić sobie, co napiszesz w linii i nie zauważyć problemów. Co najmniej podświetlanie składni poinformuje Cię, że tag został zamknięty z wyprzedzeniem, co najwyżej, napisany kod nie zostanie uruchomiony i będziesz musiał spędzić dużo czasu na szukaniu tego, co się stało. Ale to nie jest główny problem związany z tą luką. Problem pojawia się, gdy podczas generowania kodu HTML wstawiasz jakąś treść do JavaScript. Oto typowy fragment kodu dla aplikacji korzystających z React z renderowaniem serwerowym:


    okno.__INITIAL_STATE__ = ;

    Wartość początkowa może pojawić się wszędzie tam, gdzie dane pochodzą od użytkownika lub z innych systemów. JSON.stringify nie zmieni takich ciągów podczas serializacji, ponieważ są one w pełni sformatowane w formacie JSON i Javascript, więc po prostu wylądują na stronie i umożliwią atakującemu wykonanie dowolnego kodu JavaScript w przeglądarce użytkownika.


    Inny przykład:


    analytics.identify("", ...);

    Tutaj identyfikator użytkownika i odsyłacz, który przyszedł na serwer, są zapisane w wierszach z odpowiednim znakiem zmiany znaczenia. A jeśli jest mało prawdopodobne, aby user.id zawierał cokolwiek innego niż liczby, osoba atakująca może wrzucić cokolwiek do strony odsyłającej.


    Ale zabawa nie kończy się na zamykającym tagu. Znacznik otwierający jest również niebezpieczny, jeśli istnieje [ Kliknij tę etykietę, aby wybrać.



    Jeśli zauważysz błąd, zaznacz fragment tekstu i naciśnij Ctrl+Enter
    UDZIAŁ: