Wywołanie skryptów z przeglądarki

Wywołanie skryptów z przeglądarki
MR
  • Rejestracja:ponad 2 lata
  • Ostatnio:około 2 lata
  • Postów:125
0

Załóżmy, że w kodzie źródłowym mojej strony ktoś kumaty dojrzał:
<form action="doSomething.php" method="POST">
Czyli jak wpisze w przeglądarkę doSomething.php to coś się może stać… No właśnie, jak się przed tym zabezpieczyć? Pomysł mam taki jak poniżej. Tylko czy to jest sposób pewny i profesjonalny?

Sprawdzam po prostu, czy poprzez POST dostałem wszystko. A jak nie, to przekierowanie:

Kopiuj
if (isset($_POST[$myVariable])) {   
     header("refresh:1; url=form.html");
 }
Else {
// 
}

Druga sprawa to skrypty załączane poprzez require_once("doSomethingAdditional.php");. O ile użytkownik ich nie widzi i nie wie o nich, to może odgadnąć ich nazwę. Czy jest sens i takie skrypty zabezpieczać?

edytowany 2x, ostatnio: Riddle
KamilAdam
  • Rejestracja:ponad 6 lat
  • Ostatnio:dzień
  • Lokalizacja:Silesia/Marki
  • Postów:5505
4
MrocznyRycerz napisał(a):

Czyli jak wpisze w przeglądarkę doSomething.php to coś się może stać…

PHP nie znam, ale przeglądarka domyślnie wywołuje adresy przez GET, a nie POST. Ale zawsze można taki adres przepisać do postmana lub wywołać z CURLa

Kopiuj
curl -X POST twoja-strona/doSomething.php

Mama called me disappointment, Papa called me fat
Każdego eksperta można zastąpić backendowcem który ma się douczyć po godzinach. Tak zostałem ekspertem AI, Neo4j i Nest.js . Przez mianowanie
edytowany 1x, ostatnio: KamilAdam
jurek1980
  • Rejestracja:ponad 8 lat
  • Ostatnio:około godziny
  • Postów:3462
3

Ogólnie po co miałbyś się zabezpieczać? Jeśli ktoś chce wywołać stronę "w dedykowany sposób" to co za różnica czy zrobi to cURLem, przeglądarką, Postmanem czy ręcznie napisanym kodem. Jeśli chodzi Ci o to, że w formularzu masz np. 4 pola a ktoś wpisze wartość 3 no to po prostu waliduj przesłanie dane i wykonuj akcję tylko gdy są wszystkie i są poprawne. Możesz dodać jakieś uwierzytelnianie. Jeśli z kolei chcesz próbować w jakiś sposób zachować ciągłość działań możesz sprawdzić skąd przychodzi użytkownik poprzez $_SERVER['HTTP_REFERER'], możesz też np. zapisać coś w sesji.

MR
  • Rejestracja:ponad 2 lata
  • Ostatnio:około 2 lata
  • Postów:125
0

Mam wydzielony skrypt do przepisywania danych z POST na zmienną (z walidacją oczywiście). Co się stanie, jak wywołamy ten skrypt "na dziko" pomimo tego, że z zewnątrz nie jest widoczny? User dostanie po twarzy takim błędem:

Notice: Undefined index: PhoneNumber in C:\xampp\doSomething.php on line 4

jurek1980
  • Rejestracja:ponad 8 lat
  • Ostatnio:około godziny
  • Postów:3462
2

To znaczy, że nie walidujesz czy klucz PhoneNumber w POST jest. Względnie w innej części kodu.
Po prostu wykonuj jakąś akcję i dla takiego przypadku np.

Kopiuj
if(isset('someNeededKey') && isset('otherImportnatKey')) {
    doTherightJob();
}
else {
    header("Location: http://www.myAwsomeSecureWebsite/home"); // przekieruj na jakąś stronę domową
    // http_response_code(400); // zamiast przekierowania zwróć 400 - bad request
}
edytowany 1x, ostatnio: jurek1980
Szado
  • Rejestracja:ponad 7 lat
  • Ostatnio:4 miesiące
  • Lokalizacja:Kraków
  • Postów:64
