Codeigniter Active record SQL injection - codeigniter

Is below query vulnerable to SQL Injection where $evilInput is from get/post request.
$this->db->select($evilInput);
$this->db->where($evilInput2 ,"abc");
$query = $this->db->get($evilInput3);
$count = $query->num_rows();
and
$this->db->where("a=$evilInput");

I'd like to point out that all these are vulnerable to SQL injection on a default installation of CodeIgniter. The following results have been tested and verified.
1) $this->db->select($evilInput)
Here the input goes after the select keyword.
select evilInput from table_name where column_name = 1;
Here, if my evil input parameter contains something like:
updatexml(null,concat(0x3a,version()),null)-- -
The actual query will become:
select updatexml(null,concat(0x3a,version()),null)-- - from table_name where column_name = 1;
2) $this->db->where($evilInput ,"abc")
Here the input goes to the column name after WHERE clause.
select * from table_name where evilInput = 1;
CodeIgniter will not escape or filter this input. This can be easily exploited with something like:
1=1 and updatexml(null,concat(0x3a,version()),null)-- -
3) $query = $this->db->get($evilInput3)
Here the input goes in the table name.
select * from evilInput where column_name = 1;
CodeIgniter won't prevent SQL Injection if the user input is something like:
information_schema.tables where 1=1 and updatexml(null,concat(0x3a,version()),null)-- -
4) $this->db->where("a=$evilInput")
This is vulnerable to simple SQL Injection because the input is directly concatenated to the SQL query.

Related

Count of rows from all views in Oracle with a condition

I am trying to get count of all rows from views in oracle schema and my code is working fine. But when i try to add a condition like where actv_ind = 'Y', i am unable to get it working. Any suggestions on how to modify the code to make it working?
SELECT view_name,
TO_NUMBER(extractvalue(xmltype(dbms_xmlgen.getxml('select count(*) cnt from '||owner||'.'||view_name||
'where'||view_name||'.'||'actv_ind= Y')),'/ROWSET/ROW/CNT')) as VIEW_CNT
FROM all_views
WHERE owner = 'ABC' AND view_name not in ('LINK$')
I am getting the error ACTV_IND : Invalid Identifier.
The error messages from DBMS_XMLGEN are not very helpful so you need to be very careful with the syntax of the SQL statement. Add a space before and after the where, and add quotation marks around the Y:
SELECT view_name,
TO_NUMBER(extractvalue(xmltype(dbms_xmlgen.getxml('select count(*) cnt from '||owner||'.'||view_name||
' where '||view_name||'.'||'actv_ind= ''Y''')),'/ROWSET/ROW/CNT')) as VIEW_CNT
FROM all_views
WHERE owner = 'ABC' AND view_name not in ('LINK$');
The query still assumes that every view contains the column ACTV_IND. If that is not true, you might want to base the query off of DBA_TAB_COLUMNS WHERE COLUMN_NAME = 'ACTV_IND'.
Here's a simple sample schema I used for testing:
create user abc identified by abc;
create or replace view abc.view1 as select 1 id, 'Y' actv_ind from dual;
create or replace view abc.view2 as select 2 id, 'N' actv_ind from dual;

How to use SQL query to define table in dbtable?

In JDBC To Other Databases I found the following explanation of dbtable parameter:
The JDBC table that should be read. Note that anything that is valid in a FROM clause of a SQL query can be used. For example, instead of a full table you could also use a subquery in parentheses.
When I use the code:
CREATE TEMPORARY TABLE jdbcTable
USING org.apache.spark.sql.jdbc
OPTIONS (
url "jdbc:postgresql:dbserver",
dbtable "mytable"
)
everything works great, but the following:
dbtable "SELECT * FROM mytable"
leads to the error:
What is wrong?
Since dbtable is used as a source for the SELECT statement it has be in a form which would be valid for normal SQL query. If you want to use subquery you should pass a query in parentheses and provide an alias:
CREATE TEMPORARY TABLE jdbcTable
USING org.apache.spark.sql.jdbc
OPTIONS (
url "jdbc:postgresql:dbserver",
dbtable "(SELECT * FROM mytable) tmp"
);
It will be passed to the database as:
SELECT * FROM (SELECT * FROM mytable) tmp WHERE 1=0
Code In Scala
val checkQuery = "(SELECT * FROM " + inputTableName + " ORDER BY " + columnName + " DESC LIMIT 1) AS timetable"
val timeStampDf = spark.read.format("jdbc").option("url", url).option("dbtable", checkQuery).load()
Adding an alias is also necessary after the query in parenthesis.

