Italian jRdc2 + Db server - perche' mettere i comandi su file configurazione lato server?

amorosik

Expert
Licensed User
Sto giocando un po' col sistema jRdc2 consigliato da Erel per la connessione da dispositivo mobile a db coi dati
Non ho ben capito quale sia l'utilita' nel mettere i comandi sql sul file di configurazione del server b4j
A mio vedere sembra una complicazione perfettamente inutile
Tanto il client deve 'sapere' le colonne che arriveranno a seguito di una select e quindi non e' che si possa dire "..cosi' e' piu' facile perche' si puo' modifica SOLO il file di testo.."
Voglio dire, avessi fatto io un sistema simile, avrei composto il comando sql completo lato client, poi inviato il comando sul server B4j che lo avrebbe lanciato sul db server
E la risposta sarebbe poi stata restituita al client come gia' adesso avviene

E quindi la domanda e': quale utilita' vedete nel pre-comporre i comandi sql sul file config.properties lato B4j piuttosto che comporre il comando completo lato telefono/tablet e poi inviarlo al server B4j ?
 

LucaMs

Expert
Licensed User
Longtime User
Direi che il principale vantaggio riguardi la sicurezza.
Un client può chiamare l'esecuzione delle sole query predisposte sul server, mentre
piuttosto che comporre il comando completo lato telefono/tablet e poi inviarlo al server B4j ?
in quel modo potresti inviare un bel "DELETE FROM Tabella" e bonanotte. (<--- "u" volutamente non digitata 😁 )

Butta un occhio anche su:
https://it.wikipedia.org/wiki/Stored_procedure
 
Last edited:

amorosik

Expert
Licensed User
Direi che il principale vantaggio riguardi la sicurezza.
Un client può chiamare l'esecuzione delle sole query predisposte sul server, mentre

in quel modo potresti inviare un bel "DELETE FROM Tabella" e bonanotte. (<--- "u" volutamente non digitata 😁 )

Butta un occhio anche su:
https://it.wikipedia.org/wiki/Stored_procedure

Esatto, potrei da client inviare qualsiasi query, e questo mi sembra un pro non un contro
Le stored procedure sono una cosa un po' diversa, possono essere piu' complesse dell'unico enunciato sql e soprattutto sono piu' performanti in quanto gia' 'digerite' dal db server, in questo senso i comandi lato B4j del sistema jRdc non sono delle stored procedure poiche' il codice B4j le lancia da esterno db ogni volta
 

udg

Expert
Licensed User
Longtime User
i motivi per cui preferire un sistema rispetto ad un altro
Direi che questo sia il punto. Se desideri libertà (e responsabilità) al 100% puoi seguire la strada dell'accesso diretto al DB. Altrimenti un sistema come RDC/RDC2 isola il DB e quindi lo rende più sicuro.
L'accesso diretto è pericoloso perché, come tu potresti inviare qualunque comando autorizzato al DB, così potrebbe fare chiunque si prenda la briga di disassemblare il tuo sw. In più, potrebbe utilizzare quelle informazioni per prendere possesso del DB e tagliarti fuori.

Personalmente utilizzo un mio sistema molto simile a RDC, ma solo per ragioni "storiche"; nel senso che l'avevo costruito prima della nascita di RDC e poi ho continuato ad utilizzarlo. In realtà da tempo mi sono ripromesso di studiare RDC2 e poi man mano convertire i miei sw a quello, che presumo essere più sicuro/solido, ma non ho mai avuto tempo a sufficienza.

In conclusione, sono d'accordo con @LucaMs sul fatto che la sicurezza sia il motivo principale per scegliere RDC2, cui aggiungere la presumibile solidità di una soluzione proposta da Erel e il supporto della community.
 

Filippo

Expert
Licensed User
Longtime User
Direi che il principale vantaggio riguardi la sicurezza.
Un client può chiamare l'esecuzione delle sole query predisposte sul server, mentre

in quel modo potresti inviare un bel "DELETE FROM Tabella" e bonanotte. (<--- "u" volutamente non digitata 😁 )

Butta un occhio anche su:
https://it.wikipedia.org/wiki/Stored_procedure
Grazie per questo chiarimento, però non è giusto da parte tua!
Adesso non posso più dormire fino a che non cambio il mio metodo d'accesso al DB. :(
 

amorosik

Expert
Licensed User
Si, quello del craccare app, visto che mi par di capire si possa fare e senza tanti sforzi, e' un motivo valido per inserire un layer intermedio di protezione
E potendo evitare ruberie varie di dati e' effettivamente una cosa di primaria importanza
Resta il fatto che quando ho visto Erel rispondere su vari post al sistema jRdc rispetto al collegamento diretto a dati gestionale non mi e' sembrato usare queste motivazioni, tanto da indurmi a pensare che ci potessero essere altri motivi, di carattere puramente tecnico
 

Filippo

Expert
Licensed User
Longtime User
Ok, dopo una notata senza riuscire a dormire ho trovato non la Soluzione, ma una soluzione per me. :)
Il nuovo file PHP non offre una sicurezza del 100%, ma è sicuramente più sicuro del precedente.
Un'eventuale completta cancellazione di una tabella non è più facile.

Questa era il mio PHP-File:
B4X:
<?php
// Anfang
include("xxx/var.php");
// Ende

$conn = new mysqli($dbhost,$dbusername,$dbpassword,$dbname);
$query = file_get_contents("php://input");

if ($conn->connect_error)  {
    header("HTTP/1.1 500 Internal Server Error");
    echo $query.'\n';
    echo mysqli_error();
}
else
{
    $result = $conn->query($query);

    if (isset($_GET["select"]))
    {
        $rows = array();
        while($r = $result->fetch_assoc()) {
            $rows[] = $r;
        }
        print json_encode($rows);
    }
    elseif (isset($_GET["insert"]))
    {
        print $conn->insert_id;
    }
    else
    {
        print $sth;
    }
}
?>

e questo è ora:
B4X:
<?php
// Anfang
include("xxx/var.php");
// Ende

$conn = new mysqli($dbhost,$dbusername,$dbpassword,$dbname);
$query = file_get_contents("php://input");

if ($conn->connect_error)  {
    header("HTTP/1.1 500 Internal Server Error");
    echo $query.'\n';
    echo mysqli_error();
}
else
{
    if (isset($_GET["select"]) AND strpos($query,"SELECT ") >-1)
    {
        $result = $conn->query($query);
        $rows = array();
        while($r = $result->fetch_assoc()) {
            $rows[] = $r;
        }
        print json_encode($rows);
    }
    elseif (isset($_GET["insert"]) AND strpos($query,"INSERT ") >-1)
    {
        $result = $conn->query($query);
        print $conn->insert_id;
    }
    elseif (strpos($query,"DELETE ") >-1 OR (strpos($query,"UPDATE ") >-1))
    {
        if (strpos($query," WHERE ") >-1 AND (strpos($query,"=") >-1 ))
        {
            //". LIMIT 1" bewirkt das maximal 1 Datensatz gelöscht oder geändert werden kann.
            $result = $conn->query($query . " LIMIT 1");
            print $conn->affected_rows;
        }
        else
        {
            print "sql-command is wrong";
        }
    }
    else
    {
        print "sql-command not found";
    }
}
?>
 

udg

Expert
Licensed User
Longtime User
Un pizzico di protezione aggiuntiva lo puoi ottenere definendo sul DB un utente con diritti limitati.
Ad esempio che possa lavorare solo sul DB xxx e non su quello yyy
Oppure che sia abilitato alle SELECT ma non ai GRANT o altri operatori

In pratica lasci attivi solo gli operartori che sai che ti occorrono nella tua app e disabiliti tutti gli altri.
 

Filippo

Expert
Licensed User
Longtime User
Un pizzico di protezione aggiuntiva lo puoi ottenere definendo sul DB un utente con diritti limitati.
Ad esempio che possa lavorare solo sul DB xxx e non su quello yyy
Oppure che sia abilitato alle SELECT ma non ai GRANT o altri operatori

In pratica lasci attivi solo gli operartori che sai che ti occorrono nella tua app e disabiliti tutti gli altri.
La sola cosa che potrei fare è vietare il comando "Delete", tanto in nessuna delle mie App, che sono su Google-Play e Apple-Store, viene usato.
Quindi potrei creare un nuovo user, che sarei io, con il diritto "Delete".
Grazie per l'idea Umberto!
 

Filippo

Expert
Licensed User
Longtime User
Ho fatto in modo che il comando "DELETE" non si possa più usare.
Penso che ora sia ancora più sicura, cosa ne pensate?
B4X:
<?php
// Anfang
include("xxx/var.php");
// Ende

$conn = new mysqli($dbhost,$dbusername,$dbpassword,$dbname);
$query = file_get_contents("php://input");

if ($conn->connect_error)  {
    header("HTTP/1.1 500 Internal Server Error");
    echo $query.'\n';
    echo mysqli_error();
}
else
{
    if (isset($_GET["select"]) AND strpos($query,"SELECT ") == 0)
    {
        $result = $conn->query($query);
        $rows = array();
        while($r = $result->fetch_assoc()) {
            $rows[] = $r;
        }
        print json_encode($rows);
    }
    elseif (isset($_GET["insert"]) AND strpos($query,"INSERT ") == 0)
    {
        $result = $conn->query($query);
        print $conn->insert_id;
    }
    elseif (strpos($query,"UPDATE ") == 0)
    {
        if (strpos($query," WHERE ") >-1 AND (strpos($query,"=") >-1 ))
        {
            //". LIMIT 1" causes that a maximum of 1 record can be deleted or changed.
            $result = $conn->query($query . " LIMIT 1");
            print $conn->affected_rows;
        }
        else
        {
            print "sql-command is wrong";
        }
    }
    else
    {
        print "sql-command not found";
    }
}
?>
 
Top