TLS 1.2 has been in born since 2008 and yet many of us did not know about it until new requirement came to us...
To enforce the TLS 1.2 in a website, you need to add a Global.asax and then add the following line:
void Application_Start(object sender, EventArgs e)
{
System.Net.ServicePointManager.SecurityProtocol = (System.Net.SecurityProtocolType)3072;
}
Once the above code has been added, all HTTP request will be served in TLS 1.2 that includes the web service (ASMX) and HTTP request call to external website. And make sure that the project is compiled under .Net 4.6 and everything will be ok.
Notes: your program will work with TLS1.2 only. An exception will be thrown if the server does not enabled TLS 1.2.
There is a catch... if some other app is consuming the resource on your website, they must be on TLS 1.2 as well. Otherwise they will fail to make any connection to your website.
Showing posts with label Security Design. Show all posts
Showing posts with label Security Design. Show all posts
Tuesday, January 23, 2018
Wednesday, October 4, 2017
Cross-Origin Request Blocked (CORS)
To speed up the development and future upgrade, we split the huge
application into multiple AJAX services. Each AJAX service in running in
it's own application pool and it can be run on different server. The
design works perfectly. But, when you want to consume the AJAX services
through the browser, you bang your head: "Cross-Origin Request Blocked".
This is the error message that appeared in the Firefox:
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost/schedule/q?code=tx&ts=1507099862873. (Reason: CORS header ‘Access-Control-Allow-Origin’ does not match ‘(null)’).
Google Chrome returned an error message that is slightly different:
Failed to load http://localhost/schedule/q?code=tx&ts=1507099946004: The 'Access-Control-Allow-Origin' header contains multiple values '*, *', but only one is allowed. Origin 'http://localhost:56269' is therefore not allowed access.
Now, if you are googling for the solution, you will end up with add the following settings in the web.config.
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Headers" value="Content-Type" />
<add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS" />
</customHeaders>
</httpProtocol>
But, the wild card origin is no longer supported. You ended up with adding the specific origin.
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="http://localhost:56292" />
<add name="Access-Control-Allow-Headers" value="Content-Type" />
<add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS" />
</customHeaders>
</httpProtocol>
Imagine that you are hosting your AJAX services in multiple servers with different sub-domains.... the above solution will not work. This is because you are not allowed adding more than one domain name to "Access-Control-Allow-Origin".
To solve the problem, we need to handle the OPTIONS verb by adding the following settings in the web.config:
<system.webServer>
<handlers>
<add verb="OPTIONS" name="check_opt" path="*" type="ajaxLib.CORS_OPTIONS" />
</handlers>
</system.webServer>
And below is the simplified code that allows CORS:
namespace ajaxLib {
public class CORS_OPTIONS : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
if (context.Request.HttpMethod.ToUpper() == "OPTIONS") {
string s = context.Request.Headers["Origin"];
if (!string.IsNullOrWhiteSpace(s))
{
context.Response.AppendHeader("Access-Control-Allow-Origin", s);
context.Response.AppendHeader("Access-Control-Allow-Headers", "Content-Type");
context.Response.AppendHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
}
}
}
public bool IsReusable { get { return false; }}
}}
Two possibilities if you want to use the above code in the live environment,
1. If your service allows public access without any restriction, skip checking the Origin value.
2. If your service allows specific domain to access, you must check the Origin value before return it to the caller.
This is the error message that appeared in the Firefox:
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost/schedule/q?code=tx&ts=1507099862873. (Reason: CORS header ‘Access-Control-Allow-Origin’ does not match ‘(null)’).
Google Chrome returned an error message that is slightly different:
Failed to load http://localhost/schedule/q?code=tx&ts=1507099946004: The 'Access-Control-Allow-Origin' header contains multiple values '*, *', but only one is allowed. Origin 'http://localhost:56269' is therefore not allowed access.
Now, if you are googling for the solution, you will end up with add the following settings in the web.config.
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Headers" value="Content-Type" />
<add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS" />
</customHeaders>
</httpProtocol>
But, the wild card origin is no longer supported. You ended up with adding the specific origin.
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="http://localhost:56292" />
<add name="Access-Control-Allow-Headers" value="Content-Type" />
<add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS" />
</customHeaders>
</httpProtocol>
Imagine that you are hosting your AJAX services in multiple servers with different sub-domains.... the above solution will not work. This is because you are not allowed adding more than one domain name to "Access-Control-Allow-Origin".
To solve the problem, we need to handle the OPTIONS verb by adding the following settings in the web.config:
<system.webServer>
<handlers>
<add verb="OPTIONS" name="check_opt" path="*" type="ajaxLib.CORS_OPTIONS" />
</handlers>
</system.webServer>
And below is the simplified code that allows CORS:
namespace ajaxLib {
public class CORS_OPTIONS : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
if (context.Request.HttpMethod.ToUpper() == "OPTIONS") {
string s = context.Request.Headers["Origin"];
if (!string.IsNullOrWhiteSpace(s))
{
context.Response.AppendHeader("Access-Control-Allow-Origin", s);
context.Response.AppendHeader("Access-Control-Allow-Headers", "Content-Type");
context.Response.AppendHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
}
}
}
public bool IsReusable { get { return false; }}
}}
Two possibilities if you want to use the above code in the live environment,
1. If your service allows public access without any restriction, skip checking the Origin value.
2. If your service allows specific domain to access, you must check the Origin value before return it to the caller.
Labels:
.Net,
AJAX,
ASP.NET,
C#,
Security Design,
System Design
Monday, September 9, 2013
Controlling the page access permission
For most of the website that requires user logon, there are three types: (1) the system administrators (2) system users and (3) the page that is accessible without logon to the website.
The website will show the functions base on the current user type. For example, system administrator will be able to create user account, updating system settings. For system user, they will be able to access the data entry screen, generate reports. Both user types requires to access different features in the system.
In the design option, we may implement with one of the following security strategy:
The most interesting strategy is the third option and the implementation is powerful yet simple. You need to develop three page classes which inherits from Page class. Namely "AdminPage", "UserPage" and the third one is PublicPage (for public access such as "login" page and "contact us" page).
The detail implementation of the in the AdminPage is to ensure that the current user type is system administrator in OnInit event.
public class AdminPage : Page
{
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
// if the user has not logged on, jump to "access deny" page.
// if current user is not "system admin", jump to "access deny" page.
}
}
For the UserPage, we don't want the system administrator to access it (this depends on the requirments) :
public class UserPage : Page
{
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
// if the user has not logged on, jump to "access deny" page.
// if current user is not "system user", jump to "access deny" page.
}
}
Once the above page classes are ready, you just need to change your ".aspx.cs" parent class to one of the above. By using the Object Oriented Programming, your developer colleagues will be able to find out which page is for admininstrator, user and public (just right click on the AdminPage and choose Find All References). This also reduce the developer comments in the ".aspx.cs" and increase the maintainability.
By inheriting the web page from different parent page class, there is a "gray" area which you are not sure if it should be PublicPage or UserPage. In this case, you might need to declare a new hybrid page class for it and limit the contents between the "public" and "user". But, for me, I prefer to move the "contents" from the page to "user control" (i.e., ".ascx") and limit the contents base on current user type. Then, I create two pages: one inherits from PublicPage and the other from UserPage. By using user control, I'm able to have the page for single audience and I'm able to handle it easily.
The website will show the functions base on the current user type. For example, system administrator will be able to create user account, updating system settings. For system user, they will be able to access the data entry screen, generate reports. Both user types requires to access different features in the system.
In the design option, we may implement with one of the following security strategy:
- The features are turn on/off which depends on the permission that has been assigned to the user. With this strategy, the "user" has many "permissions" (i.e., one-to-many relationship).
- The features are turn on/off which depends on the user falls in which user group. With this strategy, you can have one user in one group or multiple groups (i.e., many-to-many relationship).
- The simplest way is to add a field in the "user" record to identify it's "user type" (either system administrator or system user). Plus either one of the above strategy. With this design, you will be able to come out with a complex security design that can cater most of the requirements.
The most interesting strategy is the third option and the implementation is powerful yet simple. You need to develop three page classes which inherits from Page class. Namely "AdminPage", "UserPage" and the third one is PublicPage (for public access such as "login" page and "contact us" page).
The detail implementation of the in the AdminPage is to ensure that the current user type is system administrator in OnInit event.
public class AdminPage : Page
{
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
// if the user has not logged on, jump to "access deny" page.
// if current user is not "system admin", jump to "access deny" page.
}
}
For the UserPage, we don't want the system administrator to access it (this depends on the requirments) :
public class UserPage : Page
{
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
// if the user has not logged on, jump to "access deny" page.
// if current user is not "system user", jump to "access deny" page.
}
}
Once the above page classes are ready, you just need to change your ".aspx.cs" parent class to one of the above. By using the Object Oriented Programming, your developer colleagues will be able to find out which page is for admininstrator, user and public (just right click on the AdminPage and choose Find All References). This also reduce the developer comments in the ".aspx.cs" and increase the maintainability.
By inheriting the web page from different parent page class, there is a "gray" area which you are not sure if it should be PublicPage or UserPage. In this case, you might need to declare a new hybrid page class for it and limit the contents between the "public" and "user". But, for me, I prefer to move the "contents" from the page to "user control" (i.e., ".ascx") and limit the contents base on current user type. Then, I create two pages: one inherits from PublicPage and the other from UserPage. By using user control, I'm able to have the page for single audience and I'm able to handle it easily.
Labels:
.Net,
ASP.NET,
Enhancement,
Reusable,
Security Design,
System Design,
System Development
Monday, October 22, 2012
Scaling out your system using web services
There are many different ways to improve the system respond time: one of the strategy is call scaling out. In our system design, we are implementing the "basic modules" (i.e., the system infrastructure) in web service and it is able to achieve this easily.
Web service does not have a huge different from a website. The noticeable different is that it does not have user interface (or web pages) for visitor to access. You may imagine that the web service like a mobile phone station/transmitter which is providing connection to the mobile phone. In .Net, the web service is implemented in ASMX format, WCF (Windows Communication Foundation) or simply ASPX (which returns the data in XML or JSON format).
Now, the best part of web service is not something that will make our solution cool. Instead, it is able to scale out to a server other than the web server (that is hosting the website). In this case, our customer might end up with a web server to host the website, a few web servers that host the web services.
Many programmers argue that web service is slow because of XML SOAP involves in the communication. It's true that web service in ASMX is slow but the visitor won't really feel it because of these communications were made among the web servers which is sitting next to each other. Of course, the web service implemented in XML SOAP is not suitable for real-time application. The real-time application requires low level socket programming and the handling strategy will be different.
Web service does not have a huge different from a website. The noticeable different is that it does not have user interface (or web pages) for visitor to access. You may imagine that the web service like a mobile phone station/transmitter which is providing connection to the mobile phone. In .Net, the web service is implemented in ASMX format, WCF (Windows Communication Foundation) or simply ASPX (which returns the data in XML or JSON format).
Now, the best part of web service is not something that will make our solution cool. Instead, it is able to scale out to a server other than the web server (that is hosting the website). In this case, our customer might end up with a web server to host the website, a few web servers that host the web services.
Many programmers argue that web service is slow because of XML SOAP involves in the communication. It's true that web service in ASMX is slow but the visitor won't really feel it because of these communications were made among the web servers which is sitting next to each other. Of course, the web service implemented in XML SOAP is not suitable for real-time application. The real-time application requires low level socket programming and the handling strategy will be different.
Labels:
.Net,
ASP.NET,
C#,
Database,
Enhancement,
Multi-threading,
Networking,
Optimization,
Reusable,
Security Design,
System Design,
System Development,
TCP,
WCF,
Web Service
Monday, October 15, 2012
Security web service
When you are developing a large scale application, you need a security module that is able to authenticate the users. In our system design, we developed a security web service which is shared among the sub-modules and also reduce the development time.
In .Net, you can achieve this with the technology that you want:
Updates on 6th May 2017 - it seems like ASMX or WCF are quite hard to be converted to other programming language/platform. Best is to use ASHX (i.e., generic handler) which has a faster response time due to it's simplicity and flexibility. It's also easier to port over to other programming language/platform.
In .Net, you can achieve this with the technology that you want:
- Implementing the security service using ASMX/ASHX - this service will be hosted through HTTP/HTTPS.
- Implementing the security service using WCF - in this case, you will have the choices of different protocols such as TCP, named pipe, etc.
Updates on 6th May 2017 - it seems like ASMX or WCF are quite hard to be converted to other programming language/platform. Best is to use ASHX (i.e., generic handler) which has a faster response time due to it's simplicity and flexibility. It's also easier to port over to other programming language/platform.
Labels:
.Net,
ASP.NET,
C#,
Enhancement,
Optimization,
Reusable,
Security Design,
System Design,
System Development
Monday, October 8, 2012
Security design consideration for web application
The security problem with web application:
- Web application is easier to hack as long as you know the URL - this means that some security control must be implemented in the web application.
- The primary key value of the table is integer data type - this is easier to guess what's next value. For example, "http://myWeb.com/customer.aspx?cust_id=123" and the next record is "http://myWeb.com/customer.aspx?cust_id=124".
- Session ID - you may rely on the ASP.net session ID or you handle it your own.
- Deleting record with JavaScript confirmation and then fire AJAX call to the delete action URL - is this secured? Does the delete action page implemented sufficient control?
- Folder with read & write permission for user uploading file - without limiting the file type that is acceptable by the web application, your website will have a security hole that can be exploited.
- Audit log should include the browser type, URL referrer and also the user's IP address. Without these information, it will be impossible to track who has accessed which feature/data.
Labels:
ASP.NET,
C#,
Class,
Database,
Enhancement,
Security Design,
System Design,
System Development
Monday, October 1, 2012
Security check point
In Windows client, you can develop a static function call SecurityCheckPoint() that gets the user ID and password. This SecurityCheckPoint() method will be very useful whenever you want the user to re-authenticate before any process start OR you want to get the supervisor authentication.
Well, this can be useful for the web application as well but you need to implement it using JavaScript that show a modal dialog and AJAX calls for authentication.
Labels:
C#,
Enhancement,
Security Design,
System Design,
System Development,
Windows,
WinForm
Tuesday, September 25, 2012
Something about user access control or security control design
Below is a few strategy to implement the user access control or the security feature in your application.
Let's assume that you read the previous article, the CUser class will have a CanAccess() method which returns true or false. The application should check the result of this method before performing the process/action whereas CUser class.
Different flavor of CanAccess()
- The simplest design will be user name + password and stores these information in a database table. No control over the feature accessibility.
- One level harder will be using one security "action" to treat as one permission. And one security action represent a menu option, button, input field, display field or a process to be executed. This design requires 1 user class and a collection of permitted/allowed security actions. So, you need two database tables to stores the information. For example, user A allows issuing and editing invoice but not deleting any invoice. In this case, you will have 3 allowed actions (or record) for user A.
- In case you feel that having one security action mapping to the feature is cumbersome and require lots of hard space, you may consider adding a flag field in the security action. For example, "Invoice" action will have 3 flags: issue, edit and delete where the "flag" is in BIT data type (in MSSQL database). If the flag value is "1" means permitted and "0" means not permitted.
- Some applications requires another level of sophistication - that is using "user level" in conjunction with the security actions.
- Another kind of implementation is to have write level (0-10) and read level (0-10). Both values are use in conjunction with the menu option and input fields. For example, the credit limit field for the customer has read level of "5" and write level of "8". If the user's read level is "5" and the user will be able to view the credit limit field. If the user's write level is also "5", then, this credit limit value will be disabled from editing.
Let's assume that you read the previous article, the CUser class will have a CanAccess() method which returns true or false. The application should check the result of this method before performing the process/action whereas CUser class.
Different flavor of CanAccess()
- bool CanAccess(Guid action_id)
- bool CanAccess(Guid action_id, PermissionEnum permission) [PermissionEnum {insert, update, delete, select]
- bool CanAccess(Guid action_id, int user_level)
- bool CanAccess(int read_level, int write_level)
Labels:
.Net,
ASP.NET,
C#,
Class,
Database,
Enhancement,
Integration,
Parameter,
Reusable,
Security Design,
System Design,
System Development
Thursday, September 20, 2012
Reusable class - user access control
This is another important area in the systems and it is reusable as long as the design is generic to cover all possible combination.
Basically, it should meet the following requirements:
Basically, it should meet the following requirements:
- Security control - allows user to logon to the system and verify their user name and password.
- Access permission - permission could be controlled by menu level, screen level and field level (whether the field is show/hidden or enable/disable).
- User access log - this is compulsory for audit purpose and also the alert.
- Access deny alert - upon hitting certain number of invalid user name or password, the system should generate alert and email it to the system administrator.
- Password policy - you may consider to implement minimum password length and password complexity.
- Allow supervisor overriding - this can be useful when the current user does not have permission to access certain feature (such as edit customer address) but requires to do so.
- In case the system is a web base system, it should store the browser type and visitor IP address for audit purpose.
- CUser - this class stores the user information such as user name, password, email address, etc.
- CAction - this class stores all the permissions (or features) for the system.
- CUserAccessLog - this class responsible for keeping track the user login and logout activities.
- CLog - this class (which has been discussed in previous article) which is responsible for storing the audit information such as which "action" (or "featuer") the user has clicked.
Labels:
C#,
Class,
Reusable,
Security Design,
System Design,
System Development,
Web Service,
WinForm
Subscribe to:
Posts (Atom)