Czy dobrą praktyką jest używanie pustego adresu URL dla atrybutu akcji formularza HTML? (akcja = „”)

279

Zastanawiam się, czy ktokolwiek może udzielić odpowiedzi „najlepszych praktyk” na użycie pustych działań formularza HTML w celu opublikowania z powrotem na bieżącej stronie.

Jest post z pytaniem, co robi tutaj pusta czynność formularza HTML, a niektóre strony takie jak ta sugerują, że jest w porządku, ale chciałbym wiedzieć, co ludzie myślą.

Matt Mitchell
źródło
7
Sugeruje się zastosowanie do tego tagu „najlepszych praktyk”.
Will Morgan,
Aby podwójnie potwierdzić, pozostaw akcję pustą lub po prostu nie wspominaj o żadnej akcji (jak <form name="xyz" >). Prześle działanie samodzielnie.
lwpro2
11
Brak atrybutu action powoduje otwarcie strony na ataki typu „ kliknięcie iframe ”, takie jak atakujący, który zawija twoją stronę w ramce iframe, a adres URL iframe zawiera parametr zapytania o tej samej nazwie co pole formularza. Po przesłaniu formularza wartość zapytania jest wstawiana do bazy danych, więc informacje identyfikujące użytkownika (adres e-mail, adres itp.) Zostały naruszone.
Paul Sweatte,
Zatem jaki jest prawidłowy, bezpieczny sposób przesłania formularza na bieżącą stronę?
Costa

Odpowiedzi:

268

Najlepsze, co możesz zrobić, to całkowicie pominąć atrybut akcji. Jeśli go pominiesz, formularz zostanie przesłany na adres dokumentu, tj. Tę samą stronę.

Możliwe jest również pozostawienie go pustego, a każda przeglądarka implementująca algorytm przesyłania formularzy HTML będzie traktować go jako równoważny adresowi dokumentu, co dzieje się głównie dlatego, że tak właśnie działają przeglądarki:

8.Niech akcja będzie działaniem elementu wysyłającego .

9.Jeśli akcja jest pustym ciągiem, niech akcja będzie adresem dokumentu .

Uwaga: ten krok jest umyślnym naruszeniem RFC 3986, co wymagałoby tutaj przetwarzania podstawowego adresu URL. Przyczyną tego naruszenia jest chęć zgodności ze starszymi treściami. [RFC3986]

To z pewnością działa we wszystkich obecnych przeglądarkach, ale może nie działać zgodnie z oczekiwaniami w niektórych starszych przeglądarkach ( przeglądarki robią dziwne rzeczy z pustym atrybutem action =” ) , dlatego specyfika zdecydowanie odradza autorom pozostawienie go pustym :

Te actioni formactiontreści atrybuty, jeżeli został on określony, musi mieć wartość, która jest ważna niepusty URL potencjalnie otoczony spacjami .

