AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / dba / Perguntas / 78353
Accepted
beldaz
beldaz
Asked: 2014-10-04 14:31:46 +0800 CST2014-10-04 14:31:46 +0800 CST 2014-10-04 14:31:46 +0800 CST

DEFINIR PAPEL via consulta parametrizada

  • 772

Na resposta muito útil que recebi para uma pergunta anterior , estou tentando escrever algum código JDBC que primeiro defina a função para um usuário específico antes de executar consultas subsequentes. Por segurança, gostaria de evitar ataques de injeção de SQL parametrizando a SET ROLEinstrução. Minha abordagem no Groovy (que usa JDBC) foi:

def sql = Sql.newInstance('jdbc:postgresql:mydb', 'mydbweb', 'mydbwebpass', 'org.postgresql.Driver')
sql.execute 'SET ROLE ?', user

mas isso gera um erro de sintaxe. A documentação diz que SET ROLEpode levar uma string literal, mas não estou claro como posso passá-la validamente. Alguma sugestão?

postgresql jdbc
  • 3 3 respostas
  • 2211 Views

3 respostas

  • Voted
  1. Best Answer
    Craig Ringer
    2014-10-05T23:04:07+08:002014-10-05T23:04:07+08:00

    Com base em um caso de teste simples que acabei de escrever:

    @Test
    public void test() throws SQLException {
        PreparedStatement ps = conn.prepareStatement("SET ROLE ?");
        ps.setString(1, "someuser");
        ps.executeUpdate();
    }
    

    Eu acho que o erro que você se refere é provavelmente:

    org.postgresql.util.PSQLException: ERROR: syntax error at or near "$1"
      Position: 10
        at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2245)
        at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1974)
        at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:254)
        at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:565)
        at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:420)
        at org.postgresql.jdbc2.AbstractJdbc2Statement.executeUpdate(AbstractJdbc2Statement.java:366)
        ....
    

    A razão para isso é que o protocolo do PostgreSQL só pode vincular parâmetros de posicionamento para instruções "planejáveis", que são SELECT, INSERT, UPDATEe DELETEalgumas outras. Para esses tipos de instrução, ele suporta apenas parâmetros de posicionamento para valores literais, não para identificadores ou outros elementos de sintaxe.

    Para outros tipos de instrução, os literais devem ser substituídos pelo cliente. Alguns drivers oferecem suporte à emulação do lado do cliente para preparar essas instruções, portanto, eles parecem funcionar de forma transparente, mas o PgJDBC atualmente não oferece suporte a isso.

    Na verdade, o PgJDBC oferece suporte à vinculação de parâmetros do lado do cliente se você estiver usando o protocolo legado v2, mas não expõe essa funcionalidade para conexões no protocolo v3. Mesmo se você não estiver usando instruções preparadas do lado do servidor, ele ainda usará a ligação de parâmetro do lado do servidor. Forçar o protocolo v2 funcionará, mas é uma solução ruim com muitas outras consequências em outros lugares - além disso, em algum momento, o PostgreSQL abandonará totalmente o suporte para o protocolo v2.

    Eu acho que isso é um problema com o driver e/ou protocolo de fio do PostgreSQL. O usuário não deve se preocupar se o servidor suporta vinculação de parâmetros para algumas instruções e não para outras, o driver deve cuidar disso - ou melhor, o servidor deve apenas suportá-lo para todos os tipos de instrução.

    Infelizmente, o PgJDBC também não expõe suas implementações internas de identificador seguro e escape literal para uso do aplicativo cliente. Se standard_conforming_stringsestiver ativado, porém, a regra é muito simples:

    • Substitua cada 'por ''; e
    • Envolva tudo entre aspas simples

    O mesmo se aplica aos identificadores, com aspas duplas.

    • 4
  2. hbn
    2014-10-05T14:25:41+08:002014-10-05T14:25:41+08:00

    Você pode criar uma função que executa SET ROLEcom SQL dinâmico, usando format para inserir com segurança o identificador de função ( %Iinsere um identificador, colocando aspas duplas em torno dele, se necessário, e escapando aspas duplas na string, dobrando-as, se necessário). Algo na linha de

    CREATE FUNCTION setrole(role text) RETURNS void AS $$ BEGIN EXECUTE format('SET ROLE %I', role); END $$ LANGUAGE plpgsql;
    

    Você pode então executar essa função com algo como SELECT setrole(?). Isso deve funcionar bem com os parâmetros.

    Aqui está um exemplo dele em uso em psql:

    > show role;
       role
    -----------
     testuser1
    (1 row)
    
    > SELECT setrole('testuser2');
     setrole
    ---------
    
    (1 row)
    
    > show role;
       role
    -----------
     testuser2
    (1 row)
    
    • 2
  3. Sergey
    2020-08-06T20:41:47+08:002020-08-06T20:41:47+08:00

    Tanto quanto pude testar com , SET ROLE role_nametambém pode ser obtido usando uma função set_config, por exemplo SELECT set_config('role', 'role_name', TRUE), e desta forma os parâmetros podem ser usados: SELECT set_config($1, $2, TRUE).

    Há também uma nota na documentação do Postgres que set_configfornece a mesma funcionalidade SET(mas mesmo que ROLEnão seja mencionada lá, ainda funcionou para mim).

    Versão do PostgreSQL: PostgreSQL 12.2 em x86_64-pc-linux-musl, compilado por gcc (Alpine 9.2.0) 9.2.0, 64 bits

    • 0

relate perguntas

  • Posso ativar o PITR depois que o banco de dados foi usado

  • Práticas recomendadas para executar a replicação atrasada do deslocamento de tempo

  • Os procedimentos armazenados impedem a injeção de SQL?

  • Sequências Biológicas do UniProt no PostgreSQL

  • Qual é a diferença entre a replicação do PostgreSQL 9.0 e o Slony-I?

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host

    • 12 respostas
  • Marko Smith

    Como fazer a saída do sqlplus aparecer em uma linha?

    • 3 respostas
  • Marko Smith

    Selecione qual tem data máxima ou data mais recente

    • 3 respostas
  • Marko Smith

    Como faço para listar todos os esquemas no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Listar todas as colunas de uma tabela especificada

    • 5 respostas
  • Marko Smith

    Como usar o sqlplus para se conectar a um banco de dados Oracle localizado em outro host sem modificar meu próprio tnsnames.ora

    • 4 respostas
  • Marko Smith

    Como você mysqldump tabela (s) específica (s)?

    • 4 respostas
  • Marko Smith

    Listar os privilégios do banco de dados usando o psql

    • 10 respostas
  • Marko Smith

    Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Como faço para listar todos os bancos de dados e tabelas usando o psql?

    • 7 respostas
  • Martin Hope
    Jin conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane Como faço para listar todos os esquemas no PostgreSQL? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh Por que o log de transações continua crescendo ou fica sem espaço? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland Listar todas as colunas de uma tabela especificada 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney O MySQL pode realizar consultas razoavelmente em bilhões de linhas? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx Como posso monitorar o andamento de uma importação de um arquivo .sql grande? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison Como você mysqldump tabela (s) específica (s)? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas Como posso cronometrar consultas SQL usando psql? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas Como faço para listar todos os bancos de dados e tabelas usando o psql? 2011-02-18 00:45:49 +0800 CST

Hot tag

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve