Methods Of retrieving request parameters
Hi, At my projects I always used params hash reference to retrieve request parameters as follow: get '/hello/:name' => sub { return "Hi there " . params->{name}; }; I started reading Dancer ManuaI again to discover new features whether I missed and realized that using following ones are safer: route_parameters->get('name'); query_parameters->get('name'); There is also param('name') method. As a result I see that there are 4 ways: get '/hello/:name' => sub { return "Hi there " . params->{name}; # or return "Hi there " . route_parameters->get('name'); # or return "Hi there " . query_parameters->get('name'); # or return "Hi there " . param('name'); }; Is there any technical difference between these ways that one of them can work at a special case but others don't? If there is no difference except being safer (I got this info from manual), is the reason of this diversity to support Perl motto TMTOWTDI? Which ones are you using at your projects? Thanks Kadir Beyazlı GSM : +90 535 821 50 00
Quoting Kadir Beyazlı <kadirbeyazli@gmail.com>:
Hi,
At my projects I always used params hash reference to retrieve request parameters as follow:
get '/hello/:name' => sub { return "Hi there " . params->{name}; };
I started reading Dancer ManuaI again to discover new features whether I missed and realized that using following ones are safer:
route_parameters->get('name'); query_parameters->get('name');
There is also param('name') method. As a result I see that there are 4 ways:
get '/hello/:name' => sub { return "Hi there " . params->{name}; # or return "Hi there " . route_parameters->get('name'); # or return "Hi there " . query_parameters->get('name'); # or return "Hi there " . param('name');
};
You missed one. There's also: body_parameters->get('name')
Is there any technical difference between these ways that one of them can work at a special case but others don't?
Yes, there's a big technical difference. There are three places where your app can get parameters from. You can get parameters from the query string. http://example.com/yourapp?param1=value¶m2=value¶m3=value You can also get parameters from Dancer's route matching. get '/:param1/:param2/:param3' => sub { ... }; Or you can get parameters from the body of the request (typically from a <form> that has been submitted as a POST request. The three keywords that are now recommended, all force you to say explicitly where the parameter can be found - whether it's in the query (query_parameter), the route matching (route_parameters) or the request body (body_parameters). The keywords which don't specify where to find the parameters (param or params) both look in all three places for the parameter name.
If there is no difference except being safer (I got this info from manual), is the reason of this diversity to support Perl motto TMTOWTDI?
The more explicitly-named methods are definitely safer. You really want to know where your parameters are coming from. These are the methods that you should be using. I assume the older methods are still supported for backwards compatibility. I don't know what the project's plans are about deprecating and removing them.
Which ones are you using at your projects?
I try to use the newer, more explicit, methods in new code. But I bet there's a good chance that I'm still using the older approach in code that I haven't looked at for a couple of years. Cheers, Dave...
Hi Dave, Thank you very much for clear explanation. I learnt this wonderful property now. Best Regards On Mon, Jul 11, 2016 at 12:29 PM, Dave Cross <dave@dave.org.uk> wrote:
Quoting Kadir Beyazlı <kadirbeyazli@gmail.com>:
Hi,
At my projects I always used params hash reference to retrieve request parameters as follow:
get '/hello/:name' => sub { return "Hi there " . params->{name}; };
I started reading Dancer ManuaI again to discover new features whether I missed and realized that using following ones are safer:
route_parameters->get('name'); query_parameters->get('name');
There is also param('name') method. As a result I see that there are 4 ways:
get '/hello/:name' => sub { return "Hi there " . params->{name}; # or return "Hi there " . route_parameters->get('name'); # or return "Hi there " . query_parameters->get('name'); # or return "Hi there " . param('name');
};
You missed one. There's also:
body_parameters->get('name')
Is there any technical difference between these ways that one of them can work at a special case but others don't?
Yes, there's a big technical difference.
There are three places where your app can get parameters from. You can get parameters from the query string.
http://example.com/yourapp?param1=value¶m2=value¶m3=value
You can also get parameters from Dancer's route matching.
get '/:param1/:param2/:param3' => sub { ... };
Or you can get parameters from the body of the request (typically from a <form> that has been submitted as a POST request.
The three keywords that are now recommended, all force you to say explicitly where the parameter can be found - whether it's in the query (query_parameter), the route matching (route_parameters) or the request body (body_parameters). The keywords which don't specify where to find the parameters (param or params) both look in all three places for the parameter name.
If there is no difference except being safer (I got this info from manual), is the reason of this diversity to support Perl motto TMTOWTDI?
The more explicitly-named methods are definitely safer. You really want to know where your parameters are coming from. These are the methods that you should be using.
I assume the older methods are still supported for backwards compatibility. I don't know what the project's plans are about deprecating and removing them.
Which ones are you using at your projects?
I try to use the newer, more explicit, methods in new code. But I bet there's a good chance that I'm still using the older approach in code that I haven't looked at for a couple of years.
Cheers,
Dave...
_______________________________________________ dancer-users mailing list dancer-users@dancer.pm http://lists.preshweb.co.uk/mailman/listinfo/dancer-users
-- Kadir Beyazlı Computer Engineer GSM : +90 535 821 50 00
On Jul 11, 2016, at 3:29 AM, Dave Cross <dave@dave.org.uk> wrote:
The more explicitly-named methods are definitely safer. You really want to know where your parameters are coming from.
I’m still waiting for someone to justify that stance with more than confident prose assertions. Someone, please show me code that the new keywords makes better. If I’ve defined a route: get '/foo' => sub { my $bar = param 'bar'; ... …what practical difference does it make if my caller sends me the parameters in the URL or in the request body? I’ve received a “bar” parameter, end of story. My program is satisfied. The only case I can see is if you have two or more different ways to pass a given parameter, and they have different semantic meaning: get ‘/foo/:bar?' => sub { my $bar1 = body_parameters->get('bar'); my $bar2 = query_parameters->get('bar'); my $bar3 = route_parameters->get('bar'); if (defined $bar1) { # do one thing } elsif (defined $bar2) { # do something completely different } elseif (defined $bar3) { # do something different from both above options } else { # emit flying monkeys } }; I submit that the above is horrible coding style, and no amount of keyword redesign in Dancer is going to fix the fundamental problem, that being PBD. http://www.catb.org/jargon/html/P/PBD.html
Someone, please show me code that the new keywords makes better.
Here's one I prepared earlier: https://github.com/PerlDancer/Dancer2/pull/1213/commits/0745c2797f477401bc9e... I'm not necessarily sold on a *don't use params* stance but it's definitely a potential source of subtle bugs if you are going to be passing on the parameters on. Or indeed if there is any logic outside of the route handler (e.g. middleware, maybe hooks) that doesn't use params or inspect all three sources. Daniel -----Original Message----- From: dancer-users [mailto:dancer-users-bounces@dancer.pm] On Behalf Of Warren Young Sent: 12 July 2016 16:02 To: Perl Dancer users mailing list Subject: Re: [dancer-users] Methods Of retrieving request parameters On Jul 11, 2016, at 3:29 AM, Dave Cross <dave@dave.org.uk> wrote:
The more explicitly-named methods are definitely safer. You really want to know where your parameters are coming from.
I’m still waiting for someone to justify that stance with more than confident prose assertions. Someone, please show me code that the new keywords makes better. If I’ve defined a route: get '/foo' => sub { my $bar = param 'bar'; ... …what practical difference does it make if my caller sends me the parameters in the URL or in the request body? I’ve received a “bar” parameter, end of story. My program is satisfied. The only case I can see is if you have two or more different ways to pass a given parameter, and they have different semantic meaning: get ‘/foo/:bar?' => sub { my $bar1 = body_parameters->get('bar'); my $bar2 = query_parameters->get('bar'); my $bar3 = route_parameters->get('bar'); if (defined $bar1) { # do one thing } elsif (defined $bar2) { # do something completely different } elseif (defined $bar3) { # do something different from both above options } else { # emit flying monkeys } }; I submit that the above is horrible coding style, and no amount of keyword redesign in Dancer is going to fix the fundamental problem, that being PBD. http://www.catb.org/jargon/html/P/PBD.html _______________________________________________ dancer-users mailing list dancer-users@dancer.pm http://lists.preshweb.co.uk/mailman/listinfo/dancer-users
On Jul 12, 2016, at 9:15 AM, Daniel Perrett <dp13@sanger.ac.uk> wrote:
Someone, please show me code that the new keywords makes better.
Here's one I prepared earlier:
https://github.com/PerlDancer/Dancer2/pull/1213/commits/0745c2797f477401bc9e...
The first example is essentially the same as the second example in my previous post, which I called horrible coding style. (Horrible API design style, actually.) If your app is dependent on the path the data took to get to it, it is brittle. Consider the design of cat(1). Would it be better if it behaved differently when its input comes in via stdin vs when it comes from a named file on the command line? Or, would its design be improved by denying one of the two input paths, forcing you to use stdin or the command line, not the other? Your second example is simply contrived. If create_song() expects a song name, you should call it as: find_artist(param('id'))->create_song(param('name')); Using “params” in the second function call is no more justified than using it in the find_artist() call. You should only be passing the params() hashref around to functions which you know in advance are capable of extracting any parameters they need and ignoring the rest.
On Jul 12, 2016, at 9:38 AM, Warren Young <wyml@etr-usa.com> wrote:
If your app is dependent on the path the data took to get to it, it is brittle.
Clarification: If your app *behavior* changes depending on where the data comes from, it is brittle. I gave cat(1) as an example of doing it right. For a more complex example, consider sqlite3. It will accept SQL via stdin or as a parameter following the database file name. Should it instead accept SQL via only one path? Should its interpret the SQL differently based on the input path? No and no. (And for the record, I think sqlite3 should *also* accept SQL in from a named file.) Look, I’m happy Dancer now has these new functions which let a developer restrict which sources they are willing to accept data from. If you feel that doing so will improve your program, by all means, use these new functions. My argument is against this apparent move to deprecate the preexisting flexible alternatives. Reading the newer docs, one gets a sense that using param() and params() is always wrong. I’m willing to be convinced of that, but it will take actual proof, not vague handwaving arguments. Until then, this looks like an attempt to turn Perl into a B&D language: http://www.catb.org/jargon/html/B/bondage-and-discipline-language.html And I say that as a fan of F#, a programming language that truly does have the B&D nature. All things in their proper place. Perl’s place is the duct tape of the Internet, and thus needs to follow Postel’s Law.
As a notorious dancer lurker, I agree with Warrens arguments exactly. Could security concerns, if any, be handled by global configuration parameters? Niels L On Tue, 2016-07-12 at 11:54 -0600, Warren Young wrote:
On Jul 12, 2016, at 9:38 AM, Warren Young <wyml@etr-usa.com> wrote:
If your app is dependent on the path the data took to get to it, it is brittle.
Clarification: If your app *behavior* changes depending on where the data comes from, it is brittle.
I gave cat(1) as an example of doing it right. For a more complex example, consider sqlite3. It will accept SQL via stdin or as a parameter following the database file name. Should it instead accept SQL via only one path? Should its interpret the SQL differently based on the input path? No and no. (And for the record, I think sqlite3 should *also* accept SQL in from a named file.)
Look, I’m happy Dancer now has these new functions which let a developer restrict which sources they are willing to accept data from. If you feel that doing so will improve your program, by all means, use these new functions. My argument is against this apparent move to deprecate the preexisting flexible alternatives. Reading the newer docs, one gets a sense that using param() and params() is always wrong.
I’m willing to be convinced of that, but it will take actual proof, not vague handwaving arguments.
Until then, this looks like an attempt to turn Perl into a B&D language:
http://www.catb.org/jargon/html/B/bondage-and-discipline-language.html
And I say that as a fan of F#, a programming language that truly does have the B&D nature. All things in their proper place. Perl’s place is the duct tape of the Internet, and thus needs to follow Postel’s Law. _______________________________________________ dancer-users mailing list dancer-users@dancer.pm http://lists.preshweb.co.uk/mailman/listinfo/dancer-users
Maybe I agree and maybe I don't. I'm trying to think it through and would like comments. Let's say I have an app that can generate two kinds of output. It is a front-end to a database It can be used with a JSON interface or it can present HTML as a traditional web page. The web page uses a form for the user to access the data. The JSON uses a GET with a path that Dancer2 processes. I *could* add a /html element to the path to say "output as html" but it would seldom -- if ever -- be used. I *could* add a checkbox to the web form so it would return JSON but it is unlikely a normal person would want that. So is it better to always specify the output type explicitly to get a particular behavior, or is it as good or better to have an app that behaves differently depending on how it is invoked? The web is different than most desktop applications as web apps can function as data servers (e.g. with JSON) with no UI or as a web page with a UI. What do you (all) think? --john On 7/12/2016 11:54 AM, Warren Young wrote:
On Jul 12, 2016, at 9:38 AM, Warren Young <wyml@etr-usa.com> wrote:
If your app is dependent on the path the data took to get to it, it is brittle. Clarification: If your app *behavior* changes depending on where the data comes from, it is brittle.
I gave cat(1) as an example of doing it right. For a more complex example, consider sqlite3. It will accept SQL via stdin or as a parameter following the database file name. Should it instead accept SQL via only one path? Should its interpret the SQL differently based on the input path? No and no. (And for the record, I think sqlite3 should *also* accept SQL in from a named file.)
-- John J. McDermott, CPLP Learning and Performance Consultant jjm at jkintl.com 575/737-8556 Check out my security blog posts <http://cybersecurity.learningtree.com> Add an A for the Arts To STEM and get STEAM and a strong engine to move forward.
On Jul 12, 2016, at 1:41 PM, John J. McDermott, CPLP <jjm@jkintl.com> wrote:
Let's say I have an app that can generate two kinds of output. It is a front-end to a database It can be used with a JSON interface or it can present HTML as a traditional web page.
Perfectly fine so far.
I *could* add a /html element to the path to say "output as html" but it would seldom -- if ever -- be used. I *could* add a checkbox to the web form so it would return JSON but it is unlikely a normal person would want that.
Do you know a strong functional programming language? I don’t mean FP in the way that JavaScript is a Scheme dialect and therefore FP, or even in the way that Perl is FP as laid out in Dominus’ “Higher-Order Perl.” I mean FP as in Haskell, the ML family, Erlang, etc. These languages teach you the value of thinking of functions in the mathematical sense, which is that any function called with a given set of arguments should always return the same result. Another way of saying the same thing is that functions should not have side effects. It is impossible to avoid all side effects in any practical program not doing pure mathematics, but we can minimize and restrict the scope of these side effects by thinking hard about where the boundaries should be. Strong FP languages sensitize you to this way of thinking. In the context of this debate, the principles of tightly-scoped side effects and referential transparency tell us that if you should not have a a Dancer route that returns HTML in one context and JSON in another. Either the route must differ somehow or the parameters must differ. My preference is to put all JSON-returning Dancer routes under /api, then make all other routes return HTML. (That’s a simplification. My current app also has /pdf for the routes that return dynamically-generated PDFs, for example.) Where the HTML-returning routes need data returned by the JSON API, either: 1. Call the internal JSON-returning route handler from the HTML route handler and use its data to construct the HTML; or 2. Call back into the API from the client side via JS and construct HTML from the returned JSON data there. An example of alternative 1 is: sub getSomeData { … used below … } get '/foo' => { # because not under /api, returns HTML # Do stuff here # ... # Okay, we’re ready to return our page return template '/foo' => { oneElement => getSomeData(param 'bar'), anotherElement => $variableComputedAbove, } }; prefix '/api' => { prefix '/some' => { get '/data' => \&getSomeData }; }; Here we have two routes, one returning HTML and one returning JSON, the first of which is implemented in terms of the second. Because of Dancer's automatic serializers, getSomeData() can return a normal Perl data structure that can either be consumed directly by the template used in the HTML case or be serialized to JSON for consumption on the client side via JS code. Note the use of code references here to allow the HTML route handler to call the JSON route handler. You can read more about this style of development in a series of articles I wrote for the fizzled Dancer 2015 Advent Calendar: https://goo.gl/u900Ii A lesser design principle is that, to the greatest extent practical, you should push most of the code into the JSON side to reduce code duplication. The HTML/JS client-side code can also consume JSON, but the JSON API has little use for HTML. To drag this back onto the topic of this particular thread, it is immaterial in my view whether the values passed to the Dancer route come from the URL’s query parameters, are defined as part of the route, or are passed in via a POST call in the request body. Parameters are parameters, and a properly-written Dancer route handler should return the same data regardless of the exact mechanism used to pass those parameters.
On 7/12/2016 2:27 PM, Warren Young wrote:
On Jul 12, 2016, at 1:41 PM, John J. McDermott, CPLP <jjm@jkintl.com> wrote:
Let's say I have an app that can generate two kinds of output. It is a front-end to a database It can be used with a JSON interface or it can present HTML as a traditional web page. Perfectly fine so far.
I *could* add a /html element to the path to say "output as html" but it would seldom -- if ever -- be used. I *could* add a checkbox to the web form so it would return JSON but it is unlikely a normal person would want that. Do you know a strong functional programming language? I don’t mean FP in the way that JavaScript is a Scheme dialect and therefore FP, or even in the way that Perl is FP as laid out in Dominus’ “Higher-Order Perl.” I mean FP as in Haskell, the ML family, Erlang, etc. Yeah. I haven't found them valuable for "production" software, but I have used them. These languages teach you the value of thinking of functions in the mathematical sense, which is that any function called with a given set of arguments should always return the same result. Another way of saying the same thing is that functions should not have side effects. I completely agree. I detest side-effects. It is impossible to avoid all side effects in any practical program not doing pure mathematics, but we can minimize and restrict the scope of these side effects by thinking hard about where the boundaries should be. Strong FP languages sensitize you to this way of thinking.
In the context of this debate, the principles of tightly-scoped side effects and referential transparency tell us that if you should not have a a Dancer route that returns HTML in one context and JSON in another. Either the route must differ somehow or the parameters must differ. Ohhh, I hate to call it a "debate". I'm trying to look at "best practices", particularly focusing on ease-of-use in different scenarios.
I do not want one route to return different things in different contexts, per se, so perhaps I was unclear. I want: www.mysite.com to behave in a way that a user would expect a website to behave: forms, nice view, etc. www.mysite.com/db/table1 or whatever to behave in a manner a JSON user would expect. I don't want different names. Are you suggesting I need (ignoring the actual names) www.mysite.com and json.mysite.com?
My preference is to put all JSON-returning Dancer routes under /api, then make all other routes return HTML. (That’s a simplification. My current app also has /pdf for the routes that return dynamically-generated PDFs, for example.) This is what I suggested above, I think. Where the HTML-returning routes need data returned by the JSON API, either:
1. Call the internal JSON-returning route handler from the HTML route handler and use its data to construct the HTML; or
2. Call back into the API from the client side via JS and construct HTML from the returned JSON data there.
An example of alternative 1 is:
sub getSomeData { … used below … }
get '/foo' => { # because not under /api, returns HTML # Do stuff here # ...
# Okay, we’re ready to return our page return template '/foo' => { oneElement => getSomeData(param 'bar'), anotherElement => $variableComputedAbove, } };
prefix '/api' => { prefix '/some' => { get '/data' => \&getSomeData }; }; I have done this in real life. Here we have two routes, one returning HTML and one returning JSON, the first of which is implemented in terms of the second. Because of Dancer's automatic serializers, getSomeData() can return a normal Perl data structure that can either be consumed directly by the template used in the HTML case or be serialized to JSON for consumption on the client side via JS code.
Note the use of code references here to allow the HTML route handler to call the JSON route handler.
You can read more about this style of development in a series of articles I wrote for the fizzled Dancer 2015 Advent Calendar:
A lesser design principle is that, to the greatest extent practical, you should push most of the code into the JSON side to reduce code duplication. The HTML/JS client-side code can also consume JSON, but the JSON API has little use for HTML. Agreed/
To drag this back onto the topic of this particular thread, it is immaterial in my view whether the values passed to the Dancer route come from the URL’s query parameters, are defined as part of the route, or are passed in via a POST call in the request body. Parameters are parameters, and a properly-written Dancer route handler should return the same data regardless of the exact mechanism used to pass those parameters. Hmmm. I don't want the HTML page to have to be JSON. I want a more conventional form use (although it could be JSON). --john
-- John J. McDermott, CPLP Learning and Performance Consultant jjm at jkintl.com 575/737-8556 Check out my security blog posts <http://cybersecurity.learningtree.com> Add an A for the Arts To STEM and get STEAM and a strong engine to move forward.
On Jul 12, 2016, at 3:15 PM, John J. McDermott, CPLP <jjm@jkintl.com> wrote:
Do you know a strong functional programming language? Yeah. I haven't found them valuable for "production" software, but I have used them.
Take a look at F#. It’s OCaml with the sharp corners and ugly bits knocked off. Either of those is more accessible than Erlang or Haskell. If its Microsoft origin bothers you, it’s completely open source, and runs just fine on OS X, Linux, FreeBSD, etc.: http://fsharp.org/
These languages teach you the value of thinking of functions in the mathematical sense, which is that any function called with a given set of arguments should always return the same result. Another way of saying the same thing is that functions should not have side effects. I completely agree. I detest side-effects.
That’s easy to say, but up-thread you were talking about DBMSes. Except for SELECT and some of the built-in function calls, a SQL DBMS is nothing but side-effects. (It amuses me when people talk about Erlang as a “pure” FP language when it ships with Mnesia, a disk-backed in-RAM DBMS, which amounts to a global variable store. Talk about side-effects!) Therefore, we practical software developers should not talk about eliminating side-effects, as the ivory tower types like to do, but instead talk about carefully walling off the places in our code where that happens, so that we can predict from the outside where such a thing is likely to occur.
I want: www.mysite.com to behave in a way that a user would expect a website to behave: forms, nice view, etc. www.mysite.com/db/table1 or whatever to behave in a manner a JSON user would expect. I don't want different names.
But you do have different names, which is good. Instead of /api as I was suggesting, you have segregated the JSON/DBMS stuff under /db. I still prefer /api, since I don’t see any particular reason to declare that I’m using a DBMS, but please yourself.
Are you suggesting I need (ignoring the actual names) www.mysite.com and json.mysite.com?
You could do that, too, though I’m not immediately clear on how you’d integrate name-based virtual hosting with Dancer. (I’m assuming you meant both of those to resolve to the same host. If not, then you’re talking about distributed computing, which adds a further layer of complexity.)
To drag this back onto the topic of this particular thread, it is immaterial in my view whether the values passed to the Dancer route come from the URL’s query parameters, are defined as part of the route, or are passed in via a POST call in the request body. Parameters are parameters, and a properly-written Dancer route handler should return the same data regardless of the exact mechanism used to pass those parameters.
Hmmm. I don't want the HTML page to have to be JSON. I want a more conventional form use (although it could be JSON).
I think you might want to look at Angular and other SPA frameworks, then.
On 7/12/2016 3:36 PM, Warren Young wrote:
On Jul 12, 2016, at 3:15 PM, John J. McDermott, CPLP <jjm@jkintl.com> wrote:
Do you know a strong functional programming language? Yeah. I haven't found them valuable for "production" software, but I have used them. Take a look at F#. It’s OCaml with the sharp corners and ugly bits knocked off. Either of those is more accessible than Erlang or Haskell.
If its Microsoft origin bothers you, it’s completely open source, and runs just fine on OS X, Linux, FreeBSD, etc.:
http://fsharp.org/ OK. Will.
These languages teach you the value of thinking of functions in the mathematical sense, which is that any function called with a given set of arguments should always return the same result. Another way of saying the same thing is that functions should not have side effects. I completely agree. I detest side-effects. That’s easy to say, but up-thread you were talking about DBMSes. Except for SELECT and some of the built-in function calls, a SQL DBMS is nothing but side-effects. Ummm, I didn't mention SQL. BUT, sometimes software has to interact with the work of others. (It amuses me when people talk about Erlang as a “pure” FP language when it ships with Mnesia, a disk-backed in-RAM DBMS, which amounts to a global variable store. Talk about side-effects!)
Therefore, we practical software developers should not talk about eliminating side-effects, as the ivory tower types like to do, but instead talk about carefully walling off the places in our code where that happens, so that we can predict from the outside where such a thing is likely to occur. Agreed!
I want: www.mysite.com to behave in a way that a user would expect a website to behave: forms, nice view, etc. www.mysite.com/db/table1 or whatever to behave in a manner a JSON user would expect. I don't want different names. But you do have different names, which is good. Instead of /api as I was suggesting, you have segregated the JSON/DBMS stuff under /db. Precisely. I should have included the example in my first message to avoid confusion. Sorry. I still prefer /api, since I don’t see any particular reason to declare that I’m using a DBMS, but please yourself. That was only an example. It could be a physical system or other data source. I chose a db to make it easier to discuss. /api is fine. The point is (and that's why I suggested ignoring the names), is that I want two behaviors with one hostname and different routes. Based on your comment above, you see that as two names, so I understand your point. I think we agree on substance. Are you suggesting I need (ignoring the actual names) www.mysite.com and json.mysite.com? You could do that, too, though I’m not immediately clear on how you’d integrate name-based virtual hosting with Dancer. I don't want that, I just wanted to clarify. (I’m assuming you meant both of those to resolve to the same host. If not, then you’re talking about distributed computing, which adds a further layer of complexity.) Yes, on the same (virtual) host. I was just trying to clarify, as I noted.
To drag this back onto the topic of this particular thread, it is immaterial in my view whether the values passed to the Dancer route come from the URL’s query parameters, are defined as part of the route, or are passed in via a POST call in the request body. Parameters are parameters, and a properly-written Dancer route handler should return the same data regardless of the exact mechanism used to pass those parameters.
Hmmm. I don't want the HTML page to have to be JSON. I want a more conventional form use (although it could be JSON). I think you might want to look at Angular and other SPA frameworks, then. Well, I've worked with Angular. I don't really like it. I could use a client framework, but the data I used in a real implementation of this didn't need a complex framework (I used datatables.js).
--john
_______________________________________________ dancer-users mailing list dancer-users@dancer.pm http://lists.preshweb.co.uk/mailman/listinfo/dancer-users
-- John J. McDermott, CPLP Learning and Performance Consultant jjm at jkintl.com 575/737-8556 Check out my security blog posts <http://cybersecurity.learningtree.com> Add an A for the Arts To STEM and get STEAM and a strong engine to move forward.
Hi! 2016-07-12 20:54 GMT+03:00 Warren Young <wyml@etr-usa.com>:
I gave cat(1) as an example of doing it right. For a more complex example, consider sqlite3. It will accept SQL via stdin or as a parameter following the database file name. Should it instead accept SQL via only one path? Should its interpret the SQL differently based on the input path? No and no. (And for the record, I think sqlite3 should *also* accept SQL in from a named file.)
Should sqlite3 (or cat) accept all three paths same time? Which one should first, which last? Should those inputs just concatenated together or should they divert each other in some order? As far I understand when using param/params approach Dancer may take same params 3 ways, but one of them wins, So POSTing path with query and form params /item/id/123?id=223 [id=333] we start with 3 different id-s, but at end we have one of them. Is it good design for app? I don't think so. One way to solve this as early as possible is to have those 3 different methods and make those access 3 separate arguments, so developer can choose, where from to read certain value. It leaves choice to the developer. Other way is to prioritize 3 possible ways and let one win over others (maybe depending of context, like POST prefers form value over path or query params). This way makes decision instead of developer and needs more detailed documentation, it seems not flexible at all. It is very cozy, covienient, but where you see flexibility? Actually, I am not sure why Dancer had both param and params? And how they deal with different ways to present params with same key?
Look, I’m happy Dancer now has these new functions which let a developer restrict which sources they are willing to accept data from. If you feel that doing so will improve your program, by all means, use these new functions. My argument is against this apparent move to deprecate the preexisting flexible alternatives. Reading the newer docs, one gets a sense that using param() and params() is always wrong.
I’m willing to be convinced of that, but it will take actual proof, not vague handwaving arguments.
As far every HTTP-param is easily changeable on client side I don't know which security concern may involved in this situation. I'd like to read about these too. Still, one attack vector I have in mind, even it is unlikely. Let's say we have app with authentication middleware. Middleware checks user ID from path and reads session ID from cookie, then it makes sure from backend, that user ID and session match, so it flags connection correct and gives it forward to app. In app path-ID and query-ID have conflict, but last one wins because precedence and now we run our query in rights of ID we read from query params. Seems like taking over to me. Avoidable, if we make distinction, from where param is readed. wbr, -- Kõike hääd, Gunnar
On Jul 12, 2016, at 5:08 PM, WK <wanradt@gmail.com> wrote:
2016-07-12 20:54 GMT+03:00 Warren Young <wyml@etr-usa.com>:
I gave cat(1) as an example of doing it right. For a more complex example, consider sqlite3.
Should sqlite3 (or cat) accept all three paths same time?
Of course not, and they don’t, any more than Dancer’s params() mooshes all three together: $ echo foo | cat <(echo bar) bar $ echo 'select 2*3' | sqlite3 x.db 'select 3*4' 12
Which one should first, which last?
That's up to the Dancer designers to specify.
Should those inputs just concatenated together or should they divert each other in some order?
The three parameter sources should have a defined and documented precedence order.
So POSTing path with query and form params
/item/id/123?id=223
[id=333]
we start with 3 different id-s, but at end we have one of them. Is it good design for app? I don't think so.
You see this kind of thing a lot, do you? If a caller does something like what you suggest, it doesn’t matter which one Dancer chooses to pass to your app. The caller has made an ambiguous call, so it is at the mercy of Dancer’s precedence rules.
One way to solve this as early as possible is to have those 3 different methods and make those access 3 separate arguments, so developer can choose, where from to read certain value. It leaves choice to the developer.
I answered that in the reply you quoted: if you, as the app developer, wish to restrict your APIs so they get data from only one of the three possible sources, I have no problem with that, and I’m glad Dancer now gives you a way to force that. I’m just telling you that I don’t care where my data comes from, and I don’t want someone telling me I’m wrong for not caring, unless they also show me a concrete scenario where the data source affects the behavior of the app in a way that could not happen if my program only accepted input from one of the three sources.
I am not sure why Dancer had both param and params?
These two may have the same effect: param 'foo' params->{foo} …but they do not compile to the same code.
Let's say we have app with authentication middleware. Middleware checks user ID from path and reads session ID from cookie, then it makes sure from backend, that user ID and session match, so it flags connection correct and gives it forward to app. In app path-ID and query-ID have conflict, but last one wins because precedence and now we run our query in rights of ID we read from query params. Seems like taking over to me. Avoidable, if we make distinction, from where param is readed.
If all it takes to fool your authentication system is to change a session ID in the query, how does restricting the parameter source fix that? Any attacker that can insert a second conflicting session ID into the query can just change the first session ID. Restricting the input source buys nothing. This is the same criticism I already answered from someone else in this thread, in fact: show me an attack that can modify the URL query parameters but can’t modify the POST body. The solution to both classes of problem is the same, because it’s the same attack: use HTTPS.
On Thu, 14 Jul 2016 08:09:37 -0600 Warren Young <wyml@etr-usa.com> wrote:
On Jul 12, 2016, at 5:08 PM, WK <wanradt@gmail.com> wrote:
2016-07-12 20:54 GMT+03:00 Warren Young <wyml@etr-usa.com>:
I gave cat(1) as an example of doing it right. For a more complex example, consider sqlite3.
Should sqlite3 (or cat) accept all three paths same time?
Of course not, and they don’t, any more than Dancer’s params() mooshes all three together:
$ echo foo | cat <(echo bar) bar $ echo 'select 2*3' | sqlite3 x.db 'select 3*4' 12
But Isn't that what parameters() does now with Hash::MultiValue? So for the example given below, parameters()->get_all('id') would return ( 123, 223, 333 ), right? Or maybe ( 223, 333, 123 ). While it is more complex now (having half a dozen ways to get at the same value), I think this is a decent thing for a framework to do. It gives the app developer every option to define how their app behaves, instead of having the framework dictate things.
Which one should first, which last?
That's up to the Dancer designers to specify.
Should those inputs just concatenated together or should they divert each other in some order?
The three parameter sources should have a defined and documented precedence order.
So POSTing path with query and form params
/item/id/123?id=223
[id=333]
we start with 3 different id-s, but at end we have one of them. Is it good design for app? I don't think so.
You see this kind of thing a lot, do you?
If a caller does something like what you suggest, it doesn’t matter which one Dancer chooses to pass to your app. The caller has made an ambiguous call, so it is at the mercy of Dancer’s precedence rules.
-- C. Chad Wallace, B.Sc. The Lodging Company http://www.lodgingcompany.com/ OpenPGP Public Key ID: 0x262208A0
2016-07-14 17:09 GMT+03:00 Warren Young <wyml@etr-usa.com>:
I’m just telling you that I don’t care where my data comes from, and I don’t want someone telling me I’m wrong for not caring, unless they also show me a concrete scenario where the data source affects the behavior of the app in a way that could not happen if my program only accepted input from one of the three sources.
I'm sorry, if my mail seemed arguing, I tried to think along with you, to drag in someone who could give better reasoning, where those security issues may lay... Only place I was really arguing, was aspect of old system being flexible.
Let's say we have app with authentication middleware. Middleware checks user ID from path and reads session ID from cookie, then it makes sure from backend, that user ID and session match, so it flags connection correct and gives it forward to app. In app path-ID and query-ID have conflict, but last one wins because precedence and now we run our query in rights of ID we read from query params. Seems like taking over to me. Avoidable, if we make distinction, from where param is readed.
If all it takes to fool your authentication system is to change a session ID in the query, how does restricting the parameter source fix that? Any attacker that can insert a second conflicting session ID into the query can just change the first session ID. Restricting the input source buys nothing.
Actually, I never mentioned changing session ID in the query. My described mechanism was founded on assumption, that there may be two uncoupled places, which independently choose 1 of 3 possible ID-s, and they choose differently. It is not about restricting input sources, it is about consistency. wbr, -- Kõike hääd, Gunnar
Quoting Warren Young <wyml@etr-usa.com>:
On Jul 11, 2016, at 3:29 AM, Dave Cross <dave@dave.org.uk> wrote:
The more explicitly-named methods are definitely safer. You really want to know where your parameters are coming from.
I’m still waiting for someone to justify that stance with more than confident prose assertions. Someone, please show me code that the new keywords makes better.
[ ... snip ... ] It's to do with security. If you've written the application, you know the channels that the params should be coming through. If you've written the app so that it sends 'foo' as a body parameter and it arrives as a query parameter, then that might be evidence of someone doing something with your app that you would rather they didn't do. Perhaps they're probing it for security holes. Imagine you have a form that contains important information in <hidden> form fields. You have filled in those fields in the HTML response that you sent back to the browser. That data should turn up in a body parameter. If it turns up in a query parameter, then someone is trying to override that value. Perhaps for nefarious reasons. If you were getting the value from a 'param' or 'params' call, you wouldn't know where the value comes from. Is it the legitimate body parameter or the added (perhaps nefarious) query parameter? You don't know. And that should worry you. By all means continue to take the lax approach if you want. I learned long ago that the internet is a nasty place and I'm going to be as distrustful as possible of the data I get back from my users. Dave...
On Jul 12, 2016, at 9:27 AM, Dave Cross <dave@dave.org.uk> wrote:
Quoting Warren Young <wyml@etr-usa.com>:
On Jul 11, 2016, at 3:29 AM, Dave Cross <dave@dave.org.uk> wrote:
The more explicitly-named methods are definitely safer. You really want to know where your parameters are coming from.
I’m still waiting for someone to justify that stance with more than confident prose assertions. Someone, please show me code that the new keywords makes better.
It's to do with security.
So show me a Dancer program that exposes a security hole when data is accepted via an unexpected channel. So far, all I’ve gotten is “because security.”
If you've written the application, you know the channels that the params should be coming through.
Not necessarily. The remote app might not be yours, as is common when publishing an API. I am not saying that you, as an API designer do not have the right to insist that data be passed only via documented channels. You certainly do. What I’m arguing against is this idea that if I, as the API implementer choose to call param or params to retrieve the data but I document the data as coming from only one source, that my program is somehow “wrong.”
If you've written the app so that it sends 'foo' as a body parameter and it arrives as a query parameter, then that might be evidence of someone doing something with your app that you would rather they didn't do. Perhaps they're probing it for security holes.
A sanely written Dancer route handler will do the same thing with a parameter no matter where it came from. This is the principle of referential transparency: https://en.wikipedia.org/wiki/Referential_transparency Are you arguing that this is a bad design principle?
Imagine you have a form that contains important information in <hidden> form fields. You have filled in those fields in the HTML response that you sent back to the browser. That data should turn up in a body parameter. If it turns up in a query parameter, then someone is trying to override that value.
I’m having trouble imagining an attacker capable of modifying the URL but not the POST body. Care to help me out on that one?
I learned long ago that the internet is a nasty place and I'm going to be as distrustful as possible of the data I get back from my users.
I suspect I learned long before that a principle called Postel’s Law: https://en.wikipedia.org/wiki/Robustness_principle
participants (8)
-
Chad Wallace -
Daniel Perrett -
Dave Cross -
John J. McDermott, CPLP -
Kadir Beyazlı -
Niels Larsen -
Warren Young -
WK