乡村教师

【乡村教师】

(《科幻世界》杂志 2001年1月第1期)

他知道,这最后一课要提前讲了。

又一阵剧痛从肝部袭来,几乎使他晕厥过去。他已没能气力下床了,便艰难地移近床边的窗口。月光映在窗纸上,银亮亮的,使小小的窗户看上去象是通向另一个世界的门,那个世界的一切一定都是银亮亮的,象用银子和不冻人的雪做成的盒景。他颤颤地抬起头,从窗纸的破洞中望出去,幻觉立刻消失了,他看到了远处自己渡过了一生的村庄。

……

Continue reading

鲸歌

(《科幻世界》杂志 1999年6月第6期)

沃纳大叔站在船头,望着大西洋平静的海面沉思着。他很少沉思,总是不用思考就知道怎样做,并不用思考就去做,现在看来事情确实变难了。

沃纳大叔完全不是媒体所描述的那种恶魔形象,而是一副圣诞老人的样子。除了那双犀利的眼晴外,他那圆胖的脸上总是露着甜密而豪爽的笑容。他从不亲自带武器,只是上衣口袋中装着一把精致的小刀,他用它既削水果又杀人,干这两件事时,他的脸上都露着种笑容。

……

Continue reading

西洋

[刘慈欣]

西元1420年,非洲,索马利亚,摩加迪沙沿海

这是明朝舰队打算到达的最远的地方,永乐皇帝也只让走到这里,现在,二百多只船和两万多人,静静地等待着返航的命令。

郑和沉默地站在“清和”号的舰首,他面前,印度洋笼罩在热带的暴雨中。四周一片雨雾,只有闪电剌破这一片朦胧时,舰队才在青色的电光中显现,“清远”号、“惠康”号、“长宁”号、“安济”号……如同围在旗舰四周纹丝不动的巨大礁石。众多的非洲酋长在船上欢宴三天后已上岸,激越的非洲鼓声从雨中隐隐传来,岸上棕榈林中打鼓的黑人狂舞的身影如暴雨中时隐时现的幽灵。

……

Continue reading

太原之恋

[刘慈欣]

诅咒1.0诞生于2009年12月8日。

这是金融危机的第二年,人们本来以为危机快要结束了,没想到只是开始。社会处于一种焦躁的情绪中,每个人都需要发泄,并积极创造发泄的方式,诅咒的诞生也许与这种氛围有关。

诅咒的作者是一个女孩儿,18岁至28岁之间,关于她,后来的IT考古学家们能知道的就这么多。诅咒的对象是一个男孩儿,20岁,他的情况却都记载得很清楚,他叫撒碧,在太原工业大学上大四。他和那女孩儿之间发生的事儿没什么特别的,也就是少男少女之间每天都在发生的那些事儿,后来有上千个版本,这里面可能有一个版本是真实的,但人们不知道是哪一个。反正他们之间的事情都结束后,那女孩儿对那男孩儿是恨透了,于是编写了诅咒1.0。

……

Continue reading

如何处理有难度的场景

概述

工作中经常会遇到各种各样的困难,或者是艰难场景,如果处理不好,会对同事,工作,项目造成影响。

常见的一些类型

  • 目标冲突

    一个人给出的目标与另一个人共享的目标相冲突, 比如员工的个人职业规划和安排的工作目标有冲突。

  • 角色冲突

    当某人要执行一项不属于他们通常的角色或职责的任务时,或者当他们被要求做一些本应由其他人负责的事情时。 比如要求开发人员做UAT之类的.

    ……

Continue reading

Cacheable SSL Page Found

Issue

Cacheable SSL Page Found

Risk

It is possible to gather sensitive information about the web application such as usernames, passwords, machine name and/or sensitive file locations

Cause

Sensitive information might have been cached by your browser

Fix

Prevent caching of SSL pages by adding “Cache-Control: no-store” and “Pragma: no-cache” headers to their responses.

Possible solution

you can also change the HTTP method from GET to POST if it is NOT a page but a rest API.

……

Continue reading

Cookie With Insecure or Improper or Missing SameSite Attribute

Issue

Cookie with Insecure or Improper or Missing SameSite attribute

Risk

Prevent cookie information leakage by restricting cookies to first-party or same-site context, Attacks can extend to Cross-Site- Request-Forgery (CSRF) attacks if there are no additional protections in place (such as Anti-CSRF tokens).

Cause

Sensitive Cookie with Improper or Insecure or Missing SameSite Attribute

Fix

