As part of a project I need to retrieve personal user information from a Teradata table.
To preserve user privacy we need to have access only on the sha256 hash of the values.
Would it be possible in Teradata to hash the value directly in the query?
I tried:
SELECT sha256(login_email) as sha_login_email
FROM tablex;
but the function sha256(binary) doesn't work with Strings.
I get an error: The string contains an untranslatable character.
whichever string is processed by the query.
Related
I'm writing an R Shiny/SQLite app. In the app, I have a function that returns a column from one of the tables in my SQLite database, with the function taking the table name as an input.
Before sending the query to SQLite, the function checks that the table name equals one of the table names that the user is allowed to access. However, I am not using a parameterized query, because the term I'm changing is not a variable used for comparison but the name of the table to extract information from. (There might be a way to make this work anyway with a parameterized search, I suppose.)
My question is whether this is safe from an SQL injection? Can the query be altered on its way from the server to the database, or only from an alteration in the ui input to the server?
(Bear with me, I am new to SQLite.)
Assuming your query is being concatenated as follows:
tbl <- "yourTable"
sql <- paste0("select * from ", tbl, " where some_col = 1")
Then there should be no chance of SQL injection, assuming you check the incoming table name and verify that it matches a table name in your whitelist. Note that this step is critical here to keeping things safe. Let's say that you didn't sterilize the incoming table name. Then, consider this:
tbl <- "yourTable; delete from yourTable"
This would result in the following query being submitted for execution:
select * from yourTable; delete from yourTable where some_col = 1;
Assuming your SQLite driver allows multiple SQL statements to execute, the above hack/trick might end up deleting data from a large portion of one of your tables.
So, your approach should be safe provided that you check the table name. Note that strictly speaking the table name itself is not a parameter in a parameterized query. Rather, only the literal values in the query are parameters.
SQL query parameters cannot be used in place of a table name anyway, so comparing the table name to a list of known authorized tables is your only option.
Yes, it is safe. If you're in control of the set of values that can be interpolated into the SQL query, then you can prevent unauthorized SQL injection.
Note that some other elements of SQL queries cannot be parameters:
Any identifier, e.g. a table name, column name, or schema name.
Expressions
Lists of values in an IN ( ... ) predicate. Use one parameter per value in the list.
SQL keywords.
A query parameter can be used only in place of a single scalar value. That is, where you would use a quoted string literal, quoted date literal, or numeric literal.
The problem of SQL injection is only the user input. Nothing happens to the query on its way from the server to the database (well a malware could in theory alter it, but then even a parametrized query wouldn't help).
I.e., if you create a SQL string like this (C#):
sql = "SELECT * FROM " + tableName;
Then a user might enter a tableName like
MyTable; DROP TABLE MyTable
Guess what happens.
So, if you check the table name, you are on the safe side.
In a React Native App I'm attempting to insert data into a local sqlite db
let submissionID = "1-2-3";
this.dbQuery("INSERT INTO Submissions (ID, Data) VALUES("+submissionID+",'Test')");
(dbQuery is the name of a function I made to simplify my queries but the statement inside it should be the same)
If I viewed the Submissions table after this insert statement I would expect to see a row with [ID:"1-2-3",Data:"Test"] but instead I see [ID:"-4",Data:"Test"]
I created the table like so
CREATE TABLE IF NOT EXISTS Submissions(ID BLOB PRIMARY KEY NOT NULL, Data BLOB NOT NULL)
I used Blob because I read "The value is a blob of data, stored exactly as it was input." but I've also tried Text. I've also casted submissionID as a string like so
this.dbQuery("INSERT INTO Submissions (ID, Data) VALUES("+String(submissionID)+",'Test')");
But none of that worked. I do see here how sqlite takes advantage of arithmetic operators
https://www.w3resource.com/sqlite/arithmetic-operators.php
but I'm not sure how to stop it from doing so.
How would I get sqlite to treat my hyphens as hyphens instead of subtraction signs?
What you're doing is the equivalent of:
this.dbQuery("INSERT INTO Submissions (ID, Data) VALUES(1-2-3,'Test')");
passing the numeric expression 1-2-3 to the INSERT statement. The simplest fix is to quote the string literal.
let submissionID = "1-2-3";
this.dbQuery("INSERT INTO Submissions (ID, Data) VALUES('"+submissionID+"','Test')");
However, to guard against SQL injection attacks, you really ought to be using prepared statements instead of using string concatenation to build SQL statements.
Enclose the string in single quotes i.e.
this.dbQuery("INSERT INTO Submissions (ID, Data) VALUES('"+String(submissionID)+"','Test')");
Thus the value is treated as a literal by SQLite, without enclosing the value it will either be treated as a numeric value or as an identifier (column, table, trigger, view depending upon where it is coded and thus what the parser expects).
The data type (column affinity) has little bearing other than if you specified ID INTEGER PRIMARY KEY, then you could not store anything other than an integer. As ID INTEGER PRIMARY key has a special interpretation that is the column is an alias of the rowid.
I used Blob because I read "The value is a blob of data, stored
exactly as it was input." but I've also tried Text. I've also casted
submissionID as a string like so
That is only if the value to be inserted is a BLOB byte[] or in the case of raw SQL x'FF01FE02', otherwise SQLite will store the value according to how it interprets the type should be stored.
Actual variable is Long but while saving it to Firestore I accidentally converted it to String, now I cannot perform queries like whereGreaterThan, whereLessThan, orderBy etc on this String field
There isn't a way to magically change the data type. The easiest way will be to re-write all the documents that were saved as a string.
You could use something like the Python server libraries to do this, using Cloud Shell in the GCP Console.
Note, you can grab all the documents with the field set to a string by doing a filter for >= "". This will get you every field that has a string with any value, as well as empty strings.
I am creating a table in SQLite Database which will only store a single data, else if data exists in the table, it should be deleted before inserting a new data.
This is the syntax i used to create the table
CREATE TABLE my_login_info (
id BOOLEAN PRIMARY KEY
DEFAULT True
CONSTRAINT one_row_only CHECK (id)
NOT NULL,
username STRING,
password STRING
);
however when i am trying to insert the data to the table while the table is empty, it gave an error.
Error while committing new row: CHECK constraint failed: one_row_only
Any idea what is the caused the problem?
You can use INSERT OR REPLACE to insert a new record or update the existing one that matches the key field, eg:
INSERT OR REPLACE INTO my_login_info (id,username,hash)
VALUES (true,someuser,somehash)
Just make sure you don't store the password as cleartext. Only store a strong hash. If you don't need the hash for authentication, you could get away with storing a short hash, ie only part of the full hash.
That's what git does for example, when it displays a short hash for each file version instead of the full hash
I need to programatically determine what the primary key field(s) are for a given sqlite table (using sqlite api, not command line).
I can get a list of tables and a list of columns, but only see the column type using the Column_Type() function. Need to know if a given column is the primary key (or part of the primary key if a compound key is used).
Have a look at sqlite3_table_column_metadata:
This routine returns metadata about a specific column of a specific
database table accessible using the database connection handle passed
as the first function argument.