技术男儿裆自强

哭天喊地,跺脚骂娘,技术男儿裆自强

在php中设置cookie为httponly来减轻xss攻击的危害

| Comments

目前站点一般通过cookie保存登陆、认证等敏感信息,而通过xss窃取cookie,以实现窃取敏感信息、伪造用户登陆等,是一种常见的攻击方式。

防止xss的主要方法是对用户输入内容进行转义等等,可参见此雄文: Cross Site Scripting (XSS) Attacks: Methodology and Prevention。 本文主要讨论在php下如何设置cookie为httponly,来最大限度的减轻xss攻击的危害,提升网站的安全性。

httponly是微软在Internet Explorer 6 SP1中为cookie引入的一个新特性,客户端脚本无法访问具有改属性的cookie值。 敏感cookie都应设置为httponly,减轻xss攻击的危害。

目前所有主流浏览器都支持该特性,php从5.2.0开始引入该特性。 只需在调用setcookie函数时,传入相关参数即可,如:

1
setcookie("key", $value, time()+60 * 60 * 24 * 10, "/", "", FALSE, TRUE);

具体可见php文档

需要注意的是,销毁cookie时,setcookie后四个参数必须与设置cookie时严格相同,否则无法正确销毁。 例如销毁上面设置的cookie,需调用:

1
setcookie("key", "", time()-3600, "/", "", FALSE, TRUE);

还有一点特别需要注意,目前php的默认配置中,都会使用cookie来储存session id,见如下配置:

1
2
3
session.use_cookies = 1
session.use_only_cookies = 1
session.name = PHPSESSID

因此,有被截获cookie中的PHPSESSID,来劫持当前登陆用户会话的风险。 设置保存session id的PHPSESSID为httponly有两种方法。

  1. 修改php.ini,设置session.cookie_httponly = 1
  2. 在调用start_session()之前调用session_set_cookie_params(),设置相关参数。如:
1
session_set_cookie_params(0, "/", "", FALSE, TRUE);

具体可见php文档

两种方法各有优缺点。方法1必须改动php.ini,在某些虚拟主机无法实现,但方便快捷,修改一次全局生效。 方法2需要在每个start_session()调用,可能容易漏掉,但灵活性更强,也不用依赖配置环境。

等用户退出等需要主动销毁session的时候,除了session_destroy()以外,还需要销毁cookie中的PHPSESSID。

一般资料中介绍的方法如下

1
2
3
if (isset($_COOKIE[session_name()])) {
    setcookie(session_name(), '', time() - 3600);
}

但如前所述,如果销毁时setcookie参数跟创建时不同,将无法正确销毁,用改方法基本都会失败。 正确的做法为:

1
2
3
4
5
6
7
8
9
$sessionName = session_name();
$sessionCookie = session_get_cookie_params();

session_destroy();
$_SESSION = array();

if (isset($_COOKIE[$sessionName])) {
    setcookie($sessionName, false, $sessionCookie['lifetime'], $sessionCookie['path'], $sessionCookie['domain'], $sessionCookie['secure']);
}

Gentoo下使用nginx+fastcgi部署trac

| Comments

首先,运行

emerge --ask nginx trac

安装所需应用。

需注意确保trac的USES标记中含有fastcgi与vhosts。 如果没有vhosts,trac安装完成后会自动调用webapp-config在localhost虚拟目录下创建trac应用,而本人更倾向于根据需要手动安装。

运行

webapp-config -I -h trac trac 1.0.1

将trac安装在名为trac的虚拟目录下。 再运行

trac-admin /path/to/project initenv

按提示创建trac环境。 详细介绍及trac环境的目录结构见wiki

发布静态资源,以便通过nginx直接提供,提高效率:

trac-admin /path/to/project deploy /var/www/trac

如配置为多项目,则需将/var/www/trac/htdocssitecommon目录移至/var/www/trac/htdocs/project下。

以nginx+fastcgi方式部署trac时,前端nginx做转发,后端fastcgi运行方式有两种:

  • 利用spawn-fcgi等服务,管理运行trac虚拟目录下cgi-bin/trac.fcgi脚本。
  • 以fcgi协议运行tracd服务。

由于使用tracd配置最为便捷,其他人提及的又相对较少,所以本文主要介绍后者。

Intel主板raid1灾难恢复小计

| Comments