2
MrocznyRycerz napisał(a):

Czyli jak wpisze w przeglądarkę doSomething.php to coś się może stać… No właśnie, jak się przed tym zabezpieczyć? Pomysł mam taki jak poniżej. Tylko czy to jest sposób pewny i profesjonalny?

Generalnie masz uzasadnioną obawę, poczytaj sobie o CSRF.
Natomiast Twój scenariusz jest bardzo typowy i prosty (koledzy już wyżej o tym pisali): jeśli dane formularza przyjmujesz metodą POST, a zależy Ci jedynie by zabezpieczyć się przed przypadkowym wejściem przeglądarką na adres i wykonaniem akcji, to tu nic nie musisz robić, bo przeglądarka domyślnie odpytuje serwer metodą GET.

Druga sprawa to skrypty załączane poprzez require_once("doSomethingAdditional.php");. O ile użytkownik ich nie widzi i nie wie o nich, to może odgadnąć ich nazwę. Czy jest sens i takie skrypty zabezpieczać?

Zależy co tam w tym kodzie masz. Jeśli same definicje struktur (co polecam), to niczym się martwić nie musisz, bo po wejściu na taki plik nic się nie wyświetli jeśli serwer jest poprawnie skonfigurowany (jeśli nie jest, to nic Cię nie uratuje). Natomiast jeśli masz tam odpalany kod w globalu, to lepiej zabezpieczyć się na taką okoliczność. W starych CMS-ach robiło się to jednolinijkowcem sprawdzającym istnienie stałej: defined('IN_APP') or die('Access denied'); a w pliku nadrzędnym przed includem: const IN_APP = true;.

MR
  • Rejestracja:ponad 2 lata
  • Ostatnio:około 2 lata
  • Postów:125
0

Albo wyobraźcie sobie, że ktoś odgaduje nazwę skryptu, który ogarnia połączenie z bazą danych. Komunikat z błędem poda na tacy kilka ciekawych informacji. Błędy można oczywiście wyłączyć (jeżeli się nie mylę, to error_reporting(0);), ale...

jurek1980
  • Rejestracja:ponad 8 lat
  • Ostatnio:około godziny
  • Postów:3462
3

Widzę masz złe podejście. W momencie ustawienia php.ini na produkcji masz zrobić tak, żeby użytkownik dostał błąd typu 403, 400 czy 500 itd. Będzie to błąd HTTP który nie zdradzi szczegółów czy haseł.
Poza tym, to tu nie ma co odgadywać. URLe są zapisane w kodzie HTML i może Cię zaskoczę ale są odwiedzane przez mnóstwo robotów, skryptów szukających luk bezpieczeństwa itd. Jeśli ściągniesz sobie paczki z PHP dla Windows to nie znajdziesz w nich pliku php.ini tylko php.ini.production i php.ini.development i w zależności od tego co robisz dopiero używasz sobie właściwego pliku przez np. zmianę nazwy. Proponuję edukacyjnie porównać ustawienia i poczytać w dokumentacji które co robi.

edytowany 1x, ostatnio: jurek1980
MR
  • Rejestracja:ponad 2 lata
  • Ostatnio:około 2 lata
  • Postów:125
0

Czyli po stronie skryptu mogę tylko sprawdzić, czy POSTem dostałem co chciałem. Reszta to konfiguracja serwera tj. php.in?

ZD
  • Rejestracja:około 3 lata
  • Ostatnio:ponad rok
  • Postów:2310
5
Szado napisał(a):

