dpgaspar / Flask-AppBuilder

Simple and rapid application development framework, built on top of Flask. includes detailed security, auto CRUD generation for your models, google charts and much more. Demo (login with guest/welcome) - http://flaskappbuilder.pythonanywhere.com/
BSD 3-Clause "New" or "Revised" License
4.72k stars 1.37k forks source link

When creating an API endpoint, and trying to access it with a user issued token in the request Header, it's saying access denied for the newly created permission on the api class denied. #2003

Open shenglong opened 1 year ago

shenglong commented 1 year ago

If you'd like to report a bug in Flask-Appbuilder, fill out the template below. Provide any extra information that may be useful

Responsible disclosure: We want to keep Flask-AppBuilder safe for everyone. If you've discovered a security vulnerability please report to danielvazgaspar@gmail.com.

Environment

Flask-Appbuilder version: 4.1.4

pip freeze output: aiocache==0.11.1 aiofiles==0.8.0 aiohttp==3.8.1 aiohttp-swagger==1.0.16 aiosignal==1.2.0 ansible==3.0.0 ansible-base==2.10.6 ansible-compat==2.2.1 ansible-core==2.13.4 ansible-lint==6.8.0 ansible-runner==2.3.1 apispec==3.3.2 appdirs==1.4.4 astroid==2.5 async-lru==1.0.3 async-timeout==4.0.2 attrs==22.1.0 Babel==2.10.3 bcrypt==3.2.0 black==23.1.0 bmc-helix-inventory==0.10.0 bracex==2.3.post1 cached-property==1.5.2 certifi==2020.12.5 cffi==1.14.5 chardet==4.0.0 charset-normalizer==2.1.0 cisco-gnmi==1.0.15 ciscoconfparse==1.6.40 click==8.1.3 colorama==0.4.5 commonmark==0.9.1 cryptography==3.4.6 defusedxml==0.7.1 dill==0.3.5.1 distlib==0.3.1 distro==1.7.0 dnspython==2.2.1 docker==4.4.4 docutils==0.19 email-validator==1.3.0 exceptiongroup==1.1.0 f5-icontrol-rest==1.3.13 f5-sdk==3.0.21 fastapi==0.68.2 filelock==3.0.12 Flask==2.2.2 Flask-AppBuilder==4.1.4 Flask-Babel==2.0.0 Flask-JWT-Extended==4.4.4 Flask-Login==0.6.2 flask-mongoengine==1.0.0 Flask-SQLAlchemy==2.5.1 Flask-WTF==1.0.1 frozenlist==1.3.0 future==0.18.2 genie==22.7 genie.libs.clean==22.7 genie.libs.conf==22.7 genie.libs.filetransferutils==22.7 genie.libs.health==22.7 genie.libs.ops==22.7 genie.libs.parser==22.7 genie.libs.sdk==22.7 gitdb==4.0.9 GitPython==3.1.18 greenlet==1.1.3.post0 grpcio==1.47.0 idna==2.10 importlib-metadata==5.0.0 importlib-resources==5.10.0 iniconfig==1.1.1 invoke==1.5.0 IPy==1.1 isodate==0.6.0 isort==5.7.0 itsdangerous==2.1.2 Jinja2==3.1.2 jsonify==0.5 jsonpickle==2.2.0 jsonschema==4.16.0 junit-xml==1.9 junos-eznc==2.6.4 lazy-object-proxy==1.5.2 lockfile==0.12.2 loguru==0.6.0 lxml==4.6.3 Markdown==3.4.1 MarkupSafe==2.1.1 marshmallow==3.18.0 marshmallow-enum==1.5.1 marshmallow-sqlalchemy==0.26.1 mccabe==0.6.1 mongo==0.2.0 mongoengine==0.24.2 multidict==6.0.2 mypy-extensions==0.4.3 ncclient==0.6.13 netaddr==0.8.0 netmiko==3.4.0 ntc-templates==3.0.0 numpy==1.21.3 packaging==23.0 pandas==1.3.4 paramiko==2.7.2 passlib==1.7.4 pathspec==0.10.1 pexpect==4.8.0 pii==0.0.1 pkgutil_resolve_name==1.3.10 platformdirs==2.5.2 pluggy==0.13.1 prettytable==3.3.0 prison==0.2.1 protobuf==3.20.1 psutil==5.9.1 ptyprocess==0.7.0 py==1.10.0 pyasn1==0.4.8 pyasn1-modules==0.2.8 pyats==22.7.1 pyats.aereport==22.7 pyats.aetest==22.7 pyats.async==22.7 pyats.connections==22.7 pyats.datastructures==22.7 pyats.easypy==22.7 pyats.kleenex==22.7 pyats.log==22.7 pyats.reporter==22.7 pyats.results==22.7 pyats.tcl==22.7 pyats.topology==22.7 pyats.utils==22.7 pycparser==2.20 pydantic==1.9.2 pyeapi==0.8.4 pyftpdlib==1.5.6 Pygments==2.13.0 PyJWT==2.5.0 pylint==2.7.0 pymongo==4.2.0 PyNaCl==1.4.0 pyntc==0.20.1 pynxos==0.0.5 pyparsing==3.0.9 pyrsistent==0.18.1 pyserial==3.5 pytest==7.2.1 python-daemon==2.3.2 python-dateutil==2.8.2 python-dotenv==0.10.5 python-engineio==3.14.2 python-ldap==3.4.3 python-socketio==4.6.1 pytz==2022.5 PyYAML==5.4.1 regex==2020.11.13 requests==2.25.1 requests-file==1.5.1 requests-toolbelt==0.9.1 resolvelib==0.8.1 rich==12.6.0 ruamel.yaml==0.17.21 ruamel.yaml.clib==0.2.6 scp==0.13.6 six==1.16.0 smmap==5.0.0 SQLAlchemy==1.4.42 SQLAlchemy-Utils==0.38.3 starlette==0.14.2 style==1.1.0 subprocess-tee==0.3.5 tenacity==8.0.1 textfsm==1.1.3 tftpy==0.8.0 toml==0.10.2 tomli==2.0.1 tox==3.22.0 tqdm==4.64.0 transitions==0.8.11 typed-ast==1.4.2 typing-extensions==3.10.0.2 unicon==22.7 unicon.plugins==22.7 update==0.0.1 urllib3==1.26.3 virtualenv==20.4.2 wcmatch==8.4.1 wcwidth==0.2.5 websocket-client==0.57.0 Werkzeug==2.2.2 wrapt==1.12.1 WTForms==3.0.1 xmltodict==0.13.0 yamllint==1.27.1 yamlordereddictloader==0.4.0 yang.connector==22.7 yarl==1.7.2 zeep==4.0.0 zipp==3.9.0

Describe the expected results

Tell us what should happen.

Sending a request like this:

curl 'http://localhost:8080/secured/security' -H "Authorization: Bearer $TOKEN"

TOKEN Has the issued token returned from an user in the mongodb database using create_access_token from flask_jwt_extended.

With the api endpoint written like this:

from flask_appbuilder.security.decorators import protect, has_access_api
from flask_appbuilder.api import BaseApi, expose
from flask import request

class SecuredApi(BaseApi):
    """Greeting API Test."""

    route_base = "/secured"
    @has_access_api
    @expose("/security")
    @protect()
    def security_test(self):
        return self.response(200, message="This is private")

It should return a response with the message "This is private".

Describe the actual results

Tell us what happens instead.

But instead returns this message:

{
    "message": "Access is Denied",
    "severity": "danger"
}

In the flask app output log will say this:

2023-03-07 14:59:29,400:WARNING:flask_appbuilder.security.decorators:Access is Denied for: can_security_test on: SecuredApi
2023-03-07 14:59:29,403:INFO:werkzeug:127.0.0.1 - - [07/Mar/2023 14:59:29] "GET /secured/security HTTP/1.1" 401 -

Steps to reproduce

Write and expose the same api endpoint code, run the flask app, and send the get method from the curl line.

When checking the permissions on the view from SecuredApi, it does have can_security_test permissions, assigned to the role of the user.

dpgaspar commented 1 year ago

Hi,

Use the @protect() decorator instead, https://flask-appbuilder.readthedocs.io/en/latest/rest_api.html#security