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 專案內的行為流程中,就可以在"新增區隔",從 "進階條件" 撈出自訂維度來看行為。

2019年7月24日 星期三

[C] 透過 CMAKE 搜尋 OpenSSL 函式庫產出 MD5 資料

最近幫同事 debug embedded linux 問題,恰好需要用 MD5 來做 hash ,隨意找找就用 OpenSSL 函式庫就對了。再加上原先寫的小程式已經靠 CMAKE 維護了,就繼續整合使用

CMakeLists.txt:

$ cat CMakeLists.txt
cmake_minimum_required(VERSION 3.11)
project (MD5)

SET(SOURCE_DIR ${CMAKE_SOURCE_DIR}/src)

# macOS
# $ mkdir b ; cd b;
# $ cmake .. -DOPENSSL_ROOT_DIR=/usr/local/opt/openssl -DOPENSSL_LIBRARIES=/usr/local/opt/openssl/lib
#
find_package(OpenSSL REQUIRED)
include_directories(${OPENSSL_INCLUDE_DIR})

ADD_EXECUTABLE(main
${SOURCE_DIR}/main.c
)
TARGET_LINK_LIBRARIES(main OpenSSL::SSL)


程式碼:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <openssl/md5.h>

const char * get_md5_string(const unsigned char *in, char *output) {
int i;
for(i = 0 ; i < MD5_DIGEST_LENGTH ; i++) {
sprintf(output + (i)*2, "%02x", in[i]);
}
output[MD5_DIGEST_LENGTH*2] = '\0';
return output;
}

int main(int argc, char *argv[]) {
unsigned char digest[MD5_DIGEST_LENGTH];
char readable_digest[MD5_DIGEST_LENGTH*2 + 1];

char *test = "HelloWorld";
char *input;

if (argc > 1)
input = argv[1];
else
input = test;

MD5_CTX context;
MD5_Init(&context);
MD5_Update(&context, input, strlen(input));
MD5_Final(digest, &context);

get_md5_string(digest, readable_digest);

printf("MD5: [%s]\n", readable_digest);

return 0;
}


編譯跟運行:

$ mkdir b
$ cd b ; çmake ..
$ make
$ ./main HelloWorld
MD5: [68e109f0f40ca72a15e05cc22786f8e6]
$ echo -ne "HelloWorld" | md5
68e109f0f40ca72a15e05cc22786f8e6

2019年7月3日 星期三

公司營運資方人力成本 筆記

公司營運人力成本級距

最近證交所公布了 "發布國內上市公司106年度「平均員工薪資費用」排序前50名及後50名資訊" ,引起了一陣騷動,各大媒體也一直拿來報,但很少人仔細去看證交所的那篇文章,覺得滿有意思的,筆記一下:
發布國內上市公司106年度「平均員工薪資費用」排序前50名及後50名資訊

