I'm trying to pass an SQL query string from a Java Applet to Servlet as a parameter.
Problem is that in Applet I have something say: sql=select * from p where(+p=1)
The resulting sql parameter in the Servlet is sql=select * from p where(+p=1).
So anyone knows how to prevent the browser from removing the + character from parameters?
Is there a escape character?
Thank you.
Do not EVER do this. This is the direct way for the SQL injection (for example any user can insert the DELETE request to the get string and crash your server)
You can use java.net.URLEncoder for this.
param = URLEncoder.encode(param, "UTF-8");
That said, the whole idea is leaky and very prone to attacks. One could easily reveal the URL and manually send a DELETE FROM p to it. Rather send commands as parameters, not complete SQL queries. Keep and hide the SQL queries in the server side.
Related
I am facing a strange issue. Looks like a bug in the SolrJ API:
When I try to run a search query with edismax, the "qf" field is not being encoded properly.
I am trying to use this as my "qf" value:
title^40+details_plain^20
SolrQuery.set() method adds this to the query as it is which doesn't work as it needs to be url encoded.
When I url encode it myself, it becomes:
qf=title%5E40+details_plain%5E20
However when I set that in the query, the resulting final query automatically encodes it again and makes it:
qf=title%255E40%2Bdetails_plain%255E20
Which is also wrong and the query fails saying "undefined field text" because Solr doesnt know what I want to search for so it tried to search on the default "text" field.
Here is a snippet from the code:
SolrClient solr=null;
SolrQuery query = new SolrQuery();
solr = new CloudSolrClient(zookeepers, "/" );
query.set("deftype", searchConfig.getDeftype());
//query.set("df", "details_plain"); //unless i uncomment it the query fails as qf is not correct
query.set("fl", searchConfig.getFl());
query.set("mm", searchConfig.getMm());
query.set("qf", searchConfig.getQf());
query.set("rows", searchConfig.getRows());
query.set("q", searchPhrase);
query.set("collection", searchConfig.getCollection_name());
query.set("indent", "on");
query.set("omitHeader", "true");
query.set("wt", "json");
QueryResponse response = solr.query(query);
Why doesn't it encode the original string, but encodes it again if I send it as an encoded string?
I might be overlooking something so let me know what you all think. Am I doing something wrong or should I just get Solr source code and try to fix this myself?
As far as I can remember you should not encode yourself any field. The encode/decode part is transparently handled by solrj.
Solved. Posting the solution here for anyone who might be unfortunate enough to have made the same silly mistake that I did.
The problem was in this line:
query.set("deftype", searchConfig.getDeftype());
the parameter name should be "defType" with a capital T instead of a small t like:
query.set("defType", searchConfig.getDeftype());
Ideally in such services parameter names should be all lowercase so as not to waste peoples time in issues like this but it is what it is. Maybe in a another SOLR version they will make the parameters name ignore case. One can hope!
I've got a database with names in it. These names sometimes contain non ascii characters e.g. González. I've got the collation settings such that if I search for WHERE LastName LIKE '%Gonzalez%' I get González's record back. In Management Studio I can search for both WHERE LastName LIKE '%Gonzalez%' and WHERE LastName LIKE '%González%' and both return the correct value. However when I use JPA / Hibernate the query that gets sent to the database clearly doesn't represent the á character correctly as I get 0 results.
When utilising the show_sql attribute I can see the actual query is fine, and If I copy and paste that query and replace the ? characters with '%González%' I get the correct results. Likewise if I search for Gonzalez through the web interface I get results, so I'm confident it's the á that is causing me problems, and it's only JPA / Hibernate that is causing the issue. (Having said that the issue could be the AJAX submission to the servlet that is causing the issue, but the parameter is sent as ?LastName=Gonz%C3%A1lez which I think is right?)
So if it's JPA / Hibernate how do I diagnose / fix the issue?
The show_sql logging configuration attribute only lets you see the formatted SQL statement, generated by Hibernate. To troubleshoot the problem further, you need to make sure the values, hibernate replaces the *'?'*s with, are actually correct. Look at the thread on how to see param values in hibernate log and adjust your application log settings.
The second step I'd suggest to add - is in your AJAX request, encode all your params as Base64 string, and then decode it back to UTF-8 string on the controller, handling the request.
The flow of logic should be as follow:
Client receives input 'González'
client encodes the input into 'R29uesOhbGV6' and passes it in AJAX request
controller, handling the request, decodes the parameter back to 'González'
controller passes the value down to hibernate logic, where hibernate generates SQL and executes it
in the application log, you see that hibernate actually passes 'González' parameter down to the database
I am using the webservice that will send the request for one of the column as Dran & Hyle , but i get the exception as a expected valid begining name character. due to the special character &
Below is the insert statement in my java .
public static final String PetInsert= insert into pet values(?,?,?);
I believe set define off will not work in java code , it is understood only by sql developer.
Any help is appreciated
From Java, it is recommended to use PreparedStatement when creating a statement to query the database. Read more in the documentation.
Not so sure, but can it be that in the XML of the web service the error is located? Then somewhere
"Dran & Hyle"
should go into the XML. Normally it is done automatically. So it would be the unlikely case of creating the XML oneself with Strings.
In that case use apache's StringEscapeUtils:
s = StringEscapeUtils.escaleXML(s);
P.S. I found set define off of #aUserHimself plausible.
I am attempting to use zxJDBC to connect to a database running on SQL Server 2008 R2 (Express) and call a stored procedure, passing it a single parameter. I am using jython-standalone 2.5.3 and ideally do not want to have to install additional modules.
My test code is shown below.
The database name is CSM
Stored Procedure:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: <Author,,Name>
-- Create date: <Create Date,,>
-- Description: <Description,,>
-- =============================================
CREATE PROCEDURE dbo.DUMMY
-- Add the parameters for the stored procedure here
#carrierId VARCHAR(50)
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- Insert statements for procedure here
INSERT INTO dbo.carrier (carrierId, test)
VALUES (#carrierId, 'Success')
END
GO
Jython Script:
from com.ziclix.python.sql import zxJDBC
conn = None
try :
conn = zxJDBC.connect('jdbc:sqlserver://localhost\SQLEXPRESS', 'sa', 'password', 'com.microsoft.sqlserver.jdbc.SQLServerDriver')
cur = conn.cursor()
cur.callproc(('CSM','dbo','DUMMY'), ['carrier1'])
conn.commit()
except Exception, err :
print err
if conn:
conn.rollback()
finally :
if conn :
conn.close()
By using cur.execute() I have been able to verify that the above is successfully connecting to the database, and that I can query against it. However, I have thus far been unable to successfully call a stored procedure with parameters.
The documentation here(possibly out of date?) indicates that callproc() can be called with either a string or a tuple to identify the procedure. The example given -
c.callproc(("northwind", "dbo", "SalesByCategory"), ["Seafood", "1998"], maxrows=2)
When I attempt to use this method, I receive the following error
Error("Could not find stored procedure 'CSM.DUMMY'. [SQLCode: 2812], [SQLState: S00062]",)
It would appear that zxJDBC is neglecting to include the dbo part of the procedure identifier.
If I instead call callproc with "CSM.dbo.DUMMY" as the first argument then I receive this error
Error('An object or column name is missing or empty. For SELECT INTO statements, verify each column has a name. For other statements, look for empty alias names. Aliases defined as "" or [] are not allowed. Change the alias to a valid name. [SQLCode: 1038], [SQLState: S0004]',)
Using a profiler on the database whilst running my script shows that in the second case the following SQL is executed:
use []
go
So it would seem that when using a single string to identify the procedure, the database name is not correctly parsed out.
One of my trial and error attempts to fix this was to call callproc as follows:
cur.callproc(('CSM', '', 'dbo.DUMMY'), ['carrier1'])
This got me only as far as
Error("Procedure or function 'DUMMY' expects parameter '#carrierId', which was not supplied. [SQLCode: 201], [SQLState: S0004]",)
In this case what I think is happening is that zxJDBC attempts to call a system stored procedure (sp_proc_columns) to determine the required parameters for the stored procedure I want to call. My guess is that with the procedure identifier in the incorrect format above, zxJDBC does not get a valid/correct return and assumes no parameters are required.
So basically I am not a bit stuck for ideas as to how to get it to
Use the correct database name
Correctly determine the required parameters using sp_proc_columns
Call my stored procedure with the correct name
all at the same time.
I do have a workaround, which is to use something like
cur.execute('EXEC CSM.dbo.DUMMY ?', ['carrier1'])
However I feel like callproc() is the correct solution, and would likely produce cleaner code when I come to call stored procedures with large numbers of parameters.
If anyone can spot the mistake(s) that I am making, or knows that this is not ever going to work as I think then any input would be much appreciated.
Thanks
Edit
As suggested by i-one, I tried adding cur.execute('USE CSM') before calling my stored procedure (also removing the database name from the procedure call). This unfortunately produces the same Object or Column missing error as above. The profiler shows USE CSM being executed, followed by USE [] so it seems that callproc() always fires a USE statement before the procedure itself.
I have also experimented with turning on/off autocommit, to no avail.
Edit 2
Further information following comments/suggested solutions:
"SQLEXPRESS" in my connection string is the database instance name.
Using double quotes instead of single has no effect.
Including the database name in the connection string (via ;databaseName=CSM; as specified here) and omitting it from the callproc() call leads to the original error with a USE [] statement being fired.
Using callproc(('CSM', 'dbo', 'dbo.DUMMY'), ['carrier1']) gives me some progress but results in the error
Error("Procedure or function 'DUMMY' expects parameter '#carrierId', which was not supplied. [SQLCode: 201], [SQLState: S0004]",)
I'll attempt to investigate this further
Edit 3
Based on the queries I could see zxJDBC firing, I manually executed the following against my database:
use CSM
go
exec sp_sproc_columns_100 N'dbo.DUMMY',N'dbo',N'CSM',NULL,N'3'
go
This gave me an empty results set, which would seem to explain why zxJDBC isn't passing any parameters to the stored procedure - it doesn't think it needs to. I have yet to figure out why this is happening though.
Edit 4
To update the above, the empty result set is because the call should be
exec sp_sproc_columns_100 N'DUMMY',N'dbo',N'CSM',NULL,N'3'
This unfortunately brings me full circle as I can't remove the dbo owner from the stored procedure name in my callproc() call or the procedure won't be found at all.
Edit 5
Table definition as requested
CREATE TABLE [dbo].[carrier](
[carrierId] [varchar](50) NOT NULL,
[test] [varchar](50) NULL
) ON [PRIMARY]
Though completely unaware of the technologies used here (unless some minor knowledge of SQL Server), I will attempt an answer (please forgive me if my jython syntax is not correct. I am trying to outline possibilities here not exact code)
My first approach (found at this post) would be to try:
cur.execute("use CSM")
cur.callproc(("CSM","dbo","dbo.DUMMY"), ["carrier1"])
This must have to do with the fact that sa users always have the dbo as a default schema (described at this SO post)
If the above does not work I would also try to use the CSM database name in the JDBC url (this is very common when using JDBC for other databases) and then simply call one of the two below.
cur.callproc("DUMMY", ["carrier1"])
cur.callproc("dbo.DUMMY", ["carrier1"])
I hope this helps
Update: I quote the relevant part of the link that you can't view
>> Program calls a Stored Procedure - master.dbo.xp_fixeddrives on MS SQL Server
from com.ziclix.python.sql import zxJDBC
def getConnection():
url = "${DBServer.Url}"
user= "${DBServer.User}"
password = "${DBServer.Password}"
driver = "${DBServer.Driver}"
con = zxJDBC.connect(url, user, password, driver)
return con
try:
conn = getConnection()
print 'Connection successful'
cur = conn.cursor()
cur.execute("use master")
cur.callproc(("master", "dbo", "dbo.xp_fixeddrives"))
print cur.description
for a in cur.fetchall():
print a
finally:
cur.close()
conn.close()
print 'Connection closed'
The error you get when you specified the call function like above suggests that the parameter is not passed correctly. So please modify your stored procedure to take a default value and try to call with passing params = [None]. If you see that the call succeeds we must have done something right as far as specifying the database is concerned.
Btw: the most recent documentation suggests that you should be able to access it with your syntax.
As outlined in comments callproc will work only with SELECT. Try this approach instead:
cur.execute("exec CSM.dbo.DUMMY #Param1='" + str(Param1) + "', #carrierId=" + str(carrierID))
Please see this link for more detail.
I hava a table in ms sql2000 with a column defined as nvarchar
when query this table in java i get data for this column like this :
يا هلا بالشباب الØلوين يا شباب ا٠شلونكو؟.
When i try php with adodb i get the data as it should be ,in arabic.
but i need to use java not php ,please can any one help me.
i use a normal sql statement "select * from news"
i use the latest Microsoft jdbc driver(sqljdbc4.jar).
i have no direct access to the sql server.
That looks to me like an encoding issue, make sure you're using the proper encoding in Java to get the text back. Some variant of unicode obviously.
At every character processing step (getting data, modifying data, saving data, displaying data, etcetera) ensure that you're using UTF-8 character encoding.
If it is a client application, you usually only have to worry about it in the database table and if necessary also the JDBC connection string.
If it is a webapplication, then you need to take more into account: request and response encoding. For GET requests this is an appserver setting and for POST requests and all responses you can set it in the appropriate request/response objects.