-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
New Codemod: Sonar Flask Secure Cookie (#969)
* Initial version of SonarSecureCookie * Added unit test * Added integration test * Fixed missing file for integration test * Fixed tests and refactoring
- Loading branch information
1 parent
22bdada
commit 826e82b
Showing
12 changed files
with
282 additions
and
39 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
from codemodder.codemods.test import SonarIntegrationTest | ||
from core_codemods.sonar.sonar_secure_cookie import ( | ||
SonarSecureCookie, | ||
SonarSecureCookieTransformer, | ||
) | ||
|
||
|
||
class TestSonarSecureCookie(SonarIntegrationTest): | ||
codemod = SonarSecureCookie | ||
code_path = "tests/samples/secure_cookie.py" | ||
replacement_lines = [ | ||
( | ||
8, | ||
""" resp.set_cookie('custom_cookie', 'value', secure=True, httponly=True, samesite='Lax')\n""", | ||
), | ||
] | ||
expected_diff = "--- \n+++ \n@@ -5,5 +5,5 @@\n @app.route('/')\n def index():\n resp = make_response('Custom Cookie Set')\n- resp.set_cookie('custom_cookie', 'value')\n+ resp.set_cookie('custom_cookie', 'value', secure=True, httponly=True, samesite='Lax')\n return resp\n" | ||
expected_line_change = "8" | ||
change_description = SonarSecureCookieTransformer.change_description |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
from codemodder.codemods.base_codemod import ToolRule | ||
from codemodder.codemods.libcst_transformer import ( | ||
LibcstResultTransformer, | ||
LibcstTransformerPipeline, | ||
) | ||
from core_codemods.secure_cookie_mixin import SecureCookieMixin | ||
from core_codemods.secure_flask_cookie import SecureFlaskCookie | ||
from core_codemods.sonar.api import SonarCodemod | ||
|
||
rules = [ | ||
ToolRule( | ||
id="python:S3330", | ||
name='Creating cookies without the "HttpOnly" flag is security-sensitive', | ||
url="https://rules.sonarsource.com/python/RSPEC-3330/", | ||
), | ||
ToolRule( | ||
id="python:S2092", | ||
name='Creating cookies without the "secure" flag is security-sensitive', | ||
url="https://rules.sonarsource.com/python/RSPEC-2092/", | ||
), | ||
] | ||
|
||
|
||
class SonarSecureCookieTransformer(LibcstResultTransformer, SecureCookieMixin): | ||
change_description = "Flask response `set_cookie` call should be called with `secure=True`, `httponly=True`, and `samesite='Lax'`." | ||
|
||
def leave_Call(self, original_node, updated_node): | ||
if self.node_is_selected(original_node.func): | ||
self.report_change(original_node) | ||
new_args = self.replace_args( | ||
original_node, self._choose_new_args(original_node) | ||
) | ||
return self.update_arg_target(updated_node, new_args) | ||
return updated_node | ||
|
||
|
||
SonarSecureCookie = SonarCodemod.from_core_codemod_with_multiple_rules( | ||
name="secure-cookie", | ||
other=SecureFlaskCookie, | ||
rules=rules, | ||
transformer=LibcstTransformerPipeline(SonarSecureCookieTransformer), | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
import json | ||
|
||
from codemodder.codemods.test import BaseSASTCodemodTest | ||
from core_codemods.sonar.sonar_secure_cookie import SonarSecureCookie | ||
|
||
|
||
class TestSonarSecureCookie(BaseSASTCodemodTest): | ||
codemod = SonarSecureCookie | ||
tool = "sonar" | ||
|
||
def test_name(self): | ||
assert self.codemod.name == "secure-cookie" | ||
|
||
def test_simple(self, tmpdir): | ||
input_code = """ | ||
import flask | ||
response = flask.make_response() | ||
var = "hello" | ||
response.set_cookie("name", "value") | ||
response2 = flask.Response() | ||
var = "hello" | ||
response2.set_cookie("name", "value") | ||
""" | ||
expected = """ | ||
import flask | ||
response = flask.make_response() | ||
var = "hello" | ||
response.set_cookie("name", "value", secure=True, httponly=True, samesite='Lax') | ||
response2 = flask.Response() | ||
var = "hello" | ||
response2.set_cookie("name", "value", secure=True, httponly=True, samesite='Lax') | ||
""" | ||
issues = { | ||
"hotspots": [ | ||
{ | ||
"component": "code.py", | ||
"status": "TO_REVIEW", | ||
"textRange": { | ||
"startLine": 6, | ||
"endLine": 6, | ||
"startOffset": 0, | ||
"endOffset": 19, | ||
}, | ||
"ruleKey": "python:S2092", | ||
}, | ||
{ | ||
"component": "code.py", | ||
"status": "TO_REVIEW", | ||
"textRange": { | ||
"startLine": 10, | ||
"endLine": 10, | ||
"startOffset": 0, | ||
"endOffset": 20, | ||
}, | ||
"ruleKey": "python:S2092", | ||
}, | ||
{ | ||
"component": "code.py", | ||
"status": "TO_REVIEW", | ||
"textRange": { | ||
"startLine": 6, | ||
"endLine": 6, | ||
"startOffset": 0, | ||
"endOffset": 19, | ||
}, | ||
"ruleKey": "python:S3330", | ||
}, | ||
{ | ||
"component": "code.py", | ||
"status": "TO_REVIEW", | ||
"textRange": { | ||
"startLine": 10, | ||
"endLine": 10, | ||
"startOffset": 0, | ||
"endOffset": 20, | ||
}, | ||
"ruleKey": "python:S3330", | ||
}, | ||
], | ||
} | ||
self.run_and_assert( | ||
tmpdir, input_code, expected, results=json.dumps(issues), num_changes=2 | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
from flask import Flask, session, make_response | ||
|
||
app = Flask(__name__) | ||
|
||
@app.route('/') | ||
def index(): | ||
resp = make_response('Custom Cookie Set') | ||
resp.set_cookie('custom_cookie', 'value') | ||
return resp |
Oops, something went wrong.