-
-
Notifications
You must be signed in to change notification settings - Fork 70
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Adds the ability to run bash script through appium-for-mac #30
Conversation
…selenium driver.execute_script()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for adding a feature. This will be useful.
- (AppiumMacHTTPJSONResponse *)post_execute:(NSString*)path data:(NSData*)postData | ||
{ | ||
return [self executeWebDriverCommandWithPath:path data:postData onMainThread:YES commandBlock:^(AfMSessionController *session, NSDictionary *commandParams, int *statusCode) | ||
{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure if the indentation is from github, but please ensure "return" and the block are aligned.
|
||
NSFileHandle *file = [pipe fileHandleForReading]; | ||
|
||
[task launch]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The launch method is deprecated. Please use only supported APIs.
https://developer.apple.com/documentation/foundation/nstask/1414189-launch?language=objc
- (NSString *)runCommand:(NSString *)commandToRun | ||
{ | ||
NSTask *task = [[NSTask alloc] init]; | ||
[task setLaunchPath:@"/bin/sh"]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are you sure 'sh' will run bash? Why not use /bin/bash to be explicit ?
@@ -143,6 +143,7 @@ extern NSString * const kCookieDiagnosticsDirectory; | |||
- (BOOL)isElementDisplayed:(id)element; | |||
-(BOOL) clickElement:(id)element; | |||
-(void) closeWindow; | |||
- (NSString *)runCommand:(NSString *)commandToRun; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please use a name like executeShellScript:(NSString *)script. It is more specific, and derived from the "post_execute" web driver command name.
return [self executeWebDriverCommandWithPath:path data:postData onMainThread:YES commandBlock:^(AfMSessionController *session, NSDictionary *commandParams, int *statusCode) | ||
{ | ||
// The bash command to run | ||
NSString *command = (NSString*)[commandParams objectForKey:@"script"]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rename to 'script' or 'scriptString', or something else besides 'command'. In this context, command refers to the web driver command itself.
{ | ||
// The bash command to run | ||
NSString *command = (NSString*)[commandParams objectForKey:@"script"]; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you can, please support the full "execute" command by allowing shell script arguments passed in through the 'args' commandParam. That will allow the same scriptString to have different behaviors without having to rebuild the string in your client script.
this might be a perfect backdoor %/ |
@mykola-mokhnach Yeah, AfM opens an unprotected port. In that sense AfM has been a form of back door since day one. This just improves that "feature". 😄 |
Do we want to keep it like this? I'd rather vote for closing such hole rather than extending it. |
Would that mean a password-protected https port? I thought WebDriver ports were by definition open. Could be wrong. But if an open port is a bad thing, then AfM is a bad thing. AfM is unique in the sense that the driver's universe is the whole machine, rather than the inside of a web view. Does AfM therefore not meet a particular security standard? I'm all for making it more secure if we can, but a faulty password scheme is almost worse than none, because it makes people think it is "safe". Curious: does Appium proper deal with this? Does it give you access to the whole device, or just one app at a time? |
Another possibility is to set a user default on the AfM machine, so that only a specific set of IP addresses can connect. |
@stuartbrussell-intuit In all the other driver we do limit the access to the command line, so the user cannot execute arbitrary shell commands on the target machine. Am I right @jlipps ? |
I committed some changes, but I need to dig into the API to find a replacement for the NSTask launch method, which is deprecated but there is apparently no substitution. About the security concern - what blocks me from opening the Terminal app and pass a command into it by driving the UI? |
Yeah I think it's less about secure access to AfM and more about what users can do once they have a session. With other drivers we try to limit what can be done via the driver to something other than general-purpose computing on the host machine :-) The question I usually ask when people want this kind of feature is what their use case is. Often we can then simply build a feature specifically for that use case, and not blow open a huge security hole. |
It's fine if we reject this change, but... this goes to the heart of AfM. Because of the way it is implemented, AfM has access to the entire UI of the machine, not just a specific app. So in its current form, it could easily launch Terminal and type into the window using standard webdriver commands. That's actually valuable because one script can control multi-app work flows, but with great power comes great... security holes? 😄 Seriously though, how should we treat AfM knowing how powerful it is? (btw, was this a surprise to people? I was explicit in my SelConf 2017 presentation that AfM is a fundamentally different beast from (e.g.) ChromeDriver, but not everyone saw it.) |
I guess if it's well-known that AfM can control the entire computer anyway then this doesn't add any security hole! So I'm fine with it in that case. |
👍 However, I do think it would be prudent to add something that disallows access from any other machine, for people who want to restrict who can control the computer. (e.g. a white list). |
@davidmokos I'm totally swamped, give me a couple of days and then I can review your latest. If the code is good, I'll approve it. |
I think we could use this feature together with the flag from appium/appium#9790, which should be implemented first on osx driver side |
@mykola-mokhnach Just to clarify for my confused brain: The fix for #9790 would mean, before "unsafe" actions, the user has to set a preference on the server side, or launch the server from the command line with an arg? So by default it would not be allowed? Just making sure I understand. |
@stuartbrussell-intuit Yes, your understanding is correct. The idea is that remote clients don't have access to the remote server, so they cannot change command line arguments there, but it should not be a problem if one runs Appium in a local environment. Check, for example, appium/appium-android-driver#293 |
@@ -240,6 +240,17 @@ - (AppiumMacHTTPJSONResponse *)post_url:(NSString*)path data:(NSData*)postData | |||
// POST /session/:sessionId/execute | |||
// Inject a snippet of JavaScript into the page for execution in the context of the currently selected frame. The executed script is assumed to be synchronous and the result of evaluating the script is returned to the client. | |||
|
|||
- (AppiumMacHTTPJSONResponse *)post_execute:(NSString*)path data:(NSData*)postData |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it should be also possible to pass additional environment variables
@@ -574,6 +574,32 @@ -(void) closeWindow | |||
[self.currentWindow performAction:@"AXCancel"]; | |||
} | |||
|
|||
- (NSString *)executeShellScript:(NSString *)script | |||
{ | |||
NSTask *task = [[NSTask alloc] init]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I assume NSTask starts with an empty environment by default. Shouldn't we inherit the current system env by default?
Is anyone working on this? Just to clarify the CRs for this pull request are: Not sure what is the current state of this project. I'd like some feedback if possible. Thank you |
Hi @Jiurong-Yang . Thanks for your feedback |
Superseded by appium/appium-mac-driver#38 |
we can now run bash script on the target machine running the appium-for-mac using the selenium driver.execute_script("mybashcommand")