<div class="widget">
    <div class="widget-header">
      <div class="title">
        <span class="fs1" aria-hidden="true" data-icon="&#xe092;"></span> A6 - Sensitive Data Exposure - Model Attributes Exposure
      </div>
    </div>
    <div class="widget-body">
      <div id="accordion1" class="accordion no-margin">
        <div class="accordion-group">
          <div class="accordion-heading">
            <a href="#collapseModelOne" data-parent="#accordion1" data-toggle="collapse" class="accordion-toggle">
              <i class="icon-info icon-white">
              </i>
              Description
            </a>
          </div>
          <div class="accordion-body in collapse" id="collapseModelOne" style="height: auto;">
            <div class="accordion-inner">
       <p class="desc">
        The application's API returns a model object (user or users). Using respond_with, the API returns the full model object. It is simple but exposes information such as the user's password and other user attributes that you may wish to keep invisible.
       </p>
            </div>
          </div>
        </div>
        <div class="accordion-group">
          <div class="accordion-heading">
            <a href="#collapseModelTwo" data-parent="#accordion1" data-toggle="collapse" class="accordion-toggle">
              <i class="icon-bug icon-white">
              </i>
              Bug
            </a>
          </div>
          <div class="accordion-body collapse" id="collapseModelTwo" style="height: 0px;">
            <div class="accordion-inner">
            <p class="desc">
         Within app/controllers/api/v1/users_controller.rb:
          </p>
        <pre class="ruby">
         def index
             # We removed the .as_json code from the model, just seemed like extra work.
             # dunno, maybe useful at a later time?
             #respond_with @user.admin ? User.all.as_json : @user.as_json

             respond_with @user.admin ? User.all : @user
           end

           def show
             respond_with @user.as_json
           end
        </pre>
        <p class="desc">
        The <i>as_json</i> method referenced in the comments section of the index action exists within the user model in order to override and safely protect our model from only rendering certain attributes. It is unused (commented out), app/models/user.rb:
        </p>
        <pre class="ruby">
          # Instead of the entire user object being returned, we can use this to filter.
          def as_json
            super(only: [:user_id, :email, :first_name, :last_name])
          end
        </pre>
        <p class="desc">
        When utilizing the method that most tutorials describe or advocate when rendering model objects via JSON in an API (unsafe), the response looks like this:
        </p>
        <pre>
  HTTP/1.1 200 OK
  Content-Type: application/json; charset=utf-8
  X-UA-Compatible: IE=Edge
  ETag: "6b4caf343a20865de174b2b530b945dd"
  Cache-Control: max-age=0, private, must-revalidate
  X-Request-Id: c3b0a57861087c0b827aab231747ef0c
  X-Runtime: 0.051734
  Connection: close

  {"admin":false,"created_at":"2014-01-23T16:17:10Z","email":
  "jack@metacorp.com","first_name":"Jack","id":2,"last_name":"Mannino","password":
  "b46dd2888a0904972649cc880a93f4dd","updated_at":"2014-01-23T16:17:10Z","user_id":2}
        </pre>
        <p class="desc">
        Note that all attributes associated with this user are returned via the API.
        </p>
            </div>
          </div>
        </div>
        <div class="accordion-group">
          <div class="accordion-heading">
            <a href="#collapseModelThree" data-parent="#accordion1" data-toggle="collapse" class="accordion-toggle">
              <i class="icon-lightning icon-white">
              </i>
              Solution
            </a>
          </div>
          <div class="accordion-body collapse" id="collapseModelThree" style="height: 0px;">
            <div class="accordion-inner">
              <p><b>Model Attributes Exposure - ATTACK</b></p>
        <p class="desc"> Use the API and review the data returned. Additional information on exploiting the API available under the <i>Extras > Logic Flaws</i> Section.</p>
        <p><b>Model Attributes Exposure - SOLUTION</b></p>
          <p class="desc">
          Uncomment the <i>as_json</i> method within the user model. Additionally, call <i>.as_json</i> on any User model object you would like to return via the API or other means. Example:
        </p>
        <pre class="ruby">
          respond_with @user.admin ? User.all.as_json : @user.as_json
        </pre>
        <p class="desc">
          Upon uncommenting the <i>as_json</i> method within the User model, the <i>as_json</i> method will ensure the API output only returns those attributes you have allowed in the following code:
        </p>
        <pre class="ruby">
        def as_json
          super(<span style="background-color:yellow">only: [:user_id, :email, :first_name, :last_name]</span>)
        end
        </pre>
        <p class="desc">
          The response from the API should look like:
        </p>
        <pre>
  HTTP/1.1 200 OK
  Content-Type: application/json; charset=utf-8
  X-UA-Compatible: IE=Edge
  ETag: "2333488e856669ac637e37cb4cf09cb6"
  Cache-Control: max-age=0, private, must-revalidate
  X-Request-Id: baa6a1c90004838793614e4c61633767
  X-Runtime: 0.092768
  Connection: close

  {"email":"jack@metacorp.com","first_name":"Jack","last_name":"Mannino","user_id":2}
        </pre>
            </div>
          </div>
        </div>
    <div class="accordion-group">
          <div class="accordion-heading">
            <a  style="background-color: rgb(181, 121, 158)" href="#collapseModelFour" data-parent="#accordion1" data-toggle="collapse" class="accordion-toggle">
              <i class="icon-aid icon-white">
              </i>
              Hint
            </a>
          </div>
          <div class="accordion-body collapse" id="collapseModelFour" style="height: 0px;">
            <div class="accordion-inner">
              We have an API available... what does it return?
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>