本人电脑用intel主板raid1来备份重要数据,昨天发现其中一块盘挂了。 二话不说换上一块新盘,开机Ctrl+I进入intel raid管理界面,设置好之后进入操作系统进行raid重建。

一是偷懒,二是想打会游戏,所以重建工作选择进入windows进行。 打开最新版Intel Matrix Storage Manager程序,会自动检测并重建raid1阵列。 也可以在linux下使用mdadm进行重建。

重建完成后,重启进入linux,运行mount /dev/md126 /mnt进行挂载,却出现以下错误:

mount: wrong fs type, bad option, bad superblock on /dev/md126, missing codepage or helper program, or other error In some cases useful info is found in syslog – try dmesg | tail or so

用testdisk查看分区表:

testdisk /list /dev/md126

与原始分区相符,目测分区表没有问题,应该是文件系统受损。

用fsck进行检测:

fsck /dev/md126

出现以下提示:

The filesystem size (according to the superblock) is 244189980 blocks The physical size of the device is 244189952 blocks Either the superblock or the partition table is likely to be corrupt! Abort <y>?

猜测是新换的硬盘跟原来的型号不一样(一个希捷一个西数),造成的上述问题。

输入y退出fsck检测,google一番后,找到如下解决方案:

resize2fs -f /dev/md126 244189952

运行该命令将filesystem size重设为244189952(fsck检测时提示的physical size)。 重新运行fsck /dev/md126进行检测,无任何问题。挂载后查看数据,完好如初。

谨以此记。

Linux之主板raid(fake Raid): Dmraid or Mdadm

| Comments

当系统有多块硬盘时,通过组建raid以提升磁盘性能或提供磁盘冗余,往往成为人们的首选考量。 当今主流raid实现方案大致可分为三种:

  • 硬件raid(hardware raid),通过购买昂贵的raid卡实现,我等平民不考虑。
  • 软件raid(software raid),通过操作系统内软件创建阵列,raid处理开销由CPU负责。
  • 主板raid(fake raid),通过主板内建raid控制器创建阵列,由操作系统驱动识别。

需要注意的是,fake raid仅提供廉价的控制器,raid处理开销仍由CPU负责,因此性能与CPU占用基本与software raid持平。 如果只有单个linux系统,使用software raid一般比fake raid更健壮,但是,在多启动环境中(例如windows与linux双系统),为了使各个系统都能正确操作相同的raid分区,就必须使用fake raid了。 可参考FakeRaidHowto @ Community Ubuntu Documentation以获得更多相关信息。

linux下最重要的raid管理程序为dmraidmdadm。 本人印象中,前者用于识别rake raid,后者用于管理software raid,但最近更新系统时突然发现,openSUSE及rhel等发行版都改用mdadm替代dmraid来处理rake raid。 放狗搜索一番后,发现大家都有相似的疑问,便想到简单考察总结一番,对linux下rake raid应该使用dmraid还是mdadm进行管理做一个评判。

Chartboost-x新鲜出炉: C++ Wrapper of Chartboost for Cocos2d-x

| Comments

前几日团队的手游项目到了交付阶段,运营商要求在游戏中加入Chartboost支持,以实现交叉推广。

该平台的最大特点就是:全屏广告!让玩家欲罢不能,横竖都得点一下-_–! 虽然对用户体验有一定影响,但据说效果很好,点击率超高,捷报频频。Backflip,Crowdstar, Disney, Gameloft, Get Set Games, GREE, Kabam, Kiloo, Playfirst, Pocket Gems, TinyCo等等大厂都在使用,实乃交叉推广之必备良药。

我们的游戏使用cocos2d-x引擎,逻辑代码由C++编写。为了在C++代码内直接调用Chartboost相关接口,本人对Chartboost提供的iOS和Android SDK做了一个简单的C++封装,方便使用。 最近闲来无事,对相关代码加以完善整理,取名为Chartboost-x,现正式放出,以造福大众!源代码与详细说明请见:

Chartboost-x GitHub页

该封装基本覆盖了Chartboost SDK的所有接口,实现了包括Delegate等功能,运行良好,使用简单。如果您碰巧也使用cocos2d-x,碰巧也需要Chartboost,那一定要clone下来看看,或许能节省您不少宝贵时间。

向Octopress添加JiaThis分享工具及冲突解决

| Comments

Octopress默认集成twitter、google +1、facebook like等分享工具,只需补全配置文件_config.yml中的相关信息即可。