mercator
źródło
12
Być może zmieniło się to od czasu twojej odpowiedzi ( action=""
minęły
2
@derobert Thanks. To chyba się nie zmieniło. Zmieniłem odpowiedź, aby lepiej odzwierciedlić to, co mówi specyfikacja.
mercator
73

W rzeczywistości podsekcja Zgłaszanie formularzy bieżącego szkicu HTML5 nie pozwala action="". Jest to niezgodne ze specyfikacją.

Te actioni formactiontreści atrybuty, jeżeli został on określony, musi mieć wartość, która jest ważna niepusty URL potencjalnie otoczony spacjami. (podkreślenie dodane)

Cytowana sekcja w odpowiedzi mercatora jest wymogiem dotyczącym implementacji , a nie autorów . Autorzy muszą przestrzegać wymagań autora. Cytując Jak czytać tę specyfikację :

W szczególności istnieją wymagania dotyczące zgodności, które dotyczą producentów, na przykład autorów i tworzonych przez nich dokumentów, a także wymagania dotyczące zgodności, które dotyczą konsumentów, na przykład przeglądarek internetowych. Można je rozróżnić według tego, czego wymagają: wymóg producenta określa, co jest dozwolone, zaś wymóg konsumenta określa sposób działania oprogramowania.

Zmiana z HTML4 - która pozwoliła na pusty adres URL - została wprowadzona, ponieważ „ przeglądarki robią dziwne rzeczy z pustym action=""atrybutem ”. Biorąc pod uwagę powód zmiany, prawdopodobnie najlepiej nie robić tego również w HTML4.

derobert
źródło
Czy pozwala to na całkowity brak actionatrybutu, aby wskazać, że formularz powinien zostać przesłany na adres dokumentu? Wydaje się, ponieważ mówi „jeśli jest określony”.
Kerrick
2
@Kerrick Tak, uważam, że HTML5 pozwala całkowicie pominąć atrybut akcji i domyślnie przyjmuje pusty ciąg znaków. HTML4 nie, określa działanie zgodnie z wymaganiami.
derobert
Zgadzam się z @Kerrick, dozwolone jest pominięcie atrybutu akcji. Czytając bieżący szkic HTML5, wydaje się, że pusty ciąg znaków jest niedozwolony, ale dozwolony jest brak atrybutu. W każdym razie ze względów kompatybilności zalecam zawsze dołączanie atrybutu „action” i wypełnianie go niepoprawnym pustym adresem URL (dobre praktyki są zawsze najlepszym sposobem).
serfer2
Jedna potencjalna gotcha: AngularJS zapobiegnie przesyłaniu formularzy bez atrybutu akcji. Prawdopodobnie nie jest to częsty problem, ale zajęło mi trochę czasu, aby dowiedzieć się, dlaczego niektóre części naszej starej witryny zaczęły się psuć.
Asmor
18

Brak atrybutu action powoduje otwarcie strony na ataki typu „ clickjacking” iframe , które obejmują kilka prostych kroków:

  • Osoba atakująca otacza twoją stronę ramką iframe
  • Adres URL elementu iframe zawiera parametr zapytania o tej samej nazwie co pole formularza
  • Po przesłaniu formularza wartość zapytania jest wstawiana do bazy danych
  • Informacje identyfikujące użytkownika (adres e-mail, adres itp.) Zostały naruszone

Bibliografia

Paul Sweatte
źródło
2
Czy adres URL elementu iframe nie zawiera parametrów GET, podczas gdy formularze są zwykle przesyłane przy użyciu POST? Więc jeśli strona zajmuje się tylko parametrami POST, to nie powinno stanowić problemu, prawda? Przynajmniej zwykle używam tablicy $ _POST w PHP tylko podczas przetwarzania formularzy.
Calmarius
2
@Calmarius Tak, użyj $_POSTzamiast, $_REQUESTaby tego uniknąć. Jeśli $_REQUESTużywasz kodu frameworka , użyj klastra iframe .
Paul Sweatte
17

Spowoduje to sprawdzenie poprawności w HTML5.

<form action="#">

źródło
4
Nie próbowałem tego, ale koncepcyjnie nie przewijałoby się na górę strony po przesłaniu?
Matt Mitchell,
2
Nie mogłeś użyć action="."?
s427
3
akcja = „?” działa również dobrze. Sprawdza poprawność i wskazuje bieżącą stronę bez danych zapytania i ciągów.
Chris Broski,
5
action="."to zły pomysł na ogólny przypadek. Adres URL podobny example.com/loginjest zmapowany tylko na example.com/.
Torsten Bronger
1
Ta odpowiedź jest ważna tylko wtedy, gdy użytkownik chce przewinąć do góry strony.
Buts
9

W HTML 5 action=""NIE JEST OBSŁUGIWANE, więc NIE Rób tego. ZŁA PRAKTYKA.

Jeśli zamiast tego całkowicie zignorujesz działanie, domyślnie zostanie ono przesłane na tę samą stronę, uważam, że jest to najlepsza praktyka:

<form>This will submit to the current page</form>

Jeśli wypełniasz formularz przy użyciu php, możesz rozważyć następujące kwestie. czytaj więcej o tym tutaj.

<form method="post" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>">

Możesz też #pamiętać, że będzie to działać jak kotwica i przewiń na górę strony.

<form action="#">
Ale
źródło
Czy chcesz zrozumieć, dlaczego ktoś głosował za odrzuceniem tej odpowiedzi?
Buts
Nie zgadzasz się z atrybutem akcji, czy formularz jest nadal otwarty na exploity, które są wyszczególnione na pierwszej stronie linku?
Richard Young
@RichardYoung Niestety nie rozumiem twojego pytania. Proszę ponownie sformułować.
Ale
1
Hakerzy mogą używać zmiennej $ _SERVER ["PHP_SELF"]. Jeśli PHP_SELF jest używany na twojej stronie, użytkownik może wprowadzić ukośnik (/), a następnie niektóre polecenia XSS (Cross Site Scripting) w celu wykonania. Jeśli pominiesz atrybut akcji, czy nadal jesteś na to narażony?
Richard Young,
Tak, jesteś. Atrybut akcji można dodać z powrotem po stronie klienta i podać dowolną wartość do wyboru. Jednak użycie tej htmlspecialchars()funkcji powstrzymuje ludzi przed używaniem skryptu php przeciwko tobie.
Ale
4

Zwykle używam akcji = "", która jest poprawna w XHTML i zachowuje dane GET w adresie URL.

Juddling
źródło
4
Rzadko, ale na przykład na moim forum miałbym adres URL: thread.php? Id = 12 & page = 6, a na dole strony znajduje się formularz POST do dodawania komentarzy, a ja potrzebuję danych GET, więc PHP wie, do którego wątku dodać komentarz.
Juddling 15.07.2009
20
GET jest domyślną metodą dla formularzy - nie jest to zła rzecz ;-) w3.org/TR/html401/interact/forms.html#adef-method
NickFitz
5
Używanie GET w formularzach jest złą rzeczą. Jeśli użytkownik przeładuje stronę po przesłaniu, mogą wystąpić niezamierzone konsekwencje. Jeśli jednak użyty zostanie test POST, przeglądarka ostrzeże o ponownym przesłaniu tych samych danych.
Will Sheppard,
22
@WillSheppard Nie zgadzam się. Nie możesz złożyć takiego ogólnego oświadczenia. Wszystko zależy od tego, co robi formularz. Powinieneś używać POST do wszystkiego, co wykonuje akcję (np. Wstawianie nowego postu na forum), ale GET do wszystkiego innego (np. Pole wyszukiwania lub używanie formularzy do nawigacji). Po pomyślnym przeprowadzeniu testu POST skrypt powinien przekierować przeglądarkę, aby uniemożliwić użytkownikowi ponowne przesłanie danych.
Mike
3
PS nie wszystkie przeglądarki ostrzegają użytkownika o ponownym przesłaniu danych POST (np. Opera)
Mike
4

