Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
I have a Web API controller with two actions. One action returns a list of all entities from the database. The second action takes a query string parameter and filters the entities.
The search action is wired up to use the query string parameter. It works but we encountered an issue with a doc tool not working since the action signatures are the same (the doc tool does not take into account the query string).
Is it wrong to move the search parameter from the query string to an attribute in the route? Is this an acceptable approach? Will is cause problems I'm not thinking about?
Currently, this is a URL I use:
domain.com/api/entities?q=xyz
I'm considering moving to a route-based approach:
domain.com/api/entities/xyz
If you are implementing a search feature, or other type of feature where you need to have multiple optional parameters, it is better to use query string parameters. You can supply all of them, some of them, or none of them and put them in any order, and it will just work.
// Anything Goes
/controller/action?a=123&b=456&c=789
/controller/action?c=789&a=123&b=456
/controller/action?b=456&c=789
/controller/action?c=789
/controller/action
On the other hand, if you use URL paths and routing, a parameter can only be optional if there is not another parameter to the right of it.
// OK
/controller/action/123/456/789
/controller/action/123/456
/controller/action/123
// Not OK
/controller/action/123/456/789
/controller/action/456/789
/controller/action/789
It is possible by customizing routing to be able to pass optional values in any order, but it seems like a long way to go when query strings are a natural fit for this scenario.
Another factor to consider is whether the values being put into the URL have unsafe characters in them that need to be encoded. It is poor form and sometimes not feasible to encode the path of the URL, but the rules of what types of encoded characters that can be put into a query string are more relaxed. Since URLs don't allow spaces, it is a better fit for a multiple word text search field to be encoded with the space in the query string (preserving it as is) rather than trying to find a solution to swapping out the space with a - to put into the query string and then having to change it back to a space on the server side when running the query.
search = "foo bar"
// Spaces OK
/controller/action?search=foo%20bar (works fine and server is able to interpret)
// Spaces Not OK
/controller/action/foo bar/ (not possible)
/controller/action/foo%20bar/ (may work, but a questionable design choice)
/controller/action/foo-bar/ (may work, but requires conversion on the server)
Finally, another choice worth considering is using POST instead of GET, as that would mean these values wouldn't need to be in the URL at all.
Related
We have an ASP.NET Web API controller that accepts a comma-delimited string of database column names from the query string. This string of column names is checked to ensure only alpha characters, underscores, and commas are present in the string; no spaces, special characters or numbers allowed. This string is eventually added to a SQL statement via string interpolation exactly as passed to the API in the query string.
Any other query string parameters are added to the SQL statement as parameters. We encountered an issue with parameterizing a list a columns not be interpreted correctly by Oracle so we ended up with this solution.
Although not ideal, are there any additional steps to prevent SQL injection attacks via this vector?
We are currently using Dapper for data access but frequently use plain ADO.NET.
If that's the only thing you can do, as long as you make sure you don't allow numbers and special characters like quotes, equal and different you will be fine. I would even say you should be good with numbers, I have seen cases where numbers are actually used as part of column names so you could relax that restriction a little.
You could basically create a white list of characters allowed and when the request comes in, if any character is not part of that list then you can throw Bad Request and stop right there. A white list is much better than a black list as it can be much shorter and it's easier to maintain.
Another layer of protection can come from the API itself. Make sure you :
authenticate the access to your controller, no anonymous users allowed, maybe something like OAUTH2 if you can.
turn that API call into a POST and send the list of columns in the body of the request not in the query string.
issue the request over HTTPs.
All these things together should keep you well protected as no one can now watch and see what you are sending through and they can't issue their requests either if you protect your endpoint properly.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 7 years ago.
Improve this question
I know what JSON is and what the advantages over XML. I already read some answer for this , but still i can't get through it.
So i would specifically ask this questions:
1. Is it only useful for API thing? so exchange data without refresh the whole page using AJAX..
2. Is it always used with AJAX?
3. Do people (always/very often) using JSON like this? :: Database/Server - JSON - Client.. what i mean by that is, all our data from database will be put into JSON, so people can use it easily to any other platform/language?
**because from my point of view, if the data, which we need to output not much, why not just directly write on HTML directly, and if it's a lot of data, why not use database? If you don't mind please add an example case to use json
big thanks everyone!
Because JSON is a lightweight data interchange format, it's uses vary widely. You describe using it for an API, which would be an idea situation to use JSON output over something like XML.
To specifically answer your questions:
It's not just useful for an API. It can be used to create configuration (for example, Composer's JSON configuration file). It can also be used for basic output to easily read with languages like JavaScript, since JSON is native to JavaScript as an object. (JavaScript Object Notation).
It's not always used for AJAX. Say you were building a PHP application to convert currency, and you wanted to read from an API that output as JSON, this would always be preferred. Because languages like PHP have the ability to encode and decode JSON, you could read from the API (or other source) and decode it, giving you a PHP object or array of the JSON data.
I think you mean reading from a database, outputting that in JSON format and then allowing clients to read it using an API. In this case, it's not always the way it's used - but if I had to guess, it's the most common way it's used, and probably most useful.
the JSON in my opinion, when you get some data from netWork , you can use the JSON to describe your data . JSON only is a data format. it isn't always used with AJAX . it's only a format. It contains array and dictionary.
I'm currently developing a website that allows a search on a PostgreSQL
database, the search works with to_tsquery() and I'm trying to find a way to validate the input before it's being sent as a query.
Other than that I'm also trying to add a phrasing capability, so that if someone searches for HELLO | "I LIKE CATS" it will only find results with "hello" or the entire phrase "i like cats" (as opposed to I & LIKE & CATS that will find you articles that have all 3 words,
regardless where they might appear).
Is there some reason why it's too expensive to let the DB server validate it? It does seem a bit excessive to duplicate the ts_query parsing algorithm in the client.
If the concern is that you don't want it to try running the whole query (which presumably will involve table access) each time it validates, you could use the input in a smaller query, just in pseudocode (which may look a bit like Python, but that's just coincidence):
is_valid_query(input):
try:
execute("SELECT ts_query($1)", input);
return True
except DatabaseError:
return False
With regard to phrasing, it's probably easiest to search by the non-phrased query first (using indexes), then filter those for having the phrase. That could be done server side or client side. Depending on the language being parsed, it might be easiest to construct a simple regex of the phrase that deals with repeated whitespace or other ignorable symbols.
Search for to_tsquery('HELLO|(I&LIKE&CATS)'), getting back a list of documents which loosely match.
In the client, filter that to those matching the regex "HELLO|(I\s+LIKE\s+CATS)".
The downside is you do need some additional code for translating your query into the appropriate looser query, and then for translating it into a regex.
Finally, there might be a technique in PostgreSQL to do proper phrase searching using the lexeme positions that are stored in ts_vectors. I'm guessing that phrase searches are one of the intended uses, but I couldn't find an example of it in my cursory search. There's a section on it near the bottom of http://linuxgazette.net/164/sephton.html at least.
Am wondering if the combination of trim(), strip_tags() and addslashes() is enough to filter values of variables from $_GET and $_POST
That depends what kind of validation you are wanting to perform.
Here are some basic examples:
If the data is going to be used in MySQL queries make sure to use mysql_real_escape_query() on the data instead of addslashes().
If it contains file paths be sure to remove the "../" parts and block access to sensitive filename.
If you are going to display the data on a web page, make sure to use htmlspecialchars() on it.
But the most important validation is only accepting the values you are expecting, in other words: only allow numeric values when you are expecting numbers, etc.
Short answer: no.
Long answer: it depends.
Basically you can't say that a certain amount of filtering is or isn't sufficient without considering what you want to do with it. For example, the above will allow through "javascript:dostuff();", which might be OK or it might not if you happen to use one of those GET or POST values in the href attribute of a link.
Likewise you might have a rich text area where users can edit so stripping tags out of that doesn't exactly make sense.
I guess what I'm trying to say is that there is simple set of steps to sanitizing your data such that you can cross it off and say "done". You always have to consider what that data is doing.
It highly depends where you are going to use it for.
If you are going to display things as HTML, make absolutely sure you are properly specifying the encoding (e.g.: UTF-8). As long as you strip all tags, you should be fine.
For use in SQL queries, addslashes is not enough! If you use the mysqli library for example, you want to look at mysql::real_escape_string. For other DB libraries, use the designated escape function!
If you are going to use the string in javascript, addslashes will not be enough.
If you are paranoid about browser bugs, check out the OWASP Reform library
If you use the data in another context than HTML, other escaping techniques apply.
I made a report with about 30 different rectangles and textboxes that have different visibility expressions depending on the parameters. (It's a student invoice and many different messages have to appear depending on the semester) When I made all the expressions I coded in the parameters in all upper case. Now I have a problem when users enter lowercase letters, the SQL all works fine since it is not case sensitive, but the different rectangles and textboxes don't show. Is there a way in the report code to first capitalize all the parameters before running the SQL? Or do I actually have to go back to every visibility expression and add separate iif's for upper and lower case? (That seems incredibly silly to have to do). I can't change my parameters to numbers because I have been given strict requirements for input. Thanks.
I do not know if this is the most elegant solution, but you could accomplish this by following this procedure for every parameter on the Report Parameters page:
1)Re-name the parameter, leaving its prompt as that of the old parameter.
2)Add a new parameter with the same name as the old parameter.
3)Mark this new parameter as Hidden.
4)Make sure that the new parameter's available values are marked as non-queried(available values will never be actually used.)
5)Mark the Default Values as Non-queried, using the following syntax:
=ucase(Parameters!OldParameterName.Value)
Can't you just UCASE the params (do it in the xml view, it will be quicker and you might even be able to do a regex find/replace)