Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Third party PHP plugins in a closed web application? 1

Status
Not open for further replies.

ThomasJSmart

Programmer
Sep 16, 2002
634
Has anyone worked on something like this before?
We have a closed web application coded in php/javascript, the usual. This application supports plugins to provide different features in the front-end. Kind of like widgets I guess.

We want to open this up to users so they can add plugins for their own interface. Plugins should support php/javascript. Ideally we would allow them to do this directly without us needing to check everything. but is there any secure way of doing this??

1. user submits code, we check it and add it, user tests, sends an update and the cycle starts again. secure sure, but very inefficient and takes up a lot of our time.

2. we provide some sdk/testing environment so they can build and test their plugin in an environment similar to the live application then they submit it, we check it and add to system. Still secure as the live application isnt at risk but we would need to maintain a separate testing environment and there is the chance they break the testing environment for other users.

3. (ideal but possible??) sandbox the user's web application account somehow. limit what functionality they can call with their plugin and lock it down. This way they can just upload their plugins, self test and any issues would be only within their own account and they would only be able to access their own data.

3b. item 3 might be easier possible if we didnt allow php but only some scripting language that we add. so user's plugin would have to use this safe/limited scripting language to interact with a backend api instead of direct with php. are there existing script classes/apis that can provide something like this?


Thanks!
Thomas




site | / blog |
 
3 is possible.

combination of suexec, suphp and the disable_functions php.ini directive together with some careful parameterisation of other php directives to prevent a badly written script from bringing down the server thruogh resource consumption or whatever. (
i would not want to administer this however. better to sandbox/virtualise the server instance and let the user do whatever they want.
 
but this basically means running it in a completely separate environment. then might as well tell them to host their own plugin and just interact with our API, was hoping to make it a bit more simple for the user :/

3b is sounding more and more like the way to go. limited scripting language that can communicate with an internal api for connectivity. abstract the whole thing.
ignore any php in it.

site | / blog |
 
you can make 3 work just fine on a per user basis. but what you are asking for overall is not a good paradigm.

if you don't like setting up virtualised environments for your users consider making your application overall into a web service and publishing templates for your users to host elsewhere. so your app becomes the 'plugin' rather than vice versa.
 
we have that functionality already through the rest API. So they can self-host an entire interface and just interact with our api for the data and back-end processing we offer.

the idea for the plugin is to allow users to add small pieces for functionality to our standard interface, either themselves or buy getting/purchasing from third parties.

site | / blog |
 
instigate a certification process that you charge for?

or, as i have said, you can make type 3 work. just restrict functionality at runtime: but note that this will restrict ALL the application functionality - both yours and theirs.

I cannot think of a 'neat' way to deal with JUST the plugins other than perhaps this

1. before 'include'ing any user files run a validator on them that parses them and collects a list of all functions that are called. this is not too difficult. compare the list of functions against a white list. if there is a match then migrate the file to a 'clean' folder and that means you don't have to check it again.

there are edge cases here (anonymous and/or variable functions) that might be difficult to capture. so instead of parsing you might want to use a node interceptor.


 
or perhaps you could use a templating language like twig. not my cup of tea, and i have no experience in this either. twig has what it calls a sandboxing mode.


i think i'd prefer to go the nodevisitor route if i had to choose. or write an extension to do the same thing. to write a nodevisitor you'd have to use something like xDebug anyway.
 
I like the node idea. that could work well and be automated. User would go through an upload process, upload a packaged php plugin, phing perhaps, then the uploader parses it, checking the file structure first, then it puts it through a reader/xdebug to evaluate the code. its either rejected and nothing happens, or its passes and is then added to their account for testing. at this point we limit it only to their account. for public submission as a shared plugin we would still manually check it.

the plugin itself could be written in php so no need to learn new scripting languages and pretty much all data-interactions would go via an internal API/set of functions/methods to be vetted and secured.

great :D many thanks!

site | / blog |
 
umm, nope! or at least i doubt it.

with a node inspector you'd need to let it run the whole time and intercept everything. because you cannot guarantee that all functions and methods within the uploaded files would be called during an evaluation process. that's parsing not interception.

of course running a node inspector the whole time would have a very material performance impact.

parsers can be spoofed by variable and anonymous functions unless you prescribe a variable/class naming policy too. so if you wanted to ban eval you would also need to ban use of function names $eval. If you were to adopt that as a rule then (off the top of my head) you could possibly use a regex on the incoming file. using a tokenizer to parse would not be robust as it would be (easily) possible to use variable functions to spoof it

maybe play with something like codesniffer from pear.
 
damn, thought that seemed too good to be true >.<
we do have some protection in we wont be letting anonymous people upload plugins, their accounts will need to be fully verified first (id/address/company registration proof)

I will prototype a scripted solution first i think, see how that works out. keep the syntax the same as php just process it through our api instead.



site | / blog |
 
if you are using hooks for your plugins (and thus using call_user_func() for each initial branch into the plugin), then you could also use runkit and disable functions before the branching, re-enabling only when the control was passed back to your core app.

otherwise you cannot disable functions at runtime.

i think you are left with these potentials:

[ol 1]
[li]present your app solely as an api to which limited hosted instances can connect[/li]
[li]use runkit as above[/li]
[li]constantly have a node interceptor running for those apps that desire plugin use[/li]
[li]use a parser to detect most of the nastiness[/li]
[li]have a human managed certification system chargeable by the kiloByte of code.[/li]
[/ol]

 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top