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

Yield, YieldFrom, AugAssign propagate taint #155

Merged
merged 4 commits into from
Jul 30, 2018

Conversation

bcaller
Copy link
Collaborator

@bcaller bcaller commented Jul 27, 2018

Previously += only propagated taint of the last assigment. Now, the original variable is added to right_hand_side_variables.

Yield and YieldFrom are treated a bit like augmented assignment, giving the function a final return variable yld_ a bit like ret_. Really it's a generator function, but we can treat it as a normal function. So anything yielded propagates taint to the overall "return" value of the function.

@bcaller bcaller force-pushed the yield branch 2 times, most recently from b9f740c to 0cfc1b0 Compare July 27, 2018 11:55
@KevinHock KevinHock self-requested a review July 27, 2018 17:29
@KevinHock
Copy link
Collaborator

Thanks so much for making this, it looks great :)

I'll review in-depth tomorrow as I'm still on-a-roll with my open PR.

Copy link
Collaborator

@KevinHock KevinHock left a comment

Choose a reason for hiding this comment

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

Ben Caller is the best.
🚢

@@ -9,7 +9,7 @@ This directory contains miscellaneous code that is imported from different parts

- `get_call_names`_ used in `vars_visitor.py`_ when visiting a Subscript, and `framework_helper.py`_ on function decorators in `is_flask_route_function`_

- `get_call_names_as_string`_ used in `expr_visitor.py`_ to create ret_function_name as RHS and yield_function_name as LHS, and in stmt_visitor.py when connecting a function to a loop.
- `get_call_names_as_string`_ used in `expr_visitor.py`_ to create ret_function_name as RHS and yld_function_name as LHS, and in stmt_visitor.py when connecting a function to a loop.
Copy link
Collaborator

Choose a reason for hiding this comment

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

Thanks for updating this 👍 I definitely would have forgot to.

path=self.filenames[-1])
rhs_visitor.result + [LHS],
path=self.filenames[-1],
line_number=node.lineno)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Nit: To make things more DRY, you won't need to specify node.lineno
https://github.com/python-security/pyt/blob/master/pyt/core/node_types.py#L42-L43

call_foo = 7
_exit = 8

self.assertInCfg([(entry_foo, entry),
Copy link
Collaborator

Choose a reason for hiding this comment

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

Super nit: Over time I've been trying to do

self.assertInCfg([
    (entry_foo, entry),
    (a, entry_foo),
    (_if, a),
    (yld_if, _if),
    (yld, _if),
    (yld, yld_if),  # Different from return
    (exit_foo, yld),
    (call_foo, exit_foo),
    (_exit, call_foo)
])

but it's a WIP.


def _remove_sink_from_secondary_nodes(self):
try:
self.reassignment_nodes.remove(self.sink)
except ValueError: # pragma: no cover
pass

def _remove_non_propagating_yields(self):
Copy link
Collaborator

Choose a reason for hiding this comment

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

❤️

@@ -4,6 +4,8 @@
from enum import Enum
from collections import namedtuple

from pyt.core.node_types import YieldNode
Copy link
Collaborator

Choose a reason for hiding this comment

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

Nit: Maybe ..core.node_types just since everything else does that style.

rhs_visitor.visit(node.value)
except AttributeError:
rhs_visitor.result = 'EmptyYield'
if node.value is None:
Copy link
Collaborator

Choose a reason for hiding this comment

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

You write such high quality code, but the amazing commit messages is what really separates you from the rest.

path=self.filenames[-1])
rhs_visitor_result + [LHS],
path=self.filenames[-1],
line_number=node.lineno)
Copy link
Collaborator

@KevinHock KevinHock Jul 28, 2018

Choose a reason for hiding this comment

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

Nit: So for this I don't think you need to pass line_number due to
https://github.com/python-security/pyt/blob/master/pyt/core/node_types.py#L42-L43

bcaller added 3 commits July 30, 2018 10:16
not just the last thing yielded as before.

It behaves like a cross between AugAssign (everything yielded is
added to yld_* return variable) and Return (we make a yld_* return
variable though don't immediately exit the function).
It was a str when it should've been a List[str]
It was a str instead of List[str]
Before, the variable would be tainted only if the last += was tainted.

Now

url = 'http://'
url += TAINT
url += '?x=y'

url marked as tainted.
@bcaller
Copy link
Collaborator Author

bcaller commented Jul 30, 2018

done

@KevinHock KevinHock merged commit 794a42b into python-security:master Jul 30, 2018
KevinHock added a commit that referenced this pull request Jul 31, 2018
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.

2 participants