Skip to content
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

Send version and mode to code scanning via user agent #516

Merged
merged 3 commits into from
May 31, 2021

Conversation

aeisenberg
Copy link
Contributor

@aeisenberg aeisenberg commented May 20, 2021

The initial goal of this change is to send more complete information to code scanning via the user agent. This also opens the possibility of sending the action/runner version to the CLI.

This commit changes the way the action determines if running in action
or runner mode. There is now an environment variable that is set at the
beginning of the process and elsewhere in the process, we can check to
see if the variable is set.

Merge / deployment checklist

  • Confirm this change is backwards compatible with existing workflows.
  • Confirm the readme has been updated if necessary.
  • Confirm the changelog has been updated if necessary.

@aeisenberg aeisenberg marked this pull request as draft May 20, 2021 22:21
@aeisenberg aeisenberg force-pushed the aeisenberg/update-changelog-on-release branch 12 times, most recently from 1efbebf to 800a951 Compare May 21, 2021 18:04
@aeisenberg aeisenberg changed the title [WIP] Add the isAction function Send version and mode to code scanning via user agent May 21, 2021
@aeisenberg aeisenberg mentioned this pull request May 21, 2021
2 tasks
@aeisenberg aeisenberg marked this pull request as ready for review May 21, 2021 20:44
@aeisenberg aeisenberg changed the base branch from aeisenberg/update-changelog-on-release to main May 21, 2021 20:45
Copy link
Contributor

@adityasharad adityasharad left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Neat! I defer to Robert on whether the mode initialisations are in the right place, but the logic looks sensible to me.

src/api-client.ts Outdated Show resolved Hide resolved
src/actions-util.ts Outdated Show resolved Hide resolved
src/actions-util.ts Outdated Show resolved Hide resolved
@RA80533
Copy link
Contributor

RA80533 commented May 26, 2021

The conditional branching within the updated getCodeQLBundleDownloadURL function should be tested based on the new method of determining the mode. Every occurrence in which an explicit mode was passed in now implicitly relies upon the environment in which it is called.

Should that implicit behavior be moved to a higher level of abstraction, e.g., into functions directly consumed by the end-user? There are some low-level functions that rely on the results of getCodeQLBundleDownloadURL.

@aeisenberg
Copy link
Contributor Author

Thanks for the comment @RA80533. I added a couple of more unit tests. I feel like the code is reasonably safe now. We are sure to set the mode at the beginning of every entry point. If there is a call to get the mode and it hasn't been set yet, then that will fail.

In some ways, the logic is more complex because some low level functions now rely on a new environment variable, but the trade off is that we no longer need to pass the mode parameter around. I had originally tried keeping the mode parameter and passing it around, but then almost every function needed access to it. Using the environment variable in a single place seems like a reasonable trade-off. There are other parts of the code that also rely on environment variables, so this situation is not too different.

@RA80533
Copy link
Contributor

RA80533 commented May 27, 2021

In some ways, the logic is more complex because some low level functions now rely on a new environment variable, but the trade off is that we no longer need to pass the mode parameter around. I had originally tried keeping the mode parameter and passing it around, but then almost every function needed access to it. Using the environment variable in a single place seems like a reasonable trade-off. There are other parts of the code that also rely on environment variables, so this situation is not too different.

It is very much a case of deciding which to trade off. Environment variables become unwieldy in larger projects because they create a mathematical side effect in the flow of logic; for smaller projects, such as this one, the flow of data is easy enough to follow to the point that such dependent behavior is easy to track down.

/lgtm

@aeisenberg
Copy link
Contributor Author

Ooooh...code scanning found a bug. Thank you code scanning.

@aeisenberg aeisenberg force-pushed the aeisenberg/user-agent branch 2 times, most recently from c646c93 to 026871f Compare May 28, 2021 19:11
export function setMode(mode: Mode) {
// avoid accessing actions core when in runner mode
if (mode === Mode.actions) {
core.exportVariable(CODEQL_RUN_MODE_ENV_VAR, mode);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note this is a code scanning error, but a false positive. We cannot have a code path accessible from the runner that will call into the core library. The if clause above prevents this from happening.

@aeisenberg
Copy link
Contributor Author

Updated ql queries that look for runner/actions access. Could I get another look at this?

@RA80533
Copy link
Contributor

RA80533 commented May 28, 2021

Without the guard, what would be available to non-Actions runners through the core library?

EDIT: Oh, I see. The code library doesn’t support non-GitHub Actions environments.

@aeisenberg
Copy link
Contributor Author

Yes, mostly right...there are some actions libraries that are ok to use for the runner.

predicate isSafeActionLib(string lib) {
lib = "@actions/http-client" or
lib = "@actions/exec" or
lib = "@actions/io" or
lib.matches("@actions/exec/%")
}

Copy link
Contributor

@adityasharad adityasharad left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice. Logic makes sense and neat adjustment to the query; a few minor suggestions there.

There's probably room to combine more of the logic in that query, and use some builtin features of the CodeQL JS libraries, but we can do that separately. No need to hold up this PR.

@@ -149,7 +150,9 @@ program
"(Advanced, windows-only) Inject a windows tracer of this process into a parent process <number> levels up."
)
.action(async (cmd: InitArgs) => {
setMode(Mode.runner);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor: I wonder if there's a prehook we can use to always set the mode to runner at the start of each action() call in this file. Or we can check it by query, as a follow up.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmmm...it looks like there is an event mechanism for commander, but it's not quite what we need and it is internal, so I think we will need to create a query here.

/**
* Get an expr that is only executed on actions
*/
abstract Expr getAnActionsExpr();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could instead declare:

abstract Stmt getActionsBlock();

/**
  * Gets an expr that is only executed on actions
 */
final Expr getAnActionsExpr() { getActionsBlock().getAChildStmt*().getAChildExpr*() = result }

This way each subclass needs to describe what they consider an Actions-specific statement, and you don't need to repeat the logic for an Actions-specific expression.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. That's better. Thanks.

This commit changes the way the action determines if running in action
or runner mode. There is now an environment variable that is set at the
beginning of the process and elsewhere in the process, we can check to
see if the variable is set.
Update the ql queries to account for change in how we look for runner

Previously, we guarded blocks of code to be run by the runner or the
action using if statements like this:

```js
if (mode === "actions") ...
```

We are no longer doing this. And now, the `unguarded-action-lib.ql`
query is out of date. This query checks that runner code does not
unintentionally access actions-only methods in the libraries.

With these changes, we now ensure that code scanning is happy.
@aeisenberg
Copy link
Contributor Author

Wait...commander v8 is soon to be released with a hook for preAction and postAction in it. I will get this merged, and then do the update for v8.

@aeisenberg aeisenberg enabled auto-merge May 31, 2021 16:44
@aeisenberg aeisenberg merged commit ca94508 into main May 31, 2021
@aeisenberg aeisenberg deleted the aeisenberg/user-agent branch May 31, 2021 16:49
@github-actions github-actions bot mentioned this pull request Jun 7, 2021
5 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants