2019年8月22日 星期四

[macOS] 使用 cURL command 上傳檔案且修改 Content-Disposition filename 欄位資訊

故事是為了檢驗 embedded linux 上,一些 CGI 資安問題。例如有隻 CGI 提供檔案上傳時,通常上傳完後就把檔案擺在指定位置。但擺放到指定位置時,若沒有寫好,直接拿 filename 去擺放時,就有機會做邪惡的事了!

而透過 cURL 上傳檔案,通常是用以下簡單的指定就完成:

$ curl -F "[email protected]/tmp/sample.txt" http://192.168.1.1/cgi-bin/upload.cgi

但如果細看表單內容物時,產出的結果:

POST /cgi-bin/upload.cgi HTTP/1.1
Host: 192.168.1.1
Content-Type: multipart/form-data
Content-Length: ##

----------########
Content-Disposition: form-data; name="file";
filename="sample.txt"

...


這時,有些 CGI 開發上會直接拿上述 filename 參數資訊來用,寫不好就會產生跳脫問題,如:

Content-Disposition: form-data; name="file";
filename="../etc/sample.txt"


若底層是直接用 sprintf(des_filepath, "/tmp/%s", filename); 就會有機會逃脫去覆蓋掉東西。幸運的是 embedded linux 大多會設定檔案系統是 Read-only file system 來保護 :P 若是用 PHP 時,大多都靠 basename 來保護了。

最後,補上靠 curl 串改 filename 的招數:

$ curl -F "[email protected]/tmp/sample.txt; filename=../etc/sample.txt" http://192.168.1.1/cgi-bin/upload.cgi

2019年8月7日 星期三

[開箱] 小米 A3 / Android One

小米A3

上一次買小米是小米2S的時代了 XD 用完小米2S就改用 iPhone SE 至今!

為何想買支 Android phone 呢?其實數個月來一直被 Pixel 3 / Pixel 3a 打中慾望,再加上手上的測試機 ASUS 表現不怎好,而左想右想自己也不會跳去改用 Android phone 了,就花 Pixel 3a 半個預算買隻接近 Android 原生手機,Android One 還可有兩年作業系統更新、三年月月安全更新的保證,雖說 Android 系統改朝換代時,硬體需求變化極快,有些手機硬體規格都撐不到兩年就不敷使用了。

關於 Android One 的故事,可以參考 WIKI:https://zh.wikipedia.org/wiki/Android_One

小米A3

而我自己下單前也有點遲疑,像是 NFC 功能無法測試 <囧> 而有的人是嫌棄他的 CPU 運算能力不夠新不夠強悍。目前使用的感覺非常良好!重溫 Android 中。

小米A3

Google Analytics 筆記 - 透過 gtag.js 回報 pageview 時,進行 Custom dimensions 回報

在 gtag 的自訂維度的文件上,是以 event 來教學的:gtagjs/custom-dims-mets 且 gtag 的 pageview 文件也是滿精簡:gtagjs/pages

遙想以前 ga 可以很直觀地靠 set 指令 處理:

ga('create', 'UA-XXXX-Y', 'auto');
// 設定指數 1 的自訂維度值。
ga('set', 'cd1', 'Level 1');
// 送出自訂維度值及瀏覽量匹配資料。
ga('send', 'pageview');


最後東摸摸西摸摸,找到一招,就是要發送自訂維度時,一口氣完成定義跟使用:

var params = {
'send_page_view': true,
'page_title' : title,
'page_path': path,
};

var custom_value = getSpecialInfo();
if (custom_value) {
params['ab_user'] = custom_value;
params['custom_map'] = {
'dimension1': 'ab_user',
};
}
gtag('config', 'UA-XXXX-Y', params);


而為何需要使用到這些,其實就是想多做更多的用戶分類,例如 A/B Test 時,更細膩的追蹤用戶行為。若採用 Google Analytics 實驗功能,可以直接靠 實驗/實驗ID 來區分。另外 Google 實驗在 2019/08/07 起已經移師到 Google 最佳化工具囉。只是使用 optimize.google.com 服務時,有些使用情境不太適合,像是網頁一初始畫面就要依照 A/B Test 分群做 UI 改變時,設計上只能先等 optimize.google.com js sdk 初始化才能做事,這就會稍微給人體驗不佳。如果操作上跟網頁初始化無關,如用戶點擊按鈕才依照 A/B Test 分群做不一樣的效果,那就還滿適合善用 optimize.google.com 提供的功能。

目前單靠 google analytics 自訂維度,再靠土炮 A/B 分群方式,把用戶標籤記錄在 cookie 使用:

// AB Test
function getRandomValue(min,max){
return Math.floor(Math.random()*(max-min+1))+min;
}

if (!getCookie(ab_test_cookie_name)) {
var user_flag = getRandom(1,10) > 5 ? '201908-a' : '201908-b';
setCookie(ab_test_cookie_name, user_flag, 365, '/');
}


後續在 google analytics 專案內的行為流程中,就可以在"新增區隔",從 "進階條件" 撈出自訂維度來看行為。