經統計,844家國內上市公司106年度公告之財務報告,稅前淨利合計2兆5,764億元,較105年度成長3,599億元(增幅16.24%),營運有獲利者計697家(占比82.58%);106年度員工福利費用(包括薪資、勞健保、退休金及其他)總額計1兆3,753億元,較105年度之1兆3,065億元增加5.27%,106年度之總人均員工福利費用112.11萬元較105年度之108.93萬元增加2.92%;另106年度員工薪資費用總額計1兆1,450億元(占員工福利費用比重約83.25%),員工人數合計約123萬人,總人均年薪約93萬元。
有關國內上市公司106年度平均員工薪資費用之統計情形說明如下:
一、平均員工薪資費用「排序前50名」之公司名單(依金額高至低排序)詳附件一:http://www.twse.com.tw/downloads/zh/about/press_room/doc/news-20180620001.xlsx
(一)排序前50名公司之員工年薪平均約144.3萬元至287.5萬元,營運有獲利者計48家公司(占比96%)。
(二)以產業別分析,屬電子產業者計38家公司(占比76%,其中半導體業者計19家),顯示其產業競爭力強、較有能力或意願將獲利回饋員工。
(三)排序前50名公司中,計19家公司之員工薪資費用包含依股份基礎給付(如員工認股權、限制權利新股、買回股份轉讓予員工等)之評價金額,其中電子業公司占16家,主係企業為延攬人才或獎酬員工所致
我一開始也以為那份薪資水準是基層人員的平均,雖說平均仍不如中位數準確(平均男女有一顆蛋蛋),但也有些參考價值,但仔細看 Excel 檔案後,發現那份是包含董事:
http://www.twse.com.tw/downloads/zh/about/press_room/doc/news-20180620001.xlsx 
資料來源及統計範圍說明:
(一) 就842家公告106年度財報之國內上市公司,參酌中小企業認定標準剔除員工人數未達100人之公司,並衡酌控股公司實際營運主體為各子公司,爰排除投資控股公司及金融控股公司後,以687家國內上市公司為統計範圍。
(二) 依前述公司106年度(個體、個別)財務報告附註揭露之員工薪資費用及員工人數,核計「平均員工薪資費用」算術平均數後進行排序。
(三) 「員工」可能以全職、兼職、永久、不定時或臨時之方式提供服務予企業,員工包括董事及其他管理人員。各公司財報附註揭露之員工包括董事、經理人、全職員工及臨時工等,惟不包含派遣或業務承攬外包人員。
(四) 「員工薪資費用」包括薪資、獎金、紅利等,亦包含依股份基礎給付評價之金額,暨給付董事之報酬、酬勞。
所以,只要包含董事管理層福利,參考價值就低不少 Orz 只能期待那篇證交所文章所提:
綜上,為精進上市公司之員工薪酬統計作業,使其更具可比較性、合理性、客觀性,經參酌金管會107年4月24日發布「新版公司治理藍圖」將循序推動上市公司揭露員工薪酬資訊之計畫項目(非擔任主管職務之員工人數及員工薪酬中位數、平均數),及金管會發布各業別「財務報告編製準則」規定之員工人數及員工福利費用性質別資訊(預告自107年度財務報告起將單獨揭露「董事酬金」及「未兼任員工之董事人數」),暨參考行政院主計總處之薪資統計重要名詞定義(如:受僱之全時員工、總薪資中位數等),證交所將配合增訂相關資訊申報項目及定義,並研議低薪公司之篩選標準,暨洽請渠等公司說明經營績效與員工薪酬之關聯性與合理性,期能以市場機制促使上市公司訂定合理之員工報酬,落實公司治理與企業社會責任。
盡快推出 "非擔任主管職務之員工人數及員工薪酬中位數、平均數" ,這個才是有幫助的資訊。

後來,跟朋友哈拉一陣子,跑去研究第二名的和泰汽車,筆記一下 “公司營運人力成本” 的容易忽略的項目:

  • 年薪用 14 個月、12個月的差異
  • 年薪用獎金制填補

這邊就簡化成年薪 14個月 跟 12個月 的差別筆記:

  • 首先,公司需要負擔員工的勞保(級距)、健保(級距)、退休金(級距6%) 的人力成本,這是最基本的法規
  • 勞保級距對於高科技行業很容易就進入到 Max 值,當月薪超過 45,800 後,就統一繳固定額度
  • 健保的級距很廣,可以到月薪18萬
  • 退休金的級距也廣,但只有到月薪15萬,依據對應級距提播 6%

在網路上可以看到有位和泰汽車的業務,說月薪四萬,但加了獎金可達年薪九十萬。這個現象,若把年薪拆分成12個月月薪,那月薪應當落在七萬五。

在以上的條件上製作表格,粗略可以得知,若公司聘人落在 20 人時,用月薪4萬+年獎金制度,會比純月薪制度省了快一個人力成本出來,也就是一樣的支出預算,用獎金制度可以多聘請一人。

公司營運人力成本範例

參考資料: