You are on page 1of 5

Security Assessment Assignment Solution – Meesho

Question 1:

Part 1

1. What happens to the assert statement?

Answer: We use assert to debug our code. Assert can check whether a particular user is
superuser or not. But here we are running the code in optimized mode so it will turn off the
assert. It will not affect the flow and it will not check whether user is superuser or not.

2. Why?

Answer: As we are running the code in optimized mode so it will turn off the debug like assert

3. What are possible impacts on application security posture?

Answer: Assert will be ignored here and due to that any user will be able to get a list of
customers available in the database. It will not check if they are a member of the superuser
group or not.

Part 2

1. Answer: 1) ^https?:\/\/(.*\.)?meesho\.com$

Question 2:

Part 1:

1) Is this code secure? Why?

Answer:

a. As per below line of code, we are allowing 'txt', 'pdf', 'png', 'jpg', 'jpeg' & 'gif' filetypes to
make sure that no other extensions are allowed.

ALLOWED_EXTENSIONS = {'txt', 'pdf', 'png', 'jpg', 'jpeg', 'gif'}

b. As per the below line of code, secure_filename function is being used for sanitization of the
malicious filenames

filename = secure_filename(file.filename)
2) In case of a negative answer, how could it be hardened? List the risks and the mitigations
you’d apply

Answer:

a. We should have a logic in the code to check the maximum file size

b. We can use the Flask-Uploads extension which can automatically implement a secure
upload mechanism.

c. We need to check the Content-type

Part 2:

1) Is this code secure? Why?

No, this is not a secure code.

2) In case of a negative answer, how could it be hardened? List the risks and the mitigations
you’d apply.

a. As per the below line of code, we can clearly see that the login credentials are passing
through the GET method.

@app.route('/login', methods=['GET', 'POST'])

b. We have not implemented any token with proceedwithAuthorization() function for extra
layer of security.
c. We are pushing the credentials to the verification logic without any filtration and
sanitization

Question 3:

Part 1:

1. Is the code secure? Why or why not?

As per the below line of code, we are not doing any kind of input sanitization for user input

String code = codeValidationRequest.getCode();

As per the below line of code, the rate limit is not properly implemented:

private static int ATTEMPTS_LEFT = 5;

2. Can the code be improved? If yes, what changes do you suggest?


Proper implementation of rate limit

Sanitization of code which the user is entering. “String” has alphabets instead of numbers.

Part 2:

Answer: Enable AWS CloudTrail logging across all accounts to a centralized Amazon S3
bucket.Set a lifecycle policy to move the data to Amazon Glacier after 90 days, and expire the
data after 7 years.

Question 4:

Answer:

1. We have set Access-Control-Allow-Origin to * which means even if the app is not


accessible from outside it is possible to craft an Ajax request because Cookies are not
required yet which can utilize basic auth and exploits previously mentioned Local File
read, to read the HTTP response to someone who can access the application.

2. It is possible to bypass basic authentication(“verify_password” method) if we can


combine the first vulnerability i.e path traversal to include a file that has exactly 128
bytes of content.
if pwhash != file_contents:
g.auth_err = "Credentials %s / %s are invalid" % (
username, password)
return False
else:
return True

3. The code is just checking whether there is any value named as “admin” in the “X-
Username” Request Header. We can use this to set the value for “g.user” when visiting
/protected/v1/important.
4. We can bypass the “verify_token” function because the header of JWT payload has a
“kid” key with value “debugKey”. Which is not a good implementation.
{
"alg": “none”,
"typ": "JWT",
"kid": "debugKey"
}.
{“id”: 1}

5. Path Traversal is there in username: ../../../../../../etc/passwd, Contents of the length


would not match 128 bytes and eventually we can read internal files as the logic is
displaying the contents of the fetched file in response.
with open('./data/auth/' + username, 'r') as f:
file_contents = f.read().rstrip()
if len(file_contents) != 128:
g.auth_err = "File not a user hash file: %s" % file_contents
return False

6. There will be no verification on the signature of the JWT because the parameter verify
has a value of “False”. It will not check the signature

Question 5:

Part 1:

Answer: JWT, or JSON Web Token, is an open standard used to share security information
between two parties - a client and a server. Each JWT contains encoded JSON objects,
including a set of claims. JWTs are signed using a cryptographic algorithm to ensure that the
claims cannot be altered after the token is issued.

JSON Web Token is made up of string in three parts and separated by dots. JWT is serialized
using Base64 serialization format.

Once you decode the JWT, you will get two JSON strings:

• The header and the payload.


• The signature.

The header typically consists of two parts: the type of token, which is JWT, and the hashing
algorithm that is used, such as HMAC SHA256 or RSA.

The payload contains the claims. This information is typically used by the server to verify that
the user has permission to perform the action they are requesting.

The signature part of a JWT is derived from the header and payload fields. The steps involved
in creating this signature are described below:

1. Combine the base64url encoded representations of header and payload with a dot (.)
base64UrlEncode(header) + “.” + base64UrlEncode(payload)

2. Hash the above data with a secret-key only known to the server issuing the token.
The hashing algorithm is the one described inside the header.
hash_value = hash([base64UrlEncode(header) + “.” + base64UrlEncode(payload)],
secret-key)

3. Base64Url encode the hash value obtained from the step above
Signature = base64UrlEncode(hash_value)

Because the ‘secret-key’ is only known to the server, only it can issue new tokens with a valid
signature. Users can not forge tokens as producing a valid Signature for the token requires the
knowledge of the ‘secret-key’.

Advantages of using JWT:


1. Less verbose - JWT is compact in size and can be passed in the URL, POST parameter,
or HTTP header.
2. Self-contained - JWT carries all the information needed for exchanging information and
authentication. No Cookies Required.
3. Versatile - JWT works in .NET, Python, Node.js, Java, PHP, Ruby, Go, JavaScript, and
Haskell.
4. Secure: prevents attacks like CSRF and CORS bypasses

Attacks against JWT:


1. Tampering with the ‘none’ algorithm: JWT supports the usage of ‘none’ algorithm for
use-cases where the integrity of the claim within JWT is already verified by other means.
This algorithm allows the server to issue a JWT without a signature. Attackers can use
this feature to set the algorithm in their token to ‘none’ and provide an empty signature to
fool the server into accepting it as a valid token.
2. Brute-Forcing HS256: JWTs signed with the HS256 algorithm could be vulnerable to
secret-key disclosure. that usually happens through brute-force attacks, especially for
weak keys. Since a client does not need to interact with the server to check the validity
of a secret-key after a token is issued by the server, attackers can conduct offline brute-
force attacks against the token by using wordlists of possible secret-keys.
3. Sensitive Information disclosure: All the information inside the payload is stored in plain
text. It is important not to leak sensitive information such as internal IP addresses
through the tokens.

Part 2:
Answer: Add an "s3:GetObject" action

You might also like