Flex & MySQL: Escaping in Order to Prevent SQL Injection - flex3

I'm using Zend AMF remoting in a Flex 3 project. How do I ensure that the parameters that my Flex app sends to my php doesn't result in SQL Injection or other security problems.
How do I make the $parameterArray safe? It's an array of string and numeric values. How do I use mysql_real_escape_string with $parameterArray? Also do I need to use htmlspecialchars? How do I use it in this case? Anything else I need to do to make it safe?
PHP:
class MyData {
public function getCrimeGradeData($parameterArray) {
$type = $parameterArray[0];
$latmax = $parameterArray[1];
$latmin = $parameterArray[2];
$lngmax = $parameterArray[3];
$lngmin = $parameterArray[4];
$startDateTime = $parameterArray[5];
$endDateTime = $parameterArray[6];
$query = "SELECT reportdatetime, type, latitude, longitude FROM table WHERE latitude < $latmax AND latitude > $latmin AND longitude < $lngmax AND longitude > $lngmin AND type = '$type' AND reportdatetime BETWEEN '$startDateTime' AND '$endDateTime'";
cont...

go here and have a look

Related

Does r2dbc repository support dynamic SQL conjecture?

I was migrating traditional JPA based project to reactive Project, which was based on r2dbc.
There have many dynamics SQL conjecture in our project before, like if user pass parameter exchange value as CME,we will add "and exchange='CME'" at the end of SQL and run it by JDBCTemplate:
List<Object> parameters = new ArrayList<>();
String sql = QUERY_BrokerIDs_Old;
sql += " and exchange = ?";
parameters.add(exchange);
if (!StringUtils.isEmpty(filter)) {
sql += " and memberID like ?";
parameters.add("%" + filter.trim().toUpperCase() + "%");
}
sql += " order by id";
if (page > 0 && pageSize > 0) {
int offset = (page - 1) * pageSize;
String pageClause = PAGE_CLAUSE;
sql += pageClause;
parameters.add(offset);
parameters.add(pageSize);
}
return jdbcTemplate.queryForList(sql, parameters.toArray(), String.class);
I found r2dbc repository provide multiple convient methods, like findAll, getXxxByXxx,I really like it. And we also can declare the SQL in #Query like:
#Query("SELECT * FROM person WHERE lastname = :lastname")
Flux<Person> findByLastname(String lastname);
But does it support dynamic parameter as query conditions in its repository class? Or I can do some customize on it to implement it?
Otherwise I only can implement it by SQL conjecture and run it by template, like the old way before…

Interpolated strings in F#

I am trying to use the Entity Framework Core interpolated SQL query function in F# which requires a FormattableString. However to my surprise it doesn't function as I cannot find a way to convert a regular F# string to that type. I figured just doing what you do in C# would work but it doesn't. Here is the code I currently have:
let fromDbUser (u : Entity.User) =
{
name = u.Name
age = u.Age
phone = u.Phone
}
let mname = "Foo"
let ctx = new Entity.DatabaseContext()
ctx.User.FromSqlInterpolated($"Select * FROM User Where name = {mname};")
|> Seq.map(fromDbUser)
|> printfn "%A"
Running that block of code yields a compile error:
This token is reserved for future use
I have been trying to google around but I was unable to find any way to get this to work, any help would be most appreciated!
When this was asked, F# didn't have string interpolation.
Today though, there is an RFC for it that is merged in in F# 5.0 allowing string interpolation in F#.
The error was because the $ symbol is reserved (for 6 years+ as of writing), and will probably be used for string interpolation when it is added.
As Dave pointed out, interpolation isn't implemented yet.
But for methods that absolutely require an FormattableString or an IFormattable, you can use FormattableStringFactory.Create
let query (sql: FormattableString) =
printfn "%s" (sql.ToString(null, null))
let mname = "Foo"
let fstr = FormattableStringFactory.Create("Select * FROM User Where name = {0};", mname)
query fstr
It's available from F# 5.0.
> let mname = "Foo" ;;
val mname : string = "Foo"
> let str = $"Select * FROM User Where name = {mname};" ;;
val str : string = "Select * FROM User Where name = Foo;"
Check this out. https://learn.microsoft.com/en-us/dotnet/fsharp/whats-new/fsharp-50#string-interpolation

How to set large string as param without getting ORA-01460: unimplemented or unreasonable conversion error?

In spring-boot using namedParameterJdbcTemplate (Oracle db version 12 and odbc8 driver 12.2)
I am getting the following error while executing a SELECT query bound with a parameter larger than 4000 character whereas update queries working fine.
ORA-01460: unimplemented or unreasonable conversion requested
The unit test I am trying to execute;
#Test
public void testSqlSelectQueryLargeStringParameter() {
MapSqlParameterSource params = new MapSqlParameterSource();
params.addValue("param", theLargeStr);
// #formatter:off
String sql =
"SELECT NULL id, NULL text FROM DUAL WHERE 'X' != :param ";
// #formatter:on
namedParameterJdbcTemplate.queryForRowSet(sql, params);
}
Is there any way to set this large param via MapSqlParameterSource?
I am #ahmet-orhan 's colleague, we've found a solution.
Thanks #kfinity for your suggestion, It is working for insert and update but we are still getting this error when we set clob or blob as "paremeter" in select statements.
If using a driver that supports JDBC4.0, the right solution is create a DefaultLobHandler and set streamAsLob or createTemporaryLob to true.
MapSqlParameterSource params = new MapSqlParameterSource();
String myString = "";
for (int i = 0; i < MAX_CLOB_BLOB_SIZE_IN_SELECT; i++) {
myString = myString + "1";
}
DefaultLobHandler lobHandler = new DefaultLobHandler();
lobHandler.setStreamAsLob(true);
params.addValue("param", new SqlLobValue(myString, lobHandler), Types.CLOB);
// #formatter:off
String sql =
"SELECT 1 id FROM DUAL WHERE :param IS NOT NULL ";
// #formatter:on
Integer id = namedParameterJdbcTemplate.queryForObject(sql, params, Integer.class);
We prefer streamAsLob but to be honest we have no idea which one is better.
This comment points out that ORA-01460 in JDBC queries is the same as "ORA-01704: string literal too long". (You can't have string literals longer than 4000 characters.) Maybe try this solution?
params.addValue("param", theLargeStr, Types.CLOB);
Although also != won't work for clob comparison, so you'll also need to change your query to
SELECT NULL id, NULL text FROM DUAL WHERE dbms_lob.compare('X',:param) != 0

ResultSet coming as empty after executing query

I have a query
SELECT instance_guid FROM service_instances WHERE service_template_guid='E578F99360A86E4EE043C28DE50A1D84' AND service_family_name='TEST'
Directly executing this returns me
4FEFDE7671A760A8DC8FC63CFBFC8316
F2F9DF641D8E2CACC03175A7A628D51D
Now I am trying same code from JDBC.
PreparedStatement ps = null;
ResultSet rs = null;
try {
conn = executionContext.getConnection();
if (conn != null) {
ps = (PreparedStatement)conn.prepareStatement(query);
if (params == null) params = new Object[0];
for (int i=0;i<params.length;i++) {
if (params[i] instanceof Integer) {
ps.setInt(i+1, ((Integer)params[i]).intValue());
} else if (params[i] instanceof java.util.Date) {
((PreparedStatement)ps).setDATE(i+1, new oracle.sql.DATE((new java.sql.Timestamp(((Date)params[i]).getTime()))));
//ps.setObject(i+1, new oracle.sql.DATE(new Time(((Date)params[i]).getTime())));
} else {
if (params[i] == null) params[i] = "";
ps.setString(i+1, params[i].toString());
}
}
rs = ps.executeQuery();
I see params[0] =E578F99360A86E4EE043C28DE50A1D84 and params[1]=TEST
But the resultSet is empty and not getting the result.I debugged but not much help?
Can you please let me know Am i trying right?
In java its defined as below
final static private String INSTANCE_GUID_BY_TEMPLATE_GUID =
"SELECT instance_guid FROM service_instances WHERE service_template_guid=? AND service_family_name=? "
SERVICE_FAMILY_NAME NOT NULL VARCHAR2(256)
SERVICE_TEMPLATE_GUID NOT NULL RAW(16 BYTE)
First and foremost this breaks every sql mapping pattern I have ever seen.
String sql = "SELECT instance_guid FROM service_instances WHERE service_template_guid=? AND service_family_name=?";
PreparedStatement ps = null;
ResultSet rs = null;
try {
conn = executionContext.getConnection();
ps = conn.prepareStatement(sql);
ps.setString(1,guid);
ps.setString(2,family);
rs = ps.executeQuery();
while(rs.next(){...}
...
}
You should not be dynamically figuring out the data types as they come in, unless you are trying to write some code to port from database X to database Y.
UPDATE
I see you are using RAW as a datatype, from this post:
As described in the Oracle JDBC Developer's guide and reference 11g,
when using a RAW column, you can treat it as a BINARY or VARBINARY
JDBC type, which means you can use the JDBC standard methods
getBytes() and setBytes() which returns or accepts a byte[]. The other
options is to use the Oracle driver specific extensions getRAW() and
setRAW() which return or accept a oracle.sql.RAW. Using these two will
require you to unwrap and/or cast to the specific Oracle
implementation class.
Further from a code readability standpoint, your solution makes it painful for a new developer to take over. Far too often I see people making sql be "dynamic" when in reality 99% of the time you don't need this level of dynamic query building. It sounds good in most people's heads but it just causes pain and suffering in the SDLC.

What’s the Linq to SQL equivalent to CEILING?

How do I do this
SELECT CEILING(COUNT(*) / 10) NumberOfPages
FROM MyTable
in Linq to SQL?
Many .NET methods are translated to SQL Server functions, such as most of the methods of the Math class and the String class. But there are some caveats.
Also have a look at the SqlMethods class, which exposes additional SQL Server function that doesn't have a .NET equivalent.
But you don't even need any of that in your case:
int numberOfPages;
using (var db = new MyDBDataContext())
{
numberOfPages = (int)Math.Ceiling(db.Books.Count() / 10.0);
}
You dont use SQL CEILING, you use .NET ceiling (Math.Ceiling) in your LINQ query.
I don't think this is possible.
A possible solution would be to get the total count and then figure it out in .NET code.
Like below:
where query is IQueryable
var itemsPerPage = 10;
var currentPage = 0;
var totalResults = query.Count();
var myPagedResults = query.Skip(currentPage).Take(itemsPerPage);
var totalPages = (int)Math.Ceiling((double)totalResults / (double)pageSize);