erev0s / vampi Goto Github PK
View Code? Open in Web Editor NEWVulnerable REST API with OWASP top 10 vulnerabilities for security testing
License: MIT License
Vulnerable REST API with OWASP top 10 vulnerabilities for security testing
License: MIT License
I suggest add weak JWT secret key vulnarability to the list of vulnarabilities. Brute force
Api is responsing with only one object, not a list.
Hello,
the admin parameter of the user is store as boolean in the system, but in register_user is it treated like a string. Typically, mass assignment vulnerabilities are present because a REST API framework directly maps an HTTP parameter to an attribute in the system. To make the example closer to reality, try to mimic this behavior by accepting a boolean parameter rather than a string.
Following the default requirements.txt causes error when run the docker image
Traceback (most recent call last):
File "app.py", line 1, in <module>
from config import vuln_app
File "/vampi/config.py", line 2, in <module>
import connexion
File "/usr/local/lib/python3.7/site-packages/connexion/__init__.py", line 5, in <module>
from .apis import AbstractAPI # NOQA
File "/usr/local/lib/python3.7/site-packages/connexion/apis/__init__.py", line 1, in <module>
from .abstract import AbstractAPI # NOQA
File "/usr/local/lib/python3.7/site-packages/connexion/apis/abstract.py", line 16, in <module>
from ..spec import Specification
File "/usr/local/lib/python3.7/site-packages/connexion/spec.py", line 5, in <module>
import jinja2
File "/usr/local/lib/python3.7/site-packages/jinja2/__init__.py", line 12, in <module>
from .environment import Environment
File "/usr/local/lib/python3.7/site-packages/jinja2/environment.py", line 25, in <module>
from .defaults import BLOCK_END_STRING
File "/usr/local/lib/python3.7/site-packages/jinja2/defaults.py", line 3, in <module>
from .filters import FILTERS as DEFAULT_FILTERS # noqa: F401
File "/usr/local/lib/python3.7/site-packages/jinja2/filters.py", line 13, in <module>
from markupsafe import soft_unicode
ImportError: cannot import name 'soft_unicode' from 'markupsafe' (/usr/local/lib/python3.7/site-packages/markupsafe/__init__.py)
Add version requirements on markupsafe==2.0.2
package solves the issue, but I haven't checked if the docker can function normally.
Hi,
I have seen your readme but i feel we should have some ref table showing which exploit top 10 category is present in which endpoint. Because i mapped one specific endpoint to available vulnerabilities but then same vulnerability my colleague mapped to another and we don't have any clarity which one is a valid endpoint to test those vulnerabilities.
Also having proper solution will be great. Let me know if need any help !
Thanks,
Janibasha
Hello,
Firstly, thank you for this very pleasant project!
I've encountered an ambiguity multiple times during my tests on the /users/v1/register endpoint. When using the image from Docker Hub, I don't get the same result when attempting to promote myself to admin on the API. Specifically, I am unable to perform this privilege escalation from the container linked to the image on Docker Hub, but only through the one I manually build via the project's Dockerfile.
Here are the data I'm sending to the API:
jsonCopy code
{ "username": "test2", "password": "test", "email": "[email protected]", "admin": "True" }
I want to mention that I also tested with "admin": true.
Here are my tests in more detail with Postman:
Test using the project's Dockerfile
Test using the image stored on Docker Hub
Is this an issue with the image not being updated on Docker Hub? (Last release: 4 months ago: Docker Hub Link)
I am available if you need more information.
Best regards,
Archidote
Can you provide some example please, how to exploit these? I tried it with some very long email, but always get 204 back
Love this project! Thank you.
Opening an issue to use w/ a PR I'm about to submit.
To make it even easier and more powerful to use as a teaching tool, it is handy to run one instance of VAmPI securely (vulnerable=0) and another insecure instance running in parallel on a different port (vulnerable=1). Your use of ENV within the Dockerfile makes this dead simple and adjustments to the README are all that is needed.
Also ran into a conflict w/ port 5000 on Mac OSX, so put in a note about two ways to resolve that.
Hello!
Is there API endpoint like http://127.0.0.1:5000/v3/api-docs for get API definition document?
It will be suitable for OWASP ZAP test automation with your instance for example.
Thank you!
Your OAS file is missing authentication. Looking at your OAS with Swagger, all paths appear to be unsecured and do not require authentication, even though they do. Can you fix this?
First of all, man, your work is awesome!
I'm using it to teach my students how to make web more secured.
I want to advise some ides, what can be used in continuation of your fantastic project:
What about adding some kind of RCE and docker container hardening?
For example, your awesome app can started as container inside VM in 4 variants:
According to this:
https://github.com/OWASP/Docker-Security
https://github.com/OWASP/Docker-Security/blob/main/dist/owasp-docker-security.pdf
https://cheatsheetseries.owasp.org/cheatsheets/Docker_Security_Cheat_Sheet.html
Linux version: Ubuntu 22.04.1
Summary: flask-sqlalchemy version when installing requirements.txt is incompatible and raises error shown below:
AttributeError: module 'sqlalchemy' has no attribute 'all'. Did you mean: 'file'?
Following updated requirements.txt solves this error:
connexion~=2.7.0
flask~=2.2
flask-sqlalchemy>=3.0.2
jsonschema~=3.2.0
sqlalchemy
swagger-ui-bundle
PyJWT~=1.7.1
markupsafe==2.1.1
Hi,
I can see doc says this demo app supports multiple attacks but i don't see attack payloads. So can you please share them so i can also test these attacks.
Thanks,
Jani
I'm running a relatively stock, updated Ubuntu 20.04 box and I'm hitting a docker build issue. One of the python dependencies pulls in a package called greenlet
, which is compiling against the python development headers and using the g++ compile.
The get_user method in the models/user_model.py
return the _ repr _ format when vulnerable=0
.
$ curl "http://localhost:5000/users/v1/name1"
<User(name=name1, [email protected])>
This not happen when the vulnerable environment is True, because in that scenario the response is a formatted string, meanwhile in this one it returns the first user object found:
78 else:
79 fin_query = User.query.filter_by(username=username).first()
We can take advance of the json class method to return the user data:
else:
user = User.query.filter_by(username=username).first()
fin_query = user.json() if user else None
return fin_query
Note: Calling .json() of a NoneType object could raise an error, so we must check if exists first.
But the .json() class method encloses the value in single quotes. That's not the standard json syntax we are looking for. A better solution could be like this:
else:
user = User.query.filter_by(username=username).first()
fin_query = str(User.json(user)).replace("'",'"') if user else None
return fin_query
$ curl "http://localhost:5000/users/v1/name1" # not vuln
{"username": "name1", "email": "[email protected]"}
$ curl "http://localhost:5001/users/v1/name1" # vuln
{"username": "name1", "email": "[email protected]"}
Link to code: https://github.com/erev0s/VAmPI/blob/master/openapi_specs/openapi3.yml#L562
I think response body for this endpoint should be just object not array of objects
How to get bearer token
The stake-trace appears as below while trying to perform any write operation.
##################
do_execute
def do_executemany(self, cursor, statement, parameters, context=None):
cursor.executemany(statement, parameters)
def do_execute(self, cursor, statement, parameters, context=None):
cursor.execute(statement, parameters)
def do_execute_no_params(self, cursor, statement, context=None):
cursor.execute(statement)
def is_disconnect(self, e, connection, cursor):
sqlalchemy.exc.OperationalError: (sqlite3.OperationalError) attempt to write a readonly database [SQL: DROP TABLE books] (Background on this error at: https://sqlalche.me/e/14/e3q8)
This is the Copy/Paste friendly version of the traceback. You can also paste this traceback into a gist:
<textarea cols="50" rows="10" name="code" readonly>Traceback (most recent call last): File "/usr/local/lib/python3.7/site-packages/sqlalchemy/engine/base.py", line 1901, in _execute_context cursor, statement, parameters, context File "/usr/local/lib/python3.7/site-packages/sqlalchemy/engine/default.py", line 736, in do_execute cursor.execute(statement, parameters) sqlite3.OperationalError: attempt to write a readonly databaseThe above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 2464, in call
return self.wsgi_app(environ, start_response)
File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 2450, in wsgi_app
response = self.handle_exception(e)
File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 1867, in handle_exception
reraise(exc_type, exc_value, tb)
File "/usr/local/lib/python3.7/site-packages/flask/_compat.py", line 39, in reraise
raise value
File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 2447, in wsgi_app
response = self.full_dispatch_request()
File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 1952, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 1821, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/usr/local/lib/python3.7/site-packages/flask/_compat.py", line 39, in reraise
raise value
File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 1950, in full_dispatch_request
rv = self.dispatch_request()
File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 1936, in dispatch_request
return self.view_functionsrule.endpoint
File "/usr/local/lib/python3.7/site-packages/connexion/decorators/decorator.py", line 48, in wrapper
response = function(request)
File "/usr/local/lib/python3.7/site-packages/connexion/decorators/uri_parsing.py", line 144, in wrapper
response = function(request)
File "/usr/local/lib/python3.7/site-packages/connexion/decorators/parameter.py", line 121, in wrapper
return function(**kwargs)
File "/vampi/api_views/main.py", line 7, in populate_db
db.drop_all()
File "/usr/local/lib/python3.7/site-packages/flask_sqlalchemy/init.py", line 1102, in drop_all
self._execute_for_all_tables(app, bind, 'drop_all')
File "/usr/local/lib/python3.7/site-packages/flask_sqlalchemy/init.py", line 1086, in _execute_for_all_tables
op(bind=self.get_engine(app, bind), **extra)
File "/usr/local/lib/python3.7/site-packages/sqlalchemy/sql/schema.py", line 4960, in drop_all
ddl.SchemaDropper, self, checkfirst=checkfirst, tables=tables
File "/usr/local/lib/python3.7/site-packages/sqlalchemy/engine/base.py", line 3228, in _run_ddl_visitor
conn._run_ddl_visitor(visitorcallable, element, **kwargs)
File "/usr/local/lib/python3.7/site-packages/sqlalchemy/engine/base.py", line 2211, in _run_ddl_visitor
visitorcallable(self.dialect, self, **kwargs).traverse_single(element)
File "/usr/local/lib/python3.7/site-packages/sqlalchemy/sql/visitors.py", line 524, in traverse_single
return meth(obj, **kw)
File "/usr/local/lib/python3.7/site-packages/sqlalchemy/sql/ddl.py", line 1029, in visit_metadata
_ignore_sequences=seq_coll,
File "/usr/local/lib/python3.7/site-packages/sqlalchemy/sql/visitors.py", line 524, in traverse_single
return meth(obj, **kw)
File "/usr/local/lib/python3.7/site-packages/sqlalchemy/sql/ddl.py", line 1102, in visit_table
self.connection.execute(DropTable(table))
File "/usr/local/lib/python3.7/site-packages/sqlalchemy/engine/base.py", line 1380, in execute
return meth(self, multiparams, params, _EMPTY_EXECUTION_OPTS)
File "/usr/local/lib/python3.7/site-packages/sqlalchemy/sql/ddl.py", line 81, in _execute_on_connection
self, multiparams, params, execution_options
File "/usr/local/lib/python3.7/site-packages/sqlalchemy/engine/base.py", line 1478, in _execute_ddl
compiled,
File "/usr/local/lib/python3.7/site-packages/sqlalchemy/engine/base.py", line 1944, in execute_context
e, statement, parameters, cursor, context
File "/usr/local/lib/python3.7/site-packages/sqlalchemy/engine/base.py", line 2125, in handle_dbapi_exception
sqlalchemy_exception, with_traceback=exc_info[2], from=e
File "/usr/local/lib/python3.7/site-packages/sqlalchemy/util/compat.py", line 211, in raise
raise exception
File "/usr/local/lib/python3.7/site-packages/sqlalchemy/engine/base.py", line 1901, in _execute_context
cursor, statement, parameters, context
File "/usr/local/lib/python3.7/site-packages/sqlalchemy/engine/default.py", line 736, in do_execute
cursor.execute(statement, parameters)
sqlalchemy.exc.OperationalError: (sqlite3.OperationalError) attempt to write a readonly database
[SQL:
DROP TABLE books]
(Background on this error at: https://sqlalche.me/e/14/e3q8)</textarea>
##################
Hello,
some operations in the OpenAPI specification does not provide a response schema, e.g., in the GET /users/v1
operation the response schema for the 200
status code is empty ({}
), but it should be an array of user objects.
Could you please update the specification with the response schemas?
The usename parameter requires a string type value, but when characters containing special characters are passed in, a response with a 500 response code is received
/user/v1/{username}
GET
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.