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

chore(aws): Add failed_checks to track #4018

Merged
merged 14 commits into from
May 22, 2024

Conversation

kagahd
Copy link
Contributor

@kagahd kagahd commented May 16, 2024

Context

This PR makes the AWS ec2 service and around around 15 prowler checks, that verify whether ports are open to the Internet, more concise. This PR relates to PR #3977 and PR #3979.

Description

I find it more concise to introduce a state_manager instead to share with a dozen of other checks a specific property public_ports of a specific check ec2_securitygroup_allow_ingress_from_internet_to_all_ports within the ec2_service.
I find the the code now clearer, cleaner, easier to extend and easier to maintain. It also saves some CPU cycles because the method check_security_group in the ec2_service does not need to be called for each check anymore.

License

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

@kagahd kagahd requested review from a team as code owners May 16, 2024 10:09
@github-actions github-actions bot added the provider/aws Issues/PRs related with the AWS provider label May 16, 2024
Copy link

codecov bot commented May 16, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 86.28%. Comparing base (248c7c5) to head (efa1c8f).
Report is 3 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #4018      +/-   ##
==========================================
+ Coverage   86.27%   86.28%   +0.01%     
==========================================
  Files         783      783              
  Lines       24562    24599      +37     
==========================================
+ Hits        21190    21226      +36     
- Misses       3372     3373       +1     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@jfagoagas jfagoagas self-assigned this May 17, 2024
@jfagoagas
Copy link
Member

jfagoagas commented May 17, 2024

Hi @kagahd I like your idea but we are not sure about including it at this time since we want to create an execution manager in top of Prowler's scan. Maybe it'll be easier for now to save something within the EC2 service, what do you think?

@jfagoagas jfagoagas changed the title add state_manager to make code more concise chore(ec2): Add state_manager to make code more concise while checking security groups May 17, 2024
@kagahd
Copy link
Contributor Author

kagahd commented May 17, 2024

Hi @jfagoagas,

Maybe it'll be easier for now to save something within the EC2 service, what do you think?

I preferred a separation of concerns by using the state_manager but we can put its functionality also in the ec2 service, if you prefer.
I just adapted the PR accordingly.

@jfagoagas jfagoagas self-requested a review May 17, 2024 08:38
@jfagoagas jfagoagas changed the title chore(ec2): Add state_manager to make code more concise while checking security groups chore(aws): Add failed_checks to track May 17, 2024
Copy link
Member

@jfagoagas jfagoagas left a comment

Choose a reason for hiding this comment

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

Could you add a test for each check while checking that ec2_client.is_failed_check() returns true, thus no findings will be generated?

The work is this PR is neat 💯

prowler/providers/aws/lib/service/service.py Outdated Show resolved Hide resolved
@kagahd
Copy link
Contributor Author

kagahd commented May 17, 2024

Could you add a test for each check while checking that ec2_client.is_failed_check() returns true, thus no findings will be generated?

Sure, I will add them later today.

@kagahd
Copy link
Contributor Author

kagahd commented May 17, 2024

Could you add a test for each check while checking that ec2_client.is_failed_check()

It's done.

@jfagoagas jfagoagas self-requested a review May 20, 2024 07:36
Copy link
Member

@jfagoagas jfagoagas left a comment

Choose a reason for hiding this comment

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

@kagahd I left some comments about the tests and a tiny detail in the service logic, please let me know if you need help. Thanks!

prowler/providers/aws/lib/service/service.py Outdated Show resolved Hide resolved
prowler/providers/aws/lib/service/service.py Outdated Show resolved Hide resolved
Comment on lines +463 to +472
check_all_ports = (
ec2_securitygroup_allow_ingress_from_internet_to_all_ports()
)
result_all_ports = check_all_ports.execute()

# Verify that the all ports check has detected the issue
assert any(
sg.status == "FAIL" and sg.resource_id == default_sg_id
for sg in result_all_ports
)
Copy link
Member

Choose a reason for hiding this comment

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

Maybe is easier just to call AWSService.set_failed_check and then run the ec2_securitygroup_allow_ingress_from_internet_to_any_port and verify that the finding's status extended is the new one.

Copy link
Member

Choose a reason for hiding this comment

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

This comment applies to all the tests.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Maybe is easier just to call AWSService.set_failed_check and then run the ec2_securitygroup_allow_ingress_from_internet_to_any_port and verify that the finding's status extended is the new one.

Yes, sure, it would be easier but it's cheating because it would not reflect the exact way how the values are set/get in real life by the app.
To be consistent, we need to first execute the check ec2_securitygroup_allow_ingress_from_internet_to_all_ports by checking an open security group to all ports. And after that, we have to verify that a specific port check such as ec2_securitygroup_allow_ingress_from_internet_to_any_port is in status PASS, only because the previous run check ec2_securitygroup_allow_ingress_from_internet_to_all_ports is in status FAIL, in order to avoid to report the specific open ports twice.
You need to do it this way to respect and verify by unit tests the call chain of the app.

@kagahd
Copy link
Contributor Author

kagahd commented May 21, 2024

Hi @jfagoagas
could you please advise, why the pr-lint-test tests are failing after my last last commits from today? When I run them locally, only 2 of a total 3175 unit tests are failing (which were failing also before my todays commits):

poetry run pytest -n auto --cov=./prowler --cov-report=xml tests
...
=========================================================================================== short test summary info ===========================================================================================
FAILED tests/providers/aws/services/route53/route53_dangling_ip_subdomain_takeover/route53_dangling_ip_subdomain_takeover_test.py::Test_route53_dangling_ip_subdomain_takeover::test_hosted_zone_dangling_public_record - urllib.error.URLError: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:997)>
FAILED tests/providers/aws/services/route53/route53_dangling_ip_subdomain_takeover/route53_dangling_ip_subdomain_takeover_test.py::Test_route53_dangling_ip_subdomain_takeover::test_hosted_zone_external_record - urllib.error.URLError: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:997)>
=========================================================================== 2 failed, 3173 passed, 36 warnings in 399.73s (0:06:39) ===========================================================================
~

And these 2 failing unit tests are not from me. I didn't touch them.
Why the github workflow failed on so many unit tests?
Thanks for your help!

@jfagoagas
Copy link
Member

Hi @jfagoagas could you please advise, why the pr-lint-test tests are failing after my last last commits from today? When I run them locally, only 2 of a total 3175 unit tests are failing (which were failing also before my todays commits):

poetry run pytest -n auto --cov=./prowler --cov-report=xml tests
...
=========================================================================================== short test summary info ===========================================================================================
FAILED tests/providers/aws/services/route53/route53_dangling_ip_subdomain_takeover/route53_dangling_ip_subdomain_takeover_test.py::Test_route53_dangling_ip_subdomain_takeover::test_hosted_zone_dangling_public_record - urllib.error.URLError: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:997)>
FAILED tests/providers/aws/services/route53/route53_dangling_ip_subdomain_takeover/route53_dangling_ip_subdomain_takeover_test.py::Test_route53_dangling_ip_subdomain_takeover::test_hosted_zone_external_record - urllib.error.URLError: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:997)>
=========================================================================== 2 failed, 3173 passed, 36 warnings in 399.73s (0:06:39) ===========================================================================
~

And these 2 failing unit tests are not from me. I didn't touch them. Why the github workflow failed on so many unit tests? Thanks for your help!

I think your forked repo wasn't up to date with Prowler's master. I've sync'ed your master branch and then merge that branch against this. Probably failing test happened due to this and also Github actions are degraded today so that could be also.

@kagahd
Copy link
Contributor Author

kagahd commented May 21, 2024

Hi @jfagoagas, the github workflow failed again with the same errors. Do you have another idea what the reason could be? In line 155 it says AttributeError: module 'prowler.providers.common' has no attribute 'common' but other unit tests do the same what's marked in line 105:

        with mock.patch(
            "prowler.providers.common.common.get_global_provider",
            return_value=aws_provider,
        ),

What's wrong with it?

@jfagoagas
Copy link
Member

Hi @jfagoagas, the github workflow failed again with the same errors. Do you have another idea what the reason could be? In line 155 it says AttributeError: module 'prowler.providers.common' has no attribute 'common' but other unit tests do the same what's marked in line 105:

        with mock.patch(
            "prowler.providers.common.common.get_global_provider",
            return_value=aws_provider,
        ),

What's wrong with it?

Yesterday we merged a PR which changes the location of the get_global_provider function, that was the issue. I've pushed a fix.

@jfagoagas jfagoagas self-requested a review May 22, 2024 06:36
@kagahd
Copy link
Contributor Author

kagahd commented May 22, 2024

Yesterday we merged a PR which changes the location of the get_global_provider function, that was the issue. I've pushed a fix.

That makes sense, thanks a bunch!

Copy link
Member

@jfagoagas jfagoagas left a comment

Choose a reason for hiding this comment

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

Thanks for this super improvement again @kagahd 👏

It's been a pleasure to work with you and review a PR with such a great level of quality 🚀

result = check.execute()

# Verify set_failed_check was called with the correct arguments
mock_set_failed_check.assert_called_with(
Copy link
Member

Choose a reason for hiding this comment

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

Pretty smart 💯

@jfagoagas
Copy link
Member

I have just one question left because I'm not sure, what was the previous behaviour when running an specific port check with the public_ports set to True? I thought we were not raising a finding but I'm not sure I have to test it, I mean to not modify that behaviour now.

@kagahd
Copy link
Contributor Author

kagahd commented May 22, 2024

what was the previous behaviour when running an specific port check with the public_ports set to True? I thought we were not raising a finding

Exactly, you were not raising a finding, the status was "PASS".
This behaviour is still the same, the status is still "PASS". However, I adapted the report.status_extended in order to mention that "has all ports open to the Internet and therefore was not checked against the specific XYZ port". Without my adaption of report.status_extended you would still have a message like "Security group ABC does not have XYZ port open to the Internet." which is quite wrong because all ports are open.

@jfagoagas
Copy link
Member

what was the previous behaviour when running an specific port check with the public_ports set to True? I thought we were not raising a finding

Exactly, you were not raising a finding, the status was "PASS". This behaviour is still the same, the status is still "PASS". However, I adapted the report.status_extended in order to mention that "has all ports open to the Internet and therefore was not checked against the specific XYZ port". Without my adaption of report.status_extended you would still have a message like "Security group ABC does not have XYZ port open to the Internet." which is quite wrong because all ports are open.

Thanks for confirming that, maybe we can remove that PASS finding in the future, but at the end the important ones are the FAIL findings and not to raise 2 with the same information.

@jfagoagas jfagoagas merged commit 69166a0 into prowler-cloud:master May 22, 2024
11 checks passed
@jfagoagas jfagoagas added the backport-v3 Pending to port to Prowler v3 branch label May 22, 2024
@sergargar sergargar removed the backport-v3 Pending to port to Prowler v3 branch label May 30, 2024
sergargar pushed a commit that referenced this pull request May 30, 2024
Co-authored-by: Pepe Fagoaga <pepe@prowler.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
provider/aws Issues/PRs related with the AWS provider
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants