Skip to content
This repository has been archived by the owner on Oct 6, 2020. It is now read-only.

DUO137 Itsdangerous false positive fix #40

Merged
merged 5 commits into from
Dec 11, 2019
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added
- `DUO137`: lint for insecure itsdangerous kwarg usage ([#36](https://github.com/duo-labs/dlint/issues/36))

### Fixed
- False positive for `DUO137`. ([#37](https://github.com/duo-labs/dlint/issues/39))
minusworld marked this conversation as resolved.
Show resolved Hide resolved

## [0.9.2] - 2019-11-21
### Fixed
- False negative with arbitrary depth from import alias in bad module attribute ([#32](https://github.com/duo-labs/dlint/issues/32))
Expand Down
7 changes: 1 addition & 6 deletions dlint/linters/bad_itsdangerous_kwarg_use.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,7 @@ def none_algorithm_predicate(call, kwarg_name):
])

def none_string_predicate(call, kwarg_name):
return functools.partial(
tree.kwarg_str,
call,
kwarg_name,
"none"
),
return tree.kwarg_str(call, kwarg_name, "none")

return [
{
Expand Down
50 changes: 50 additions & 0 deletions tests/test_bad_itsdangerous_kwarg_use.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,56 @@ def test_bad_itsdangerous_kwarg_usage(self):

assert result == expected

def test_false_positive_in_the_wild(self):
python_node = self.get_ast_node(
"""
from flask.ext.restful import fields, url_for
from itsdangerous import JSONWebSignatureSerializer as Serializer
from itsdangerous import BadSignature
from werkzeug.security import generate_password_hash, check_password_hash
from . import db
class User(db.Model):
__tablename__ = 'users'
id = db.Column(db.Integer, primary_key=True)
email = db.Column(db.String(256), unique=True)
password_hash = db.Column(db.String(256))

def generate_api_token(self):
serializer = Serializer(app.config['SECRET_KEY'])
return serializer.dumps({'id': self.id})

@staticmethod
def verify_api_token(token):
serializer = Serializer(app.config['SECRET_KEY'])
try:
data = serializer.loads(token)
except BadSignature:
# invalid token
return None
return User.query.get(data['id'])

@property
def password(self):
raise AttributeError('password is not readable')

@password.setter
def password(self, password):
self.password_hash = generate_password_hash(password)

def verify_password(self, password):
return check_password_hash(self.password_hash, password)

def __repr__(self):
return '<User %r>' % self.email
"""
)
linter = dlint.linters.BadItsDangerousKwargUseLinter()
linter.visit(python_node)

result = linter.get_results()
expected = []
assert result == expected


if __name__ == "__main__":
unittest.main()