但是,但是,作为水深火热的墙内人民,这些工具大部分状况下都处于瘫痪状态,甚至会拖慢整个站点的加载速度。 权衡起见,只得在_config.yml中注释掉twitter、google +1、facebook like相关选项, 并添加对JiaThis等分享工具的支持。

此外,JiaThis与Octopress的Video模块有一点小冲突,会导致分享工具条左下角被一个小白框遮盖,像一块烦人的膏药,需要做一定处理。

1. 向_config.yml中添加JiaThis配置开关

仿照原始风格,在_config.yml底部添加如下配置:

1
2
# JiaThis
jiathis: true

以后,想要开启或关闭JiaThis,只需修改该配置值即可。

2. 集成JiaThis代码

修改source/_include/post/sharing.html,在最后一行</div>前添加如下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{% if site.jiathis %}
  <!-- JiaThis Button BEGIN -->
  <div class="jiathis_style">
    <span class="jiathis_txt">分享到:</span>
    <a class="jiathis_button_tsina">新浪微博</a>
    <a class="jiathis_button_googleplus">Google+</a>
    <a class="jiathis_button_renren">人人网</a>
    <a class="jiathis_button_qzone">QQ空间</a>
    <a class="jiathis_button_tqq">腾讯微博</a>
    <a href="http://www.jiathis.com/share" class="jiathis jiathis_txt jiathis_separator jtico jtico_jiathis" target="_blank">更多</a>
    <a class="jiathis_counter_style"></a>
  </div>
  <script type="text/javascript" src="http://v2.jiathis.com/code/jia.js?uid=1334720487296344" charset="utf-8"></script>
  <!-- JiaThis Button END -->
{% endif %}

其中2到14行为从http://www.jiathis.com/获取的分享代码,可自行定制。

MacVim处理中文时卡顿、CPU占用过高问题

| Comments

问题出现在MacVim-snapshot-65版本

本人一般用MacVim编辑文档。近期发现编辑含有大段中文的markdown文档时,出现卡顿、MacVim进程CPU占用严重过高问题。 google搜索无果,自行研究,过程如下:

  • 打开纯英文markdown文档,不管多长都不会出现卡顿问题。
  • 打开大段中文txt文件,未出现卡顿问题。
  • 考虑可能是语法高亮造成卡顿问题,关闭语法高亮,大段中文的markdown文档未出现卡顿问题。

虽然关闭语法高亮可以解决卡顿问题,但是。。。这个必须得有啊!!!

继续研究,偶然发现,在Preferences对话框中选择Advanced选项卡,去掉Use Core Text renderer选项的勾勾, 则打开语法高亮后,大段中文也不会造成卡顿,至此问题解决。

虽然去掉Use Core Text renderer选项后,渲染效果变差一点点,无法使用透明效果,偶尔出现残像,但总比没有语法高亮强。 Sigh…

小议libjpeg解压损坏文件时的错误处理

| Comments

本文主要介绍libjpeg解压损坏文件时,可能的一些错误与处理方法。libjpeg的常规使用请参阅文档或其他文章。

问题1:错误处理

使用libjpeg解压文件时难免产生错误,原因可能是图片文件损坏、io错误、内存不足等等。 默认的错误处理函数会调用exit()函数,导致整个进程结束,这对用户来说是非常不友好的。我们需要注册自定义错误处理函数,改变此行为。

libjpeg采用c语言的setjmp/longjmp机制实现错误处理,首先需要包含以下头文件:

1
#include <setjmp.h>

定义错误处理结构体:

1
2
3
4
5
6
7
struct my_error_mgr {
  struct jpeg_error_mgr pub;  /* "public" fields */

  jmp_buf setjmp_buffer;    /* for return to caller */
};

typedef struct my_error_mgr * my_error_ptr;

实现错误处理函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
METHODDEF(void)
my_error_exit (j_common_ptr cinfo)
{
  /* cinfo->err really points to a my_error_mgr struct, so coerce pointer */
  my_error_ptr myerr = (my_error_ptr) cinfo->err;

  /* Always display the message. */
  /* We could postpone this until after returning, if we chose. */
  (*cinfo->err->output_message) (cinfo);

  /* Return control to the setjmp point */
  longjmp(myerr->setjmp_buffer, 1);
}

以上代码只是简单的打印错误信息,之后调用longjmp,使控制流跳转到setjmp设置的代码块。 如果需要,还可通过cinfo->err->msg_code判断错误类型,进行进一步处理。