Finding sequences and triggers associated with an Oracle table

I have used this query to fetch the list of sequences belonging to an Oracle database user:
SELECT * FROM all_sequences x,all_tables B
WHERE x.sequence_owner=B.owner AND B.TABLE_NAME='my_table';
But that database user is having many more sequence also, so the query returns me all the sequence of the database user. Can anybody help me to find the particular sequence of my_table using query so that I can get the auto increment id in my application.
i want the query which fetch list of table of my database user with the sequence and triggers used in the table
You can get the triggers associated with your tables from the user_triggers view. You can then look for any dependencies recorded for those triggers in user_dependencies, which may include objects other than sequences (packages etc.), so joining those dependencies to the user_sequences view will only show you the ones you are interested in.
Something like this, assuming you are looking at your own schema, and you're only interesting in triggers that references sequences (which aren't necessarily doing 'auto increment', but are likely to be):
select tabs.table_name,
trigs.trigger_name,
seqs.sequence_name
from user_tables tabs
join user_triggers trigs
on trigs.table_name = tabs.table_name
join user_dependencies deps
on deps.name = trigs.trigger_name
join user_sequences seqs
on seqs.sequence_name = deps.referenced_name;
SQL Fiddle demo.
If you're actually looking at a different schema then you'll need to use all_tables etc. and filter and join on the owner column for the user you're looking for. And if you want to include tables which don't have triggers, or triggers which don't refer to sequences, you can use outer joins.
Version looking for a different schema, though this assumes you have the privs necessary to access the data dictionary information - that the tables etc. are visible to you, which they may not be:
select tabs.table_name,
trigs.trigger_name,
seqs.sequence_name
from all_tables tabs
join all_triggers trigs
on trigs.table_owner = tabs.owner
and trigs.table_name = tabs.table_name
join all_dependencies deps
on deps.owner = trigs.owner
and deps.name = trigs.trigger_name
join all_sequences seqs
on seqs.sequence_owner = deps.referenced_owner
and seqs.sequence_name = deps.referenced_name
where tabs.owner = '<owner>';
If that can't see them then you might need to look at the DBA views, again if you have sufficient privs:
select tabs.table_name,
trigs.trigger_name,
seqs.sequence_name
from dba_tables tabs
join dba_triggers trigs
on trigs.table_owner = tabs.owner
and trigs.table_name = tabs.table_name
join dba_dependencies deps
on deps.owner = trigs.owner
and deps.name = trigs.trigger_name
join dba_sequences seqs
on seqs.sequence_owner = deps.referenced_owner
and seqs.sequence_name = deps.referenced_name
where tabs.owner = '<owner>';
One way would be to run these queries to check if there are any sequence's Pseudocolumns (NEXTVAL and CURRVAL ) used in your functions , procedures, packages, Triggers or PL/SQL JAVA SOURCE.
select * from user_source where
UPPER(TEXT) LIKE '%NEXTVAL%';
select * from all_source where
UPPER(TEXT) LIKE '%NEXTVAL%';
Then go to the specific Procedure, Function or Trigger to check which column/table gets populated by a sequence.
The query could also be used with '%CURRVAL%'
This might not help if you are running inserts from JDBC or other external applications using a sequence.
Oracle 12c introduced the IDENTITY columns, using which you could create a table with an identity column, which is generated by default.
CREATE TABLE t1 (c1 NUMBER GENERATED BY DEFAULT ON NULL AS IDENTITY,
c2 VARCHAR2(10));
This will internally create a sequence that auto-generates the value for the table's column.So, If you would like to know which sequence generates the value for which table, you may query the all_tab_columns
SELECT data_default AS sequence_val
,table_name
,column_name
FROM all_tab_columns
WHERE OWNER = 'HR'
AND identity_column = 'YES';
SEQUENCE_VAL |TABLE_NAME |COLUMN_NAME
-----------------------------------------|-------------------------------------
"HR"."ISEQ$$_78160".nextval |T1 |C1
I found a solution to this problem to guess the sequence of a particular sequence
select * from SYS.ALL_SEQUENCES where SEQUENCE_OWNER='OWNER_NAME' and LAST_NUMBER between (select max(FIELD_NAME) from TABLE_NAME) and (select max(FIELD_NAME)+40 from TABLE_NAME);
This query will guess by search the LAST_NUMBER of the sequence value between MAX value of the field using sequence and Max value + 40 (in my case cache value is 20, so I put 40)
select SEQUENCE_NAME from sys.ALL_TAB_IDENTITY_COLS where owner = 'SCHEMA_NAME' and table_name = 'TABLE_NAME';

