分類彙整: 编程

Web Application Security

今天公司培训,去上了一天课,讲的主题是“Web Application Security”。主讲人是一个老外,handshake networking的consultant。我觉得讲的内容很不错,在这里和大家分享一下吧。

Web Application Security

 

随着网络高速发展,越来越多公司将部分业务放在网上。一来方便了客户,二来也减低了公司本身的行政费用。以前黑客们大多将精力集中在OS或者Web Server层面。比如说Windows的漏洞或者是IIS,Apache的漏洞,并加以攻击。但随着这些软件的不断完善,攻击的难度也越来越大。相比起来,Web Application层面的攻击就比较容易。原因有几个:第一,OS和Web Server的漏洞可以通过patch的形式修复,一旦开发商发布这些patch,大部分电脑的漏洞都可以堵塞。但Web Application都是自己开发的,这个堵塞了漏洞,另一个还可以用同样的手法攻击。第二,Web Application的开发都是小规模进行,质量良莠不齐,攻击起来相对简单。

程序员避免犯的错误

 

在这里说几个常犯的错误吧。

  1. 不要在同一个目录下备份文件。一般来说,程序员有个习惯就是做任何修改之前先备份一下,将原来的文件改成.bak, .tmp之类的。如果黑客知道我们的文件名(不可能不知道,就在网址里),就可以尝试下载有这些后缀的文件,找到的话,我们的源代码就会被直接下载咯。
  2. 修改Web Server的默认设置。修改Web Server的设置,使得返回的http header不会有IIS/6.0或Apache 2.2.1之类可以告诉黑客服务器版本的东西。因为这信息有助于黑客锁定攻击你的方法。而且主讲人还说了一个很重要的原因。大部分黑客都是没有既定目标的,他们只是在网上漫游,寻找合适的网站来攻击。如果你的网站返回的是没有任何意义的东西,他们就会觉得那管理员最起码懂一点安全的东西。于是就会放弃这个网站,直接寻找下一个。哈哈,这个强吧。
  3. 尽量不要将多个Application放在同一个服务器中。因为你永远不知道别人的Application有什么漏洞,所以每增加一个Application就等于增加了该服务器被攻击的机率。要知道,一个Application被攻破,黑客就可以通过其他方法拿到别的Application的控制权。

目前先说这么多吧。

Slide Show widget for BlogEngine.NET

今天用jquery写了一个给BlogEngine.NET用的slide show小工具。最重要的功能是你可以通过edit来自己上传照片,并且照片在上传后会在服务器背后自动压缩,以减低容量要求。啥也不说了,看首页右面的例子就是了,呵呵。

马上下载来玩玩吧。

This widget is written in jquery, an open source javascript library. It allows you to upload your own photos and display it as a slide show. You can see the effect on the Homepage. Please download it right below, a readme file is included.

SlideShow

jquery初步介绍

最近在网上看到jquery这个名词,于是在网上搜了一下,发觉貌似还挺多人在使用的。下面是一段关于jquery的描述:

“jQuery 是一套物件導向式簡潔輕量級的 JavaScript Library。透過 jQuery 你可以用最精簡少量的程式碼來輕鬆達到跨瀏覽器 DOM 操作、事件處理、設計頁面元素動態效果、AJAX 互動等。”

好,那就开始吧。第一步是先要下载jquery:

http://docs.jquery.com/Downloading_jQuery
接著將此 JS 檔放進您網頁 HTML 的 <head> 及 </head> 之間…

<script type="text/javascript" src="jQuery 檔案路徑"></script>

jQuery 所有的屬性及函式都是定義在「jQuery」這個物件之下,這使你不會因為使用 jQuery Library 而與原本有的全域變數等其它命名空間產生衝突。此外,要取得 jQuery 物件也可以透過它提供的的另外一個縮寫符號 (別名)-錢字號「$」,這時大家可能會問那我有使用其它的 JavaScript Library 也是用「$」怎麼辦?有辦法,用下面這一行就解決了:

jQuery.noConflict();

接著你就可以繼續用 $ 來操作你原本有的函式。但是如果你還是比較想用 $ 來操作 jQuery 怎麼辦?也有取巧的辦法:

(function($) {
    // 在此區塊內我們使 $ 參照 jQuery 物件
    // 在此區塊內使用 $ 不會與其它函式衝突
})(jQuery);

你也可以自己取個 jQuery Object 的別名:

var $alias = jQuery.noConflict();

接下來你就可以使用 $alias 取代 $。

jQuery 的基本操作概念 (Coding basics)

jQuery 程式碼由 $ (或jQuery) 開始 → 後面會接著圓刮號「()」→ 而圓刮號裡面的參數是你想叫 jQuery 幫你找什麼 (取得哪個(些)元素) → 接著是你想叫 jQuery 執行什麼動作 (或處理事件)。例如:

/*
$("#demo"):選取id為demo的元素,並綁定onclick事件
.css("background-color","gray"):
叫jQuery將其CSS的背景顏色屬性改成灰色
你可以用滑鼠點這個範例看效果
*/
$("#demo").click(function(){ $("#demo").css("background-color","gray"); });

Chaining - 串接

在 jQuery 中,幾乎所有成員都會返回自己執行後的結果-也是一個 jQuery 物件,因此你可以連續地使用函數 (Chaining)。以下我們用一個範例來說明 Chaining 是怎麼一回事:

$("#container").css("color", "blue").css("background-color", "red");

上面這段程式碼由兩段函式組成:

$("#container").css("color", "blue") → 將文字改成藍色
$("#container").css("background-color", "red") → 再將背景顏色改為紅色

利用 Chaining 只剩一行,是不是簡潔多了?

介绍一下Bucket Sort

排序算法是大家刚学编程的时候一定要学的算法,冒泡算法(bubble sort),快速排序(quick sort)等等相信大家耳熟能详。我下面要介绍的bucket sort其实大家应该也学过,不过最近刚刚帮别人交了一份作业,勾起了不少回忆,所以顺便在这里发出来。下面的算法有几个限制:所排序的一定要是正整数,至于整数的大小和个数都是可以修改的。

[code:c#]
#include
#include 

#define MAX_INT 65536
#define MAX_NO_INPUT 1000

struct bucket{
 int data;
 bucket* next;
};

void addToBucket(struct bucket *head[],int value)
{
 bucket* current;

 if (head[value] == NULL)
 {
  head[value] = (bucket*)malloc(sizeof(bucket));
  head[value]->data = value;
  head[value]->next = NULL;
 }
 else
 {
  current = head[value];
  while (current->next != NULL)
   current = current->next;
  current->next = (bucket*)malloc(sizeof(bucket));
  current->next->data = value;
  current->next->next = NULL;
 }
}
void printOut(bucket* head[],int size)
{
 int i=0;
 bucket *current;
 FILE *fp;

 fp = fopen("output.txt","w");

 for (i=size-1;i>=0;i--)
 {
  if (head[i] == NULL)
   continue;
  current = head[i];
  while(current != NULL)
  {
   fprintf(fp,"%d\n",current->data);
   current = current->next;
  }
 }
 fclose(fp);
}
int main()
{
 bucket* head[MAX_INT] = {NULL};
 int unsorted[MAX_NO_INPUT];
 FILE *fp;
 int i=0;

 //read in a file
 if ((fp = fopen("input.txt","r"))==NULL)
 {
  printf("Cannot open file");
  exit(0);
 }

 i=0;
 while (fscanf(fp,"%i\n",&unsorted[i])!=EOF && i< MAX_NO_INPUT)
  i++;
 fclose(fp);

 int length = i;
 i = 0;
 for (i=0;i

[/code]

以上的算法时间复杂度是O(n)。算是比较快速的排序算法,不过就跟所有算法一样,其实都是时间和空间上的取舍。它的空间复杂度相当大,尤其是在整数上限很大的情况下,更是占用了不少内存。所以,大家还是要按情况使用。

浅说C#里的指针用法

C#是一种高级语言,他其中一个特性就是Managed code的概念。整个C#的程序都是在.NET runtime里运行的,这个设计能够有效防止程序员一些错误的编程,有效提高了程序的稳定性。但如果我们有时候真的需要直接操作内存,或者想写一些高效的代码,是不是就没办法了呢?实际上,C#并没有完全去掉对指针和底层memory操作的支持。可是如果要想使用指针的话,就必须使用unsafe这个关键字。unsafe可以使用在一个方法上:

[code:c#]

unsafe int GetSomeNumber()
{
  //code that can use pointers
}

[/code]

当然,你也可以使用unsafe将真个类包起来:

[code:c#]

unsafe class MyClass
{
}

[/code]

同样的,也可以将类中的某个属性标记为unsafe

[code:c#]

class MyClass
{
  unsafe int* pX;
}

[/code]

或者你可以只将代码中的某一段包起来

[code:c#]

void MyMethod()
{
  //code that doesn't use pointers
  unsafe
  {
  }
}

[/code]

可是对于方法内部的本地变量,是不可以标识为unsafe的:

[code:c#]

int MyMethod()
{
  unsafe int *pX;   //WRONG
}

[/code]

如果想在方法内部使用一个指针性的本地变量的话,就要将该方法标识为unsafe或者在unsafe block内部声明该变量。最后,你只要在project properties里面的Build页面把allow unsafe code选项勾上就可以了。C#中关于指针的语法和C/C++差不多,在这里就不再详述了。唯一区别是在声明指针变量上面,C++是int *px, *py;而C#是int* px,py;在C#中*是跟随类型而不是跟随变量名的。

类成员的指针

在C#中,指向类的指针是不允许的。因为C#的garbage collector并没有维护指针的信息,指针指向的内存有可能在程序运行的时候被回收,造成意想不到的后果。可是我们有没有办法将指针指向类中的变量呢?比如我们有一个如下的类:

[code:c#]

class MyClass
{
  public long x;
  public float F;
}
MyClass myObject = new MyClass();
long* p: = &(myObject.X);
float* pF = &(myObject.F);

[/code]

如果你尝试编译以上代码的话你就会发现编译器会返回一个编译错误。原因就是因为在C#中,类是放在heap上的,garbage collector有可能随时将一个类移到新的地方,使得本来的指针指向了一个错误的位置。要解决这个问题,就要使用fixed关键字。将以上代码做以下的修改:

[code:c#]

MyClass myObject = new MyClass();
fixed(long* pL = &(myObject.X))
{
  //do something
}

[/code]

使用了fixed关键字,garbage collector就不会将该类移动到别处。fixed关键字还可以有以下用法:

[code:c#]

fixed(long *pL = &(myObject.X))
fixed(float *pF = &(myObject.F))
{
}

[/code]

或者

[code:c#]

fixed(long * pX=&(myObject.X), px2=&(myObject2.X))
{
}

[/code]