Zależy co tam w tym kodzie masz. Jeśli same definicje struktur (co polecam), to niczym się martwić nie musisz, bo po wejściu na taki plik nic się nie wyświetli jeśli serwer jest poprawnie skonfigurowany (jeśli nie jest, to nic Cię nie uratuje). Natomiast jeśli masz tam odpalany kod w globalu, to lepiej zabezpieczyć się na taką okoliczność. W starych CMS-ach robiło się to jednolinijkowcem sprawdzającym istnienie stałej: defined('IN_APP') or die('Access denied'); a w pliku nadrzędnym przed includem: const IN_APP = true;.

Za "moich czasów" (czyli "ach, ta dzisiejsza młodzież") to takie includowane / requirowane fragmenty PHP się po prostu umieszczało poza przestrzenią dostępną dla serwera http (o piętro krótsza ścieżka), w lżejszym przypadku w podkatalkogu, dla którego plik .htacces blokował dostęp sieciowy


If you put a million monkeys at a million keyboards, one of them will eventually write a Java program - the rest of them will write Perl
Zobacz pozostały 1 komentarz
jurek1980
I cały czas się tak robi, chociaż wiadomo frameworki rozwijają to podejście i dochodzi jeszcze autoloading
Szado
No zgadzam się, to co napisałem to metoda chałupnicza ale sprawdza się przy jakichś prostych, pojedynczych skryptach zagłębionych w strukturze katalogów.
cerrato
Jeśli się mylę to proszę o sprostowanie, ale jeśli masz w formularzu adres wysyłki w stylu form.php i ten skrypt dasz w katalogu odciętym od świata przez .htaccess to chyba nie da się wysłać formularza, bo skrypt go przetwarzający nie będzie w stanie się dobić do tego pliku. Czy jeszcze jest za wcześnie i kawa nie zaczęła u mnie działać? ;)
jurek1980
Chodzi o taką konstrukcję jak np. w Laravel czy Symfony @cerrato czyli mamy jakiś katalog publiczny i na niego kierujesz ruch i katalogi z kodem źródłowym do których z www bezpośrednio nie dobijesz się.
cerrato
No właśnie o to mi chodzi - jeśli tamte pliki z "ukrytych" folderów gdzieś includujesz, to spoko. Ale ja zrozumiałem, że padła porada w stylu jeśli nie chcesz, żeby ktoś odpalił bezpośrednio dany plik to go ukryj HTASSESS'em - tylko wtedy taki plik nie może być np. adresem wysyłki/przetworzenia formularza i ogólnie - nie możesz się do niego wprost odnieść, więc to taka średnia porada ;)
jurek1980
  • Rejestracja:ponad 8 lat
  • Ostatnio:około godziny
  • Postów:3462
0

W kwestii pokazania szczegółów kodu czy haseł tak. Chociaż widziałem cuda w kodzie gdzie ktoś jawnie pokazywał wrażliwe dane w ramach błędu, zapewne pozostawiając coś po procesie tworzenia kodu, a co nie powinno przejść review.

Riddle
Administrator
  • Rejestracja:prawie 15 lat
  • Ostatnio:4 minuty
  • Lokalizacja:Laska, z Polski
  • Postów:10056
4

@MrocznyRycerz Powinieneś to zrobić wielopoziomowo:

  • Po pierwsze, spodziewasz się że w Twoim $_POST jest konkretny zestaw kluczy, i jak widać oprogramowanie całkowicie nie jest przygotowane na obsłużenie tego że tych kluczy nie ma, że jest tylko ich pozdbiór, albo jest request inną metodą. Najpierw, powinieneś zacząć od tego żeby Twoje oprogramowanie umiało ohandlować taki przypadek: czyli np odpowiedzieć odpowiednim statusem błędu HTTP (np 400) lub 405, wysyłając odpowiedni header (np z przekierowaniem) albo wysyłając odpowiednie body (z komunikatem o brakujących polach). Błędy które widzisz, wynikają tylko i wyłacznie z tego ze nie obsłużyłeś jakiegoś przypadku. To powinieneś zrobić ASAP.
  • Po drugie, jeśli Twój widok w HTML strzela pod Twój plik PHP, to znaczy że ten plik PHP jest cześcią Twojego interfejsu, i nie ważne jak bardzo byś chciał go "zabezpieczyć", to do niego musi się być dać dostać przez HTTP, bo jak inaczej miałby działać Twój formularz. A skoro można się dostać przez HTTP, to nie za bardzo jesteś w stanie wymusić czy z przeglądarki, czy z formularza, czy z curla czy postmana czy jakiegokolwiek innego klienta HTTP ktoś trzela, także takie zabezpieczenia raczej nie mają sensu.
  • Po trzecie, u Ciebie jest wystawionych kilka plików .php, ale tylko pod jeden chcesz strzelać. Pisałem już w poprzednim temacie: Walidacja imienia i nazwiska dla pola tekstowego że to i tak trochę głupio robisz żę dzielisz to na pliki, bo w Twoim przypadku i tak wystarczyłby jeden. Ale jeśli koniecznie chcesz mieć kilka to powinieneś zrobić dwie rzeczy:
    • Po pierwsze, w tych plikach "ukrytych" nie powinieneś mieć kodu, a jedynie funkcje, czyli nawet jak ktoś odpali taki skrypt, to jedyne co zrobi to funkcje zostaną zadeklarowane, ale żaden kod się nie odpali.
    • Po drugie, dlaczego masz ustawiony server HTTP tak że odpala Ci każdy możliwy plik? powinieneś mieć whitelistę, że tylko plik dajmy index.php jest odpalany, a wszystkie inne pliki .php są niewidoczne, i mają zwracać 404, tak jakby ich nie było.

Co do odpowiedzi z CSRF, nie sądzę żeby to był dobry pomysł, bo to wymaga persystencji i pamiętania klucza, a z tym widać ze user ma problem. Raczej zacząłbym od dwóch punktów wyżej.

edytowany 3x, ostatnio: Riddle
MR
Po pierwsze, w tych plikach "ukrytych" nie powinieneś mieć kodu, a jedynie funkcje, czyli nawet jak ktoś odpali taki skrypt, to jedyne co zrobi to funkcje zostaną zadeklarowane, ale żaden kod się nie odpali. Apka docelowo będzie generować PDF, na którym ma być formułka RODO oraz jakiś inny "formalny tekst". Chciałem to zapisać w osobnym pliku (deklaracja stringa), by z całości skleić treść formularza.
MR
Czyli to również pasuje wydzielić podobnie jak deklaracja funkcji, bo nie ma "zagrożenia".
Riddle
@MrocznyRycerz: Pasowałoby, ale w mądry i odpowiedni sposób.
piotrpo
  • Rejestracja:ponad 7 lat
  • Ostatnio:4 dni
  • Postów:3277
3

Jak ktoś kumaty z dostateczną ilością wolnego czasu zobaczy to w kodzie twojej strony, to się przed tym nie zabezpieczysz . <- ta kropka jest wyboldowana, ale nie widać.

Podstawowa zasada pisania czegokolwiek po stronie serwera, to nie wolno ufać, że cokolwiek dostajesz od klienta/przeglądarki pochodzi z uprawnionej aplikacji/strony internetowej.

Jeżeli masz skrypt, który nie powinien być wywoływany z zewnątrz, to nie powinien być widoczny z zewnątrz. Udostępnianie przypadkowych endpointów to taka trochę masakra (nic osobistego, zwyczajne stwierdzenie faktu).

Jeżeli masz jakiś endpoint, który ma być widoczny z zewnątrz, jest widoczny z zewnątrz i powinien wymagać uwierzytelniania, bo robi coś ważnego (dajmy na to powoduje wykonanie przelewu...) to powinien zostać jakoś zabezpieczony przed atakami CSRF. Czym jest CSRF? Jesteś zalogowany do swojego banku i bank ci ufa. Na innej stronie (nawet nie lewej, wystarczy, że jest podatna na ataki XSS lub podobne) ktoś wstawia kawałek kodu, który wywołuje:

Kopiuj
POST https://twojbank.com
{
  "targetAccount":"numer konta atakującego",
  "amount":""
}

Ten kod wykona się w innej zakładce, ale w przeglądarce, do której jesteś zalogowany, zostaną więc dołożone wszystkie cookies, które powinny pójść pod ten adres.
Żeby temu zapobiec możesz wprowadzić jakiś tam typ tokenów anty-CSRF, czyli masz zabezpieczony endpoint, z którego pobierasz token, oraz sprawdzasz poprawność tego tokenu (tutaj nie zgadzam się z @Riddle, że trzeba ten token pamiętać, wystarczy, że jest się w stanie potwierdzić jego autentyczność).

Ps.
Ogólnie, to jestem trochę przerażony powszechną wśród programistów ignorancją w zakresie bezpieczeństwa. Szczególnie, że obecnie jakieś 99.999% aplikacji z tej łączności przez internet korzysta. I nie jest to przytyk pod kątem OP'a, bo ostatnio kandydat na stanowisko architekta nie był w stanie opowiedzieć czym jest XSS czy CSRF. Znaczy powiedział, że "są skanery, które sprawdzają kod pod kątem podatności na ataki".

MR
  • Rejestracja:ponad 2 lata
  • Ostatnio:około 2 lata
  • Postów:125
0

Pobawiłem się trochę Curlem i zauważyłem 2 rzeczy:

  • jeżeli odgadnę nazwy zmiennych w polach formularza (a to nie problem), które wysyłam POSTem, to za pomocą Curl (parametr -X POST) mój skrypt można uruchomić (spoko, htmlspecialchars na ratunek)
  • jeżeli wykonam komendę curl -v localhost/walidacja/sendForm.php to dostaję taką odpowiedź, a tymczasem powinno mnie przekierować na form.html z kodem 30x?
    screenshot-20221224224856.png
jurek1980
  • Rejestracja:ponad 8 lat
  • Ostatnio:około godziny
  • Postów:3462
1

Pokaż kod który przekierowuje. Ustawisz tam jakiś status 30X ?

MR
header("refresh:1; url=form.html");
ZD
  • Rejestracja:około 3 lata
  • Ostatnio:ponad rok
  • Postów:2310
1
MrocznyRycerz napisał(a):

Pobawiłem się trochę Curlem i zauważyłem 2 rzeczy:

  • jeżeli odgadnę nazwy zmiennych w polach formularza (a to nie problem), które wysyłam POSTem, to za pomocą Curl (parametr -X POST) mój skrypt można uruchomić (spoko, htmlspecialchars na ratunek)

Nie chwytam zwiazku logicznego jednego z drugim, pachnie jak magiczne uwielbienie htmlspecialchars (co jest dośc masowe)


If you put a million monkeys at a million keyboards, one of them will eventually write a Java program - the rest of them will write Perl
jurek1980
  • Rejestracja:ponad 8 lat
  • Ostatnio:około godziny
  • Postów:3462
1

Na temat odpowiadaj w postach.

header("refresh:1; url=form.html"); —

https://www.php.net/manual/en/function.header.php
Location żeby mieć 302. Lub podajesz response code jako parametr i taki trafi do przeglądarki.

edytowany 2x, ostatnio: jurek1980
MR
  • Rejestracja:ponad 2 lata
  • Ostatnio:około 2 lata
  • Postów:125
2

W sumie nic dziwnego, że poniższe daje kod 200:
header("refresh:1; url=form.html");
a to już 302:
header("Location: http://localhost/walidacja/form.html");

Riddle
Administrator
  • Rejestracja:prawie 15 lat
  • Ostatnio:4 minuty
  • Lokalizacja:Laska, z Polski
  • Postów:10056
3

Ogólnie, to to pytanie jest trochę odwrotne.

Jak masz serwer, z jakimiś plikami i skryptami, to one nie są domyślnie "otwarte", one są domyślnie zamknięte, do takiego servera nie może nic wejść samo z siebie, pewnie nawet żaden port nie jest otwarty. Tylko dopiero dodając jakieś głupie reguły, typu "jeśli ktoś strzeli pod .php to uruchom go jako CGI" to wtedy są takie cyrki, że można strzelić pod arbitralny plik i go wykonać.

Więc schemat wygląda tak:

  1. Miej bezpieczny server
  2. Postaw na nim server
  3. skonfiguruj server tak żeby pozwalał odpalać arbitralne pliki .php
  4. załóż post na forum z pytaniem "jak zabezpieczyć skrypty".

Oczywiście odpowiedź nasuwa się sama - wywal zasadę w serverze (tam apache czy nginx) która pozwala Ci odpalać randomowe pliku, i zmiast tego ustaw jakiś entry point, że tylko strzelajac po index.php się go wykonuje, a wszystkie inne są traktowane jako 404.

Kliknij, aby dodać treść...

Pomoc 1.18.8

Typografia

Edytor obsługuje składnie Markdown, w której pojedynczy akcent *kursywa* oraz _kursywa_ to pochylenie. Z kolei podwójny akcent **pogrubienie** oraz __pogrubienie__ to pogrubienie. Dodanie znaczników ~~strike~~ to przekreślenie.

Możesz dodać formatowanie komendami , , oraz .

Ponieważ dekoracja podkreślenia jest przeznaczona na linki, markdown nie zawiera specjalnej składni dla podkreślenia. Dlatego by dodać podkreślenie, użyj <u>underline</u>.

Komendy formatujące reagują na skróty klawiszowe: Ctrl+B, Ctrl+I, Ctrl+U oraz Ctrl+S.

Linki

By dodać link w edytorze użyj komendy lub użyj składni [title](link). URL umieszczony w linku lub nawet URL umieszczony bezpośrednio w tekście będzie aktywny i klikalny.

Jeżeli chcesz, możesz samodzielnie dodać link: <a href="link">title</a>.

Wewnętrzne odnośniki

Możesz umieścić odnośnik do wewnętrznej podstrony, używając następującej składni: [[Delphi/Kompendium]] lub [[Delphi/Kompendium|kliknij, aby przejść do kompendium]]. Odnośniki mogą prowadzić do Forum 4programmers.net lub np. do Kompendium.

Wspomnienia użytkowników

By wspomnieć użytkownika forum, wpisz w formularzu znak @. Zobaczysz okienko samouzupełniające nazwy użytkowników. Samouzupełnienie dobierze odpowiedni format wspomnienia, zależnie od tego czy w nazwie użytkownika znajduje się spacja.

Znaczniki HTML

Dozwolone jest używanie niektórych znaczników HTML: <a>, <b>, <i>, <kbd>, <del>, <strong>, <dfn>, <pre>, <blockquote>, <hr/>, <sub>, <sup> oraz <img/>.

Skróty klawiszowe

Dodaj kombinację klawiszy komendą notacji klawiszy lub skrótem klawiszowym Alt+K.

Reprezentuj kombinacje klawiszowe używając taga <kbd>. Oddziel od siebie klawisze znakiem plus, np <kbd>Alt+Tab</kbd>.

Indeks górny oraz dolny

Przykład: wpisując H<sub>2</sub>O i m<sup>2</sup> otrzymasz: H2O i m2.

Składnia Tex

By precyzyjnie wyrazić działanie matematyczne, użyj składni Tex.

<tex>arcctg(x) = argtan(\frac{1}{x}) = arcsin(\frac{1}{\sqrt{1+x^2}})</tex>

Kod źródłowy

Krótkie fragmenty kodu

Wszelkie jednolinijkowe instrukcje języka programowania powinny być zawarte pomiędzy obróconymi apostrofami: `kod instrukcji` lub ``console.log(`string`);``.

Kod wielolinijkowy

Dodaj fragment kodu komendą . Fragmenty kodu zajmujące całą lub więcej linijek powinny być umieszczone w wielolinijkowym fragmencie kodu. Znaczniki ``` lub ~~~ umożliwiają kolorowanie różnych języków programowania. Możemy nadać nazwę języka programowania używając auto-uzupełnienia, kod został pokolorowany używając konkretnych ustawień kolorowania składni:

```javascript
document.write('Hello World');
```

Możesz zaznaczyć również już wklejony kod w edytorze, i użyć komendy  by zamienić go w kod. Użyj kombinacji Ctrl+`, by dodać fragment kodu bez oznaczników języka.

Tabelki

Dodaj przykładową tabelkę używając komendy . Przykładowa tabelka składa się z dwóch kolumn, nagłówka i jednego wiersza.

Wygeneruj tabelkę na podstawie szablonu. Oddziel komórki separatorem ; lub |, a następnie zaznacz szablonu.

nazwisko;dziedzina;odkrycie
Pitagoras;mathematics;Pythagorean Theorem
Albert Einstein;physics;General Relativity
Marie Curie, Pierre Curie;chemistry;Radium, Polonium

Użyj komendy by zamienić zaznaczony szablon na tabelkę Markdown.

Lista uporządkowana i nieuporządkowana

Możliwe jest tworzenie listy numerowanych oraz wypunktowanych. Wystarczy, że pierwszym znakiem linii będzie * lub - dla listy nieuporządkowanej oraz 1. dla listy uporządkowanej.

Użyj komendy by dodać listę uporządkowaną.

1. Lista numerowana
2. Lista numerowana

Użyj komendy by dodać listę nieuporządkowaną.

* Lista wypunktowana
* Lista wypunktowana
** Lista wypunktowana (drugi poziom)

Składnia Markdown

Edytor obsługuje składnię Markdown, która składa się ze znaków specjalnych. Dostępne komendy, jak formatowanie , dodanie tabelki lub fragmentu kodu są w pewnym sensie świadome otaczającej jej składni, i postarają się unikać uszkodzenia jej.

Dla przykładu, używając tylko dostępnych komend, nie możemy dodać formatowania pogrubienia do kodu wielolinijkowego, albo dodać listy do tabelki - mogłoby to doprowadzić do uszkodzenia składni.

W pewnych odosobnionych przypadkach brak nowej linii przed elementami markdown również mógłby uszkodzić składnie, dlatego edytor dodaje brakujące nowe linie. Dla przykładu, dodanie formatowania pochylenia zaraz po tabelce, mogłoby zostać błędne zinterpretowane, więc edytor doda oddzielającą nową linię pomiędzy tabelką, a pochyleniem.

Skróty klawiszowe

Skróty formatujące, kiedy w edytorze znajduje się pojedynczy kursor, wstawiają sformatowany tekst przykładowy. Jeśli w edytorze znajduje się zaznaczenie (słowo, linijka, paragraf), wtedy zaznaczenie zostaje sformatowane.

  • Ctrl+B - dodaj pogrubienie lub pogrub zaznaczenie
  • Ctrl+I - dodaj pochylenie lub pochyl zaznaczenie
  • Ctrl+U - dodaj podkreślenie lub podkreśl zaznaczenie
  • Ctrl+S - dodaj przekreślenie lub przekreśl zaznaczenie

Notacja Klawiszy

  • Alt+K - dodaj notację klawiszy

Fragment kodu bez oznacznika

  • Alt+C - dodaj pusty fragment kodu

Skróty operujące na kodzie i linijkach:

  • Alt+L - zaznaczenie całej linii
  • Alt+, Alt+ - przeniesienie linijki w której znajduje się kursor w górę/dół.
  • Tab/⌘+] - dodaj wcięcie (wcięcie w prawo)
  • Shit+Tab/⌘+[ - usunięcie wcięcia (wycięcie w lewo)

Dodawanie postów:

  • Ctrl+Enter - dodaj post
  • ⌘+Enter - dodaj post (MacOS)