Oracle and Pagination

In MySql, the concept of pagination can easily be implemented with a single SQL statement using the LIMIT clause something like the following.
SELECT country_id, country_name
FROM country c
ORDER BY country_id DESC
LIMIT 4, 5;
It would retrieve the rows starting from 5 to 10 in the result set which the SQL query retrieves.
In Oracle, the same thing can be achieved using row numbers with a subquery making the task somewhat tedious as follows.
SELECT country_id, country_name
FROM
(SELECT rownum as row_num, country_id, country_name
FROM
(SELECT country_id, country_name
FROM country
ORDER BY country_id desc)
WHERE rownum <= 10
)
WHERE row_num >=5;
In Oracle 10g (or higher, I'm not sure about the higher versions though), this can be made somewhat easy such as,
SELECT country_id, country_name
FROM (SELECT country_id, country_name, row_number() over (order by country_id desc) rank
FROM country)
WHERE rank BETWEEN 6 AND 10;
Regarding an application like a web application, the concept of pagination is required to implement almost everywhere and writing such SQL statements every time a (select) query is executed is sometimes a tedious job.
Suppose, I have a web application using Java. If I use the Hibernate framework then there is a direct way to do so using some methods supported by Hibernate like,
List<Country>countryList=session.createQuery("from Country order by countryId desc")
.setFirstResult(4).setMaxResults(5).list();
but when I simply use JDBC connectivity with Oracle like,
String connectionURL = "jdbc:oracle:thin:#localhost:1521:xe";
Connection connection = null;
Statement statement = null;
ResultSet rs = null;
Class.forName("oracle.jdbc.OracleDriver").newInstance();
connection = DriverManager.getConnection(connectionURL, "root", "root");
statement = connection.createStatement();
rs = statement.executeQuery("SELECT * from country");
My question in this case, is there a precise way to retrieve a specified range of rows using this code? Like in the preceding case using the methods something like setFirstResult() and setMaxResults()? or the only way to achieve this is by using those subqueries as specified.
Because 'No' is an answer too:
Unfortunately, you will have to use the subquery approach. I would personally use the one with the rank (the second one).

SQL Server 2005 Express - generate script to create VIEW based on relational tables?

Is there a way in SQL Server 2005 Express to generate a script that would create a VIEW based on tables primary/foreign key relationships?
I have multiple databases with thousands of tables, and its very time consuming to look at the "table dependencies" and try to JOIN data in the query window.
Thanks
This Query return Create statement for tables, but you must first note that:
1. only works for 1 column foreign key references
2. has not been tested for sql server express 2005, but works fine for Sql server 2005
create function dbo.func59C217D64BC54EA0B841BF1AB43D9398(#table1 nvarchar(1000), #table2 nvarchar(1000))
returns nvarchar(max)
as
begin
declare #sql nvarchar(max)
set #sql = ''
select #sql = #sql + dr + '.[' +cc +'] AS ['+ cc+ ISNULL(rr,'') + '],'
from (
select column_name cc,
dr = case when table_schema + '.' +table_name = #table1 then 'a' else 'b' end,
cast(NULLIF(row_number() over (partition by column_name order by table_name),1) as nvarchar) rr
from INFORMATION_SCHEMA.COLUMNS where table_schema + '.' +table_name in
(#table1,#table2)
) i
return substring(#sql,1,len(#sql) - 1)
end
GO
select cast(
'CREATE VIEW ['+r.CONSTRAINT_SCHEMA+'].[vw' +cp.TABLE_NAME+cf.TABLE_NAME+ ']
AS SELECT '+dbo.func59C217D64BC54EA0B841BF1AB43D9398(cp.TABLE_SCHEMA+'.' +cp.TABLE_NAME,cf.TABLE_SCHEMA+ '.' +cf.TABLE_NAME)+' FROM ['+cp.TABLE_SCHEMA+'].['+cp.TABLE_NAME+'] AS a
JOIN ['+cf.TABLE_SCHEMA+'].['+cf.TABLE_NAME +'] AS b
ON a.['+cp.COLUMN_NAME+'] = b.['+cf.COLUMN_NAME +']' as ntext) as sql
from INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS r
JOIN INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE cf ON r.CONSTRAINT_NAME = cf.CONSTRAINT_NAME
JOIN INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE cp ON r.UNIQUE_CONSTRAINT_NAME = cP.CONSTRAINT_NAME
GO
DROP function dbo.func59C217D64BC54EA0B841BF1AB43D9398
hope I helped, or at least make you started

Resources