Review possible solutions for configuring SameSite Cookie attribute to recommended values

for K8s, you may edit the ingress configuration, set samesite value

nginx.ingress.kubernetes.io/session-cookie-samesite: "Strict"
……

Continue reading

Blind Sql Injection

Security

  • Risk: It is possible to view, modify or delete database entries and tables

  • Cause: Sanitation of hazardous characters was not performed correctly on user input

  • Fix: Review possible solutions for hazardous character injection

  • Reasoning: The test result seems to indicate a vulnerability because it shows that values can be appended to parameter values, indicating that they were embedded in an SQL query. In this test, three (or sometimes four) requests are sent. The last is logically equal to the original, and the next-to-last is different. Any others are for control purposes. A comparison of the last two responses with the first (the last is similar to it, and the next-to-last is different) indicates that the application is vulnerable.

How to fix

https://sequelize.org/v5/manual/raw-queries.html

make sure to ‘replace’/‘bind’

……

Continue reading

Golang Oauth2 Github

Github Oauth2

首先,在github上申请一个Oauth App, 获取client id / secret

需要这些信息,下边的代码是放在环境变量中

    AUTH_URL      = os.Getenv("AUTH_URL") // github authorization url
    TOKEN_URL     = os.Getenv("TOKEN_URL") // github token url
    CLIENT_ID     = os.Getenv("CLIENT_ID") // client id
    CLIENT_SECRET = os.Getenv("CLIENT_SECRET") // client secret
    REDIRECT_URL  = os.Getenv("REDIRECT_URL") // the redirect url

在包的初始化代码中,初始化

  var (
    oauth2Config *oauth2.Config
  )

  init() {
    oauth2Config = &oauth2.Config{
    ClientID:     CLIENT_ID,
    ClientSecret: CLIENT_SECRET,
    RedirectURL:  REDIRECT_URL,

    // Discovery returns the OAuth2 endpoints.
    Endpoint: oauth2.Endpoint{
            AuthURL:   AUTH_URL,
            TokenURL:  TOKEN_URL,
            AuthStyle: oauth2.AuthStyleInHeader,
    },

    Scopes: []string{"openid", "email", "site_admin", "repo", "admin:org", "user"},
  }

Login handler

  func HandleRedirect(w http.ResponseWriter, r *http.Request) {
    //you need to generate random state here
  http.Redirect(w, r, oauth2Config.AuthCodeURL(state), http.StatusFound)
  }

callback handler

  func HandleOAuth2Callback(w http.ResponseWriter, r *http.Request) {
        log.Printf("Processing response")
        state := r.URL.Query().Get("state")
        target, ok := stateMap[state]
        if !ok {
                http.Error(w, "missing target in request", http.StatusBadRequest)
        }

        // remove from map
        // delete(stateMap, state)

        log.Printf("in HandleOAuth2Callback, target url : %s", target)

        user, err := getUserInfo(r.FormValue("code"))

        // create the user if not found

        tNow := time.Now()
           claims := jwt.StandardClaims{
                Issuer:    "CCMS Application",
                Subject:   user,
                IssuedAt:  tNow.Unix(),
                ExpiresAt: tNow.Add(2 * time.Hour).Unix(), // two hours
        }
        token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
        ss, err := token.SignedString(jwtKey)
        if err != nil {
                http.Error(w, "Failed to sign the token : "+err.Error(), http.StatusInternalServerError)
                return
        }
        rUrl := fmt.Sprintf("%s?token=%s", target, ss)
        log.Printf("redirect to :%s", rUrl)
        http.Redirect(w, r, rUrl, http.StatusFound)

the function to exchange code to get access token

  func getUserInfo(code string) (string, error) {
        token, err := oauth2Config.Exchange(oauth2.NoContext, code)
        if err != nil {
                return "", fmt.Errorf("code exchange failed: %s", err.Error())
        }
        ctx := context.Background()
        log.Printf("access token: %+v", token)
        // token.AccessToken --- this is the token you can use to call github api
        return email, nil
  }
……

Continue reading

Terminate Golang App

channel to terminate

在 main.go中, 创建一个channel接收os.Signal

 sigChan := make(chan os.Signal, 1)
	// ctrl+c->SIGINT, kill -9 -> SIGKILL
	signal.Notify(sigChan, syscall.SIGINT, syscall.SIGKILL)

在main.go快结束的位置,加上

 <-sigChan
log.Info("exit")

如果用户有发送kill -9 或者ctrl+c, 会接收到这个信号。

……

Continue reading