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

Taint propagates from methods of tainted objects #167

Merged
merged 1 commit into from
Aug 18, 2018

Conversation

bcaller
Copy link
Collaborator

@bcaller bcaller commented Aug 15, 2018

Previously

x = TAINT.lower() would be tainted (due to special handling for assignment_call_nodes)

but

x = str(TAINT.lower()) wouldn't be tainted.

To fix this, TAINT is added to the RHS variables of
TAINT.lower().

This will mean that e.g. request will be a RHS variable of
request.get(), but I think that will be OK.

In the test which changed, the additional line is because resp has
become tainted.

However, this still leaves the following false negatives to fix another
day:

assert_vulnerable('result = str("%s" % str(TAINT.lower()))') # FAILS
assert_vulnerable('result = str("%s" % TAINT.lower().upper())') # FAILS

@KevinHock KevinHock self-requested a review August 16, 2018 02:22
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.

Looks great so far, this will help us with our

base64.urlsafe_b64decode(
  state.encode('ascii')
).split(';')[1]

false-negative in our last evaluation https://github.com/oakie/oauth-flask-template/blob/master/auth.py#L63-L72

:D :D :D 🎈

@@ -657,6 +657,10 @@ def add_blackbox_or_builtin_call(self, node, blackbox):
# `scrypt.outer(scrypt.inner(image_name), scrypt.other_inner(image_name))`
last_return_value_of_nested_call.connect(call_node)

if '.' in call_function_label:
# taint is a RHS variable of taint.lower()
rhs_vars.append(call_function_label.split('.', 1)[0])
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can you try deleting the

        if isinstance(call, BBorBInode):
            # Necessary to know e.g.
            # `image_name = image_name.replace('..', '')`
            # is a reassignment.
            vars_visitor = VarsVisitor()
            vars_visitor.visit(ast_node.value)
            call.right_hand_side_variables.extend(vars_visitor.result)

in https://github.com/python-security/pyt/blob/master/pyt/cfg/stmt_visitor.py#L475-L481

This PR should make that code redundant 👍

If my hunch is correct about that, can you update this comment
https://github.com/python-security/pyt/blob/master/pyt/cfg/stmt_visitor.py#L670

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yep that works. Thanks 👍

@@ -613,7 +613,7 @@ def add_blackbox_or_builtin_call(self, node, blackbox):
right_hand_side_variables=[],
line_number=node.lineno,
path=self.filenames[-1],
func_name=call_label.result[:index]
func_name=call_function_label
Copy link
Collaborator

Choose a reason for hiding this comment

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

++
So Fresh, So Clean

@KevinHock
Copy link
Collaborator

Also, some news, I've been busy making slides these past few weeks for PyBay, and so will return to my open expr_star_handler PR soon.

@bcaller bcaller force-pushed the method-propagation branch 2 times, most recently from d23ab96 to 976b128 Compare August 16, 2018 13:21
@bcaller
Copy link
Collaborator Author

bcaller commented Aug 16, 2018

Thanks, I've modified the commit.

@KevinHock
Copy link
Collaborator

I think merging the other PR caused some merge conflicts with this one.

Previously

`x = TAINT.lower()` would be tainted (due to special handling for
assignment_call_nodes)

but

`x = str(TAINT.lower())` wouldn't be tainted.

To fix this, `TAINT` is added to the RHS variables of
`TAINT.lower()`.

This will mean that e.g. `request` will be a RHS variable of
`request.get()`, but I think that will be OK.

In the test which changed, the additional line is because resp has
become tainted.

However, this still leaves the following false negatives to fix another
day:

`assert_vulnerable('result = str("%s" % str(TAINT.lower()))')  # FAILS`
`assert_vulnerable('result = str("%s" % TAINT.lower().upper())') # FAILS`
@bcaller
Copy link
Collaborator Author

bcaller commented Aug 17, 2018

Thanks for the reminder. Fixed.

@KevinHock KevinHock merged commit a2d7634 into python-security:master Aug 18, 2018
@bcaller bcaller deleted the method-propagation branch September 7, 2018 10:42
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