Mam tabeli test(id,name)
.
Muszę wstawić wartości jak: user's log
, 'my user'
, customer's
.
insert into test values (1,'user's log');
insert into test values (2,''my users'');
insert into test values (3,'customer's');
Otrzymuję błąd, jeśli uruchomię dowolną z powyższych instrukcji.
Jeśli istnieje jakakolwiek metoda, aby to zrobić poprawnie, udostępnij. Nie chcę żadnych przygotowanych oświadczeń.
Czy jest to możliwe przy użyciu mechanizmu ucieczki SQL?
Odpowiedzi:
Literały łańcuchowe
Unikanie pojedynczych cytatów
'
poprzez ich podwojenie ->''
jest standardowym sposobem i działa oczywiście:W starych wersjach lub jeśli nadal działasz z
standard_conforming_strings = off
lub, generalnie, jeśli poprzedzasz swój ciąg znaków,E
aby zadeklarować składnię łańcucha ucieczki Posix , możesz również uciec za pomocą odwrotnego ukośnika\
:Sam odwrotny ukośnik jest poprzedzany innym odwrotnym ukośnikiem. Ale generalnie nie jest to preferowane.
Jeśli masz do czynienia z wieloma pojedynczymi cudzysłowami lub wieloma warstwami ucieczki, możesz uniknąć cytowania piekła w PostgreSQL za pomocą ciągów cytowanych w dolarach :
Aby dodatkowo uniknąć pomyłek w notowaniach dolara, dodaj unikalny token do każdej pary:
Które mogą być zagnieżdżone na dowolnej liczbie poziomów:
Zwróć uwagę, jeśli
$
postać powinna mieć specjalne znaczenie w oprogramowaniu klienckim. Dodatkowo może być konieczne ucieczka. Nie dotyczy to standardowych klientów PostgreSQL, takich jak psql lub pgAdmin.Wszystko to jest bardzo przydatne do pisania funkcji plpgsql lub ad-hoc poleceń SQL. Nie może jednak zmniejszyć potrzeby użycia przygotowanych instrukcji lub innej metody w celu zabezpieczenia przed wstrzyknięciem SQL w aplikacji, gdy możliwe jest wprowadzanie danych przez użytkownika. Odpowiedź @ Craiga zawiera więcej informacji na ten temat. Więcej szczegółów:
Wartości w Postgres
Gdy mamy do czynienia z wartościami w bazie danych, istnieje kilka przydatnych funkcji do prawidłowego cytowania ciągów:
quote_literal()
lubquote_nullable()
- ta ostatnia wyprowadza ciąg znakówNULL
dla wejścia zerowego. (Jest teżquote_ident()
do podwójnego cytując strun gdzie potrzebne do uzyskania prawidłowych SQL identyfikatory ).format()
ze specyfikatorem formatu%L
odpowiadaquote_nullable()
.Lubić:
format('%L', string_var)
lubconcat()
zazwyczaj nie są dobre, ponieważ nie unikają zagnieżdżonych pojedynczych cudzysłowów i odwrotnych ukośników.concat_ws()
źródło
SELECT $outer$OUT$inner$INNER$inner$ER$outer$;
dowodzi, że zagnieżdżanie drugiego poziomu nie działa tutaj.Jest tak wiele złych światów, ponieważ twoje pytanie sugeruje, że prawdopodobnie masz luki w aplikacjach SQL .
Powinieneś używać sparametryzowanych instrukcji. W przypadku języka Java należy używać
PreparedStatement
symboli zastępczych . Mówisz, że nie chcesz używać sparametryzowanych instrukcji, ale nie wyjaśniasz dlaczego , i szczerze mówiąc, musi to być bardzo dobry powód, aby ich nie używać, ponieważ są one najprostszym i najbezpieczniejszym sposobem rozwiązania problemu, który próbujesz rozwiązać rozwiązać.Zobacz Zapobieganie wstrzykiwaniu SQL w Javie . Nie bądź Bobby kolejną ofiarą .
W PgJDBC nie ma funkcji publicznej do cytowania ciągów i zmiany znaczenia. Po części dlatego, że może to wydawać się dobrym pomysłem.
Tam są wbudowane w cytując funkcje
quote_literal
iquote_ident
w PostgreSQL, ale są zaPL/PgSQL
jego pomocą funkcjiEXECUTE
. Te dniquote_literal
są w większości przestarzałeEXECUTE ... USING
, ponieważ jest to sparametryzowana wersja , ponieważ jest bezpieczniejsza i łatwiejsza . Nie możesz ich użyć do celów, które tu wyjaśnisz, ponieważ są to funkcje po stronie serwera.Wyobraź sobie, co się stanie, jeśli otrzymasz wartość
');DROP SCHEMA public;--
od złośliwego użytkownika. Wyprodukowalibyście:który dzieli się na dwie instrukcje i komentarz, który jest ignorowany:
Ups, tam idzie twoja baza danych.
źródło
= ANY(?)
i parametr tablicy.database is accessed by java
więc to bezpośrednio odnosi się do pytania. Bardzo ważne jest również, aby ludzie przybywający tutaj byli świadomi potencjalnych zagrożeń, szczególnie biorąc pod uwagę, że SQL Injection jest najczęstszą przyczyną podatności oprogramowania. Po zapoznaniu się z problemem ludzie mogą podejmować świadome decyzje, kiedy nie ma to znaczenia, na przykład przypadek użycia ładowania początkowego.Zgodnie z dokumentacją PostgreSQL (4.1.2.1. Stałe łańcuchowe) :
Zobacz także parametr standard_conforming_strings , który kontroluje, czy działa ucieczka z ukośnikami odwrotnymi.
źródło
W postgresql, jeśli chcesz wstawić wartości z
'
nim, to musisz podać dodatkowe'
źródło
możesz użyć funkcji chr (int) postrgesql:
źródło
Jeśli musisz wykonać pracę w Pg:
to_json(value)
https://www.postgresql.org/docs/9.3/static/functions-json.html#FUNCTIONS-JSON-TABLE
źródło
format()
,quote_literal()
lubquote_nullable()
do ucieczki cytaty. Zobacz: stackoverflow.com/a/25143945/939860źródło
user's log
zamiastabc
prawidłowego podania . Catch 22.