Myślę, że najlepiej jest wyraźnie określić, gdzie znajduje się formularz. Jeśli chcesz być całkowicie bezpieczny, wpisz ten sam adres URL, w którym znajduje się formularz, w atrybucie akcji, jeśli chcesz, aby przesłał się z powrotem do siebie. Mimo że przeglądarki głównego nurtu oceniają ""tę samą stronę, nie można zagwarantować, że zrobią to przeglądarki inne niż ogólne.

I oczywiście cały URL, w tym dane GET, takie jak Juddling, wskazuje.

Will Morgan
źródło
2

Po prostu użyj

?

<form action="?" method="post" enctype="multipart/form-data" name="myForm" id="myForm">

Nie narusza standardów HTML5.

M_R_K
źródło
Nie przegłosowałem, ale twoja metoda porzuci wszystkie parametry get. Formularz podany poniżej urwałby się, example.com/update_user?user_id=1ponieważ formularz zostanie przesłany doexample.com/update_user?
vikki
1

Często to robiłem, kiedy pracowałem z Classic ASP. Zwykle używałem go, gdy potrzebna była jakaś weryfikacja po stronie serwera dla danych wejściowych (przed dniami AJAX). Główną wadą, którą widzę, jest to, że nie oddziela logiki programowania od prezentacji na poziomie plików.

busse
źródło
1
Dlaczego nie? Myślę, że to nie jest połączone. Mogę poprosić formularz o opublikowanie danych na tej samej stronie i zbudowanie tej strony z odpowiednim rozdzieleniem kontrolera i widoku.
markus
1

Używam, aby w ogóle nie określać atrybutu akcji. Tak naprawdę jest zaprojektowany mój framework, wszystkie strony są przesyłane z powrotem dokładnie pod ten sam adres. Ale dzisiaj odkryłem problem. Czasami pożyczam wartość atrybutu akcji, aby wykonać jakieś wywołanie w tle (chyba niektórzy nazywają je AJAX). Stwierdziłem więc, że IE zachowuje wartość atrybutu akcji jako pustą, jeśli atrybut akcji nie został określony. W moim rozumieniu jest to trochę dziwne, ponieważ jeśli nie określono atrybutu akcji, odpowiednik JavaScript musi być co najmniej niezdefiniowany. W każdym razie, moim celem jest, zanim wybierzesz najlepszą praktykę, musisz zrozumieć więcej kontekstu, na przykład czy użyjesz atrybutu w JavaScript, czy nie.

Singagirl
źródło