V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
fytriht
V2EX  ›  信息安全

发现微博 mobile web 版的登陆接口完全不设防

  •  
  •   fytriht · 2017-02-18 16:12:40 +08:00 · 7671 次点击
    这是一个创建于 2837 天前的主题,其中的信息可能已经有所发展或是发生改变。

    地址: https://m.weibo.cn 登陆接口: https://passport.weibo.cn/sso/login

    不用抓包工具,直接用 chrome dev tools 就可以找到接口,没有验证码(试了几十次没有遇到过), Post 的账号密码数据也没有加密.... 是因为是测试版的缘故吗?

    分享一下我模拟登陆的代码:

    const superagent = require('superagent')
    
    const weiboLogin = (username, password) => {
      const loginApi = 'https://passport.weibo.cn/sso/login'
      const formData = { username, password }
      const headers = {
        'Referer': 'https://passport.weibo.cn/signin/login',
        'Content-Type': 'application/x-www-form-urlencoded'
      }
      return new Promise((resolve, reject) =>
        superagent.post(loginApi)
          .set(headers)
          .send(formData)
          .end((err, res) => {
            if (err) reject('something went wrong.')
            try {
              const { rawHeaders, text } = res.res
              const cookie = rawHeaders.filter(item => item.startsWith('SUB='))
                               .map(item => item.split(';')[0])
                               .join()
              const uid = JSON.parse(text).data.uid
              if (uid === undefined) reject('wrong password or username')
              resolve({ cookie, uid })  // uid: user ID
            } catch (err) {
              reject('something went wrong.')
            }
          })
      )
    }
    
    weiboLogin('username', 'password')
      .then(res => console.log(res.cookie))
      .catch(console.error)
    

    项目地址是 https://github.com/fytriht/weibo-cleaner

    61 条回复    2017-02-19 23:49:21 +08:00
    Kilerd
        1
    Kilerd  
       2017-02-18 16:31:09 +08:00 via iPhone
    用了 https 还需要加密传输吗??? 黑人问号
    fytriht
        2
    fytriht  
    OP
       2017-02-18 16:41:28 +08:00 via Android
    @Kilerd 加密的话起码没那么容易实现模拟登录吧
    msg7086
        3
    msg7086  
       2017-02-18 16:58:48 +08:00
    @fytriht 加密为什么就不容易了?
    shiji
        4
    shiji  
       2017-02-18 17:07:01 +08:00 via Android
    @fytriht 要不你来提一个不容易实现模拟登录的加密方案?
    terence4444
        5
    terence4444  
       2017-02-18 17:13:29 +08:00 via iPhone
    我看过一点,它的代码是加了一点点东西的,比如密码的 id 就会加个 4 位随机数字。有时候会跳验证码出来。
    laoyur
        6
    laoyur  
       2017-02-18 17:46:18 +08:00
    楼主说的没有加密,应该指的是密码明文
    为什么 https 了就可以理直气壮地密码明文了??? 黑人问号
    Jaylee
        7
    Jaylee  
       2017-02-18 17:49:28 +08:00
    @laoyur 那该怎么做呢? 你说个方案看看?
    chinafeng
        8
    chinafeng  
       2017-02-18 17:51:39 +08:00
    前端做再多加密, JS 跑一跑, 不就都出来了吗...
    laoyur
        9
    laoyur  
       2017-02-18 18:06:02 +08:00
    @Jaylee #7 加密是不能保证被模拟登录,我关注的点是明文密码传输。最理想的情况,我当然希望我的密码不要被明文入库,或者新浪被拖库后我的明文密码不会被爆出来咯
    当然如果政策要求或者其他原因得不到这样的保障,我也一点办法也没有。不过这并不妨碍我有“不要明文传输密码”的诉求啊
    gouchaoer
        10
    gouchaoer  
       2017-02-18 18:12:32 +08:00 via Android
    web 端登陆 url 没法隐藏的,至于验证码问题只是你登陆不够多,放穷举肯定做了的
    miyuki
        11
    miyuki  
       2017-02-18 18:45:17 +08:00 via Android
    哇居然有用 Promise
    fytriht
        12
    fytriht  
    OP
       2017-02-18 19:13:38 +08:00
    @miyuki 什么意思?
    Quaintjade
        13
    Quaintjade  
       2017-02-18 19:33:22 +08:00 via Android   ❤️ 1
    @laoyur
    SSL 本来就是让应用层不用操心加密的事。既然是 HTTP over SSL ,那么 HTTP 用明文传输并没什么问题。

    你担心明文入库那是另一个问题,和明文传输没必然关系。
    如果你信不过网站的人品的话,更好的办法是用密码管理软件给每个网站设不同密码。
    billlee
        14
    billlee  
       2017-02-18 19:33:35 +08:00
    @laoyur https 了还哪来的明文传输?
    langmoe
        15
    langmoe  
       2017-02-18 19:34:19 +08:00   ❤️ 1
    照这逻辑怕是世界上大部分网站都不设防,谷歌登陆的账号密码也是明文 POST 的
    验证码没试过不下结论,但是倾向于 10L 的观点,毕竟国内公网 IP 是个稀缺资源,设计上还是得留点空间的
    Jaylee
        16
    Jaylee  
       2017-02-18 19:53:01 +08:00
    @laoyur 多读书
    laoyur
        17
    laoyur  
       2017-02-18 20:09:23 +08:00
    @Quaintjade #13
    @langmoe #15
    的确明文入库和明文传输没必然关系,明文传输(确切说是原始密码传输)到服务端后,并不能证明服务端就明文入库。但如果能在源头就杜绝了原始密码传输,让其对服务端都不可见,那不是能最大限度防止原始密码被泄漏么。当然,可能我过于理想化了。

    @billlee #14 我的意思是原始密码传输,如引起误解请见谅

    @Jaylee #16 一言不合就让我多读书,谢谢你的意见,对的,谁都应该多读书。
    crab
        18
    crab  
       2017-02-18 20:11:05 +08:00
    有验证码的,而且还是手势验证码。你没出现是你号没遇到。
    通常没绑定手机,或者异地的号(买来的),就都会有手势。

    sina 手机端这边一直都是明文, pc 才有 RSA 。
    fytriht
        19
    fytriht  
    OP
       2017-02-18 20:25:37 +08:00
    @crab 你说的是手机端是 web 还是客户端? 我测试的是手机端 web 版 ( https://m.weibo.cn) 的登陆接口, 账号绑定了手机非异地的,一直没有遇到过验证码。同一个账号在 pc 端倒是经常要验证码
    billlee
        20
    billlee  
       2017-02-18 20:25:49 +08:00
    @laoyur 理解了。你是指在前端先做一遍摘要,保证服务器根本不会收到口令原文,目的不是为了防止第三方监听,而是网站本身表示自己对用户的口令明文不感兴趣,对吧?
    stabc
        21
    stabc  
       2017-02-18 20:26:14 +08:00
    @laoyur 连最基本的加密知识都不懂,你还是虚心一点吧。
    laoyur
        22
    laoyur  
       2017-02-18 20:27:30 +08:00
    @billlee #20 是的
    laoyur
        23
    laoyur  
       2017-02-18 20:28:25 +08:00
    @stabc #21 ……
    murmur
        24
    murmur  
       2017-02-18 20:55:01 +08:00
    这得花多少时间才能给明白解释清楚,为啥 https 也能在调试器里抓到东西,甚至 flidder 你配了也能抓。。
    fytriht
        25
    fytriht  
    OP
       2017-02-18 21:22:34 +08:00
    @murmur 可能是我没表达明白,我的意思是微博的登陆接口也太好找了,用 dev tools 也能很方便地抓到。有些网站的登陆接口要用抓包工具才抓到。 另外,加密的知识我确实不是很懂
    treo
        26
    treo  
       2017-02-18 21:49:28 +08:00
    都 ssl 了还要加密什么?在客户端加密明文密码都属于自欺欺人,顶多就是糊弄一下产品经理
    https://www.nccgroup.trust/us/about-us/newsroom-and-events/blog/2011/august/javascript-cryptography-considered-harmful/
    bao3
        27
    bao3  
       2017-02-18 23:30:27 +08:00
    不能把密码加个盐吗?
    iptux
        28
    iptux  
       2017-02-19 00:11:15 +08:00 via Android
    既然是移动端就要考虑浏览器未启用 js 的可能,又有 HTTPS ,直接 POST 并没有什么问题
    Shura
        29
    Shura  
       2017-02-19 00:13:07 +08:00 via Android
    中间人攻击不是那么容易的
    acmetal
        30
    acmetal  
       2017-02-19 00:56:30 +08:00
    @laoyur 其实按你说的在客户端加密了再发,就算加密十次,跟没加密有什么区别。。。密码被截获了发往同一个接口照样能登录成功
    vimffs
        31
    vimffs  
       2017-02-19 01:25:40 +08:00
    @acmetal 赞!#30 这个思路解答得好。明文也好,加密文本也好,只要能截获、登录就不是问题了。但是,如果换个进程(不是你打开的那个 chrome ,或用 Wireshark ), @laoyur 你会发现截获 HTTPS 真的不是那么轻而易举。
    exoticknight
        32
    exoticknight  
       2017-02-19 01:37:32 +08:00
    post 是明文,但是传输不是啊……
    imn1
        33
    imn1  
       2017-02-19 01:48:05 +08:00
    看这个帖子后怀疑人生了……
    难道客户端要用 js 加密?
    dallaslu
        34
    dallaslu  
       2017-02-19 01:52:27 +08:00   ❤️ 15
    使用了 HTTPS ,那么被第三方攻击者嗅探到密码的风险,先不用过于费神考虑了, SSL 的中间人攻击稍后再说。值得关心的事情是「明文」提交给网站是否不妥。

    1. 网站若被拖库,会暴露密码明文吗?

    如果网站将密码明文入库,的确如此。

    事实上,网站开发人员普遍有了不存储明文密码的意识。我们可以在安全链接的基础上明文传输密码,在服务端计算出 hash 后,与数据库中存储的 hash 值对比来验证密码是否一致。强制客户使用复杂密码,即使 hash 泄漏,也能对付得了暴力破解。

    如果密码不够复杂,还是有可能被破解。预先准备一个庞大的密码字典,按指定算法获得的 hash ,做成一个映射表,使用 hash 反查即可立刻获得明文。所以有安全意识的开发人员会使用一段足够复杂的随机字符串,做为「盐」与密码明文连接后成一个新字符串,将计算出的 hash 值存储入库;同时盐也是明文存储的。 这样就能规避查表破解了。更严谨的做法是为每一个用户的密码都生成一个独一无二的「盐」。

    除了用盐来得到口味不同的 hash 之外,还可以在「烹饪手法」上做文章,比如不断对 hash 加盐再算 hash 值,重复 N 次。

    2. 传输加盐后的 hash ,会更安全吗?

    比如我们在客户端实现 MD5 或 SHA256 这样的加密算法,如有必要还会重复 N 次;将处理后的内容发送给服务器,服务器拿去存储和验证。这样,网站可以明确的表示对客户的密码明文没有兴趣。有这种态度的网站值得赞赏,但如果仅仅如此的话,还是不够的。

    如果省略了服务器方面的计算,攻击者只要从数据库中拿到客户端计算出的 sha256(password+salt) 的结果,原封不动的传给服务器,仍然可以模拟登录。所以无论客户端提交的是原始密码,还是加工后的密码,服务器都应该继续加盐「烹饪」后再使用。

    3. 客户端和服务端都对密码进行加工,还有泄漏原始密码的风险吗?

    还是有的。毕竟入侵网站拿到服务器数据是困难的,而广撒渔网入侵普通用户的电脑可能会容易一些。木马程序记录用户的键盘输入,原始密码仍然会被窃取。常见而有效的办法是,网站记录用户的登录地点、时间、频率等特征,一旦发现异常登录即刻限制账户的操作,可以很大程度上避免用户的损失。

    这一切的源头在于用户输入了原始密码。如果网站事先与用户协商,使用随机的一次性密码,就规避了这种风险。比如短信密码, Google 二次验证,以及其他的内置密钥的临时口令生成设备。即便网站不支持这些功能,也可以使用密码管理器来为不同的网站生成不同的密码,避免战线全面沦陷。

    还有一种可能,攻击者使用你的帐号和密码字典,加工后不断向服务器尝试登录,或者提交随机密码来碰运气;不过只要网站采取了限制密码尝试次数的措施,就轻松搞定了。如果攻击者在极有限的次数内猜到了原文密码,或者另外一个内容不同、但「烹饪」后的 hash 完全一致的密码,你一定要想办法联系到他,让他写一个彩票号码给你。

    4. 使用随机密码就万无一失了吗?

    尽管攻击者并不知道你的原始密码,但是他们有可能远程控制你的访问终端。比如使用后门程序操作你的浏览器发送一些敏感的操作请求,入侵你的手机来读取短信内容,甚至直接偷走你的动态令牌设备……

    5. 我已经足够小心地管理自己的设备和密码,可以高枕无忧了吗?

    少年,不得不提一下中间人攻击了。攻击者污染你的 DNS ,把你的请求劫持到了他们的服务器上,伪装成目标网站。尽管浏览器提示了网站的证书可能有问题,你点击了忽略,继续操作。你要申请短信密码了是么?攻击者会帮你向真正的网站请求短信密码,然后你把短信密码发到了假网站,攻击者就能成功登录了。所以,你需要换一个足够智能和安全的浏览器,并重视浏览器的安全提示。

    6. 我终于明白浏览器证书提示的重要性了,还会有其他问题吗?

    更厉害的中间人攻击,可能浏览器都发觉不了。比如攻击者设法搞到了一个有效的证书。当然,如果你访问过真的网站,浏览器会察觉到这两个网站的证书稍有不同( HSTS )。最倒霉的情况是第一次访问,你和浏览器一起掉进了坑里;很快这将成为一个大新闻的,网站丢了证书声明作废,或者某某证书机构闹了乌龙将证书发给了坏人。你有机会在事后意识自己受到了欺骗。你应该提前关注新闻,学习自己管理设备上的证书,随时告诉设备某某机构是否值得信任。

    7. 我搞懂了证书和证书机构,可以无所畏惧了吗?

    你访问了网站首页,没有发现问题;在表单上填上了随机密码,页面跳转到加密页面,证书也没有问题,只不过页面提示说密码不正确。注意!你有可能被猪队友坑了。在启用加密链接之前,你的密码在网络上裸奔了一次!你的程序员队友犯了一个错误,将表单提交到了非加密地址,尽管后来跳转到安全链接上了。要是网站使用了 HSTS ,就不会发生这样的情况了。 HSTS 需要访问一次网站才能生效,如果网站加入到了浏览器的内置 HSTS 名单中就最好不过了。

    8. 我很靠谱,网站也很靠谱,我的原始密码已经像在核避难场所里一样不怕攻击了吗?

    理论上接近了,除非网站使用证书私钥不够长,被越来越厉害的计算机破解,像 HTTP 一样容易监听。你终于安心了,直到有一天,你小手一滑在输入网址的时候敲错了一个字母,或者点击了一个链接,进入了一个域名相似的假网站……

    9. 我已练成了金刚指和火眼金睛,试问谁敢与我争峰?

    手机来了新消息,老板说把情报系统的密码发给我……你马上回复了短信密码和二次验证码,得,社会工程学,还是防不胜防!

    ----
    以上内容随手一写,有错误请各位指正。
    davidyin
        35
    davidyin  
       2017-02-19 05:02:43 +08:00 via Android
    @dallaslu 够全面
    laoyur
        36
    laoyur  
       2017-02-19 08:05:01 +08:00 via iPhone
    @acmetal
    @vimffs
    你们还是没明白我关注的点
    怪我一开始把原始口令传输说成了明文密码传输哦,我的错。
    我从来没说不要 https ,相反, https 是必须的,用了 https 后没必要再吹毛求疵那么怕中间人,这个也是显然的。
    我纠结的是,现在的大部分方案都是自恃有了 https 后,就直接原始口令传输给服务端,这真的好么?各种社工层出不穷,如能保护原始口令不沦陷,这样的工作能做为何不去做?如果在源头上就能给用户的原始口令做保护,也就是前端先把用户原始口令加盐后摘要,再传给服务端,它再爱咋处理咋处理。

    @dallaslu 写得很好,赞一个
    weakiwi
        37
    weakiwi  
       2017-02-19 08:11:41 +08:00 via Android
    @shiji 可以看看 qq 安全的登录页面,那个是有加密的
    loading
        38
    loading  
       2017-02-19 08:12:21 +08:00 via Android
    只要服务器处理好,就能解决你的顾虑,所以就没必要在前端做了。

    那些出事的库都是要么明文,要么只是 md5 一次。
    没加盐,没用慢算法等。

    楼主还是多了解一下吧。
    old9
        39
    old9  
       2017-02-19 08:39:07 +08:00 via Android
    因为前端处理是毫无意义的自欺欺人。
    340244120
        40
    340244120  
       2017-02-19 09:09:33 +08:00 via Android
    主要还是怕麻烦和节省开销吧。因为前段加密的话,点登陆的时候得先去数据库拿到盐,客户端收到后才能加密,然后开始常规登陆。
    340244120
        41
    340244120  
       2017-02-19 09:27:57 +08:00 via Android
    最大的可能还是早期的设计没考虑过前端加密。后面再补的话,老用户就登不上了。 [当然原理上是可以实现的,但太麻烦了,登陆的时候判断下是不是老用户,是的话前端就不加密,转到后台,用前端算法加密一次,再用后端算法加密一次,移除老用户标记。
    340244120
        42
    340244120  
       2017-02-19 09:31:47 +08:00 via Android
    漏了一句话 老用户完成两次加密后,数据库更新密码字段。
    zhenjiachen
        43
    zhenjiachen  
       2017-02-19 10:24:43 +08:00
    手机版微博验证码很变态好吧!
    Tink
        44
    Tink  
       2017-02-19 10:47:11 +08:00 via iPhone
    讨论的都不是同一个问题
    fytriht
        45
    fytriht  
    OP
       2017-02-19 11:03:20 +08:00
    @dallaslu 学习了!
    Jackhuang
        46
    Jackhuang  
       2017-02-19 11:10:35 +08:00 via iPhone
    前端加密我觉得真的没有必要,后端加密够了,社工的问题是脱裤明文问题。
    Kilerd
        47
    Kilerd  
       2017-02-19 11:11:16 +08:00
    前段加密就是自欺欺人。 js 都是暴露出来的。 加密跟不加密的区别在哪里??


    年轻人,就该多读书。不要总是想搞什么大新闻。
    old9
        48
    old9  
       2017-02-19 11:21:37 +08:00 via Android
    如果前端加密有用,还要 HTTPS 干什么。
    340244120
        49
    340244120  
       2017-02-19 11:47:22 +08:00 via Android
    楼上你们大部分人都没明白楼主的意思。楼主的意思是 前端加密,防止原始密码被截获。因为原始密码一旦被获得,黑客就可以用相同的用户名密码去其他网站 /应用撞库了
    quxiangxuanqxx
        50
    quxiangxuanqxx  
       2017-02-19 12:03:27 +08:00   ❤️ 1
    @340244120

    @laoyur

    这样做没有任何意义,你看的明文和原始口令是在你自己的电脑上,应用层在你自己的电脑上,但是数据在网络传输中,已经 SSL 加密了,黑客截获是拿不到原始口令的

    如果黑客已经黑掉了你的电脑,为什么还要去抓包,直接键盘钩子勾出来不就行了

    如果说黑客只是拿到了部分权限,只能抓包?能抓包已经可以下钩子了

    综上所诉,没有意义,徒增笑而
    crs0910
        51
    crs0910  
       2017-02-19 14:55:56 +08:00
    前端加密对网站当然没有什么意义,但是对用户是有意义的啊,比如加个 md5 就可以保证网站方对用户的原密码是不能掌握的。也可能是我读书少。
    x86
        52
    x86  
       2017-02-19 14:58:13 +08:00
    前端加密有什么用...
    mornlight
        53
    mornlight  
       2017-02-19 15:54:55 +08:00   ❤️ 1
    前端对密码做处理可以增加中间人攻击时获取明文密码的难度,只能说意义不大,也不是完全没有意义。淘宝的登录 POST 请求就是没有明文密码的。
    不管谁知道的多谁知道的少,技术问题可以大家一起讨论,讨论的过程会沉淀下来给后面的人看。遇到自己不屑的观点就用「多读书」这样的话来嘲讽,是智力上的自我矮化。
    laoyur
        54
    laoyur  
       2017-02-19 17:53:55 +08:00
    @mornlight #53 是诶,虽然我说“明文密码”用语不精准,但从我再增加的回复中也不难理解我在说的到底是啥。
    退一万步说即使我话题跑偏,但我说的问题真的一点讨论意义都没有吗?不见得吧。
    我承认自己不是牛人,但好歹我认认真真在讨论问题,人啥都不说直接来一句“年轻人多读书”、“最基础的加密都不懂,要谦虚”……我一个话题跑偏不要紧,但所谓的国内第一的个人技术社区的价值也要往这个方面跑偏吗?
    laoyur
        55
    laoyur  
       2017-02-19 17:56:05 +08:00
    @x86 #52 是前端对原始口令 hash
    imn1
        56
    imn1  
       2017-02-19 18:18:05 +08:00
    @laoyur
    如果你把“明文”“加密”这些说法,换成“唯一化处理”(注意不仅是 hash ),就是把即将发送出去的密码串转换成跟其他网站不相容的另一个串,或者我能理解,两个意义——
    1.唯一化处理后让客户端盗得的不再是原始密码,不能用于其他站点
    2.即使原始密码和其他站点相同,通过唯一化处理,变成不能用其他站点密码(也就是原始密码)碰撞本站密码
    gy911201
        57
    gy911201  
       2017-02-19 18:24:57 +08:00
    @laoyur 我明白你的意思,我是这样想的,如果是客户端被黑客入侵,那么可以直接用键盘钩子拿到原始密码,前端加密没有起到作用,如果是服务端被黑客入侵,那么如果程序没有安全问题(明文入库,日志包含敏感信息)的话,那么黑客要拿到 https 里的明文密码也需要很高的权限,有此权限的时候一般都可以直接对网站进行挂码,那么这个前端加密依然不起作用……
    当然了,我的论据的前提是黑客要拿到 https 里的明文密码需要的权限至少与可以对网站挂马需要的权限一致,不知道这个前提有没有问题……
    laoyur
        58
    laoyur  
       2017-02-19 18:25:55 +08:00
    @imn1 #56 我在楼上的回复中承认过了,我“明文密码”的说法是不精准,我之所以说明文,是自己默认了在 https 语境下的明文(原文),给他人理解带来了偏差,抱歉。但“加密”的锅我不背,我所提到的加密字眼,只是引述楼主以及楼上各位的话题,我始终要表达的是对原始密码的摘要,或者你所说的“唯一化处理”,而不是可逆的“加密”。
    4641585
        59
    4641585  
       2017-02-19 19:56:34 +08:00   ❤️ 1
    我来总结一下

    1 、可以用 chrome dev 因为是同一个进程,与启用了 HTTPS 无关。

    2 、有一种观点是如果已经启用了 HTTPS ,前端处理相对没有意义。对于 HTTP 来说,前端处理是有意义的,可参阅 https://github.com/EtherDream/WebScrypt 。对于使用了可靠证书的,启用 HTTPS 的网站来说,前端处理是否有意义,这个问题约等于 HTTPS 是否足够完美。认为其完美的人以数学、密码学为主要论据,认为其可能不够完美的人会以历史上曾被猿们认为可靠的而后来被证明不够可靠的事例为论据。讨论这个问题,这不是第一个帖子也不会是最后一个。

    3 、无论怎样,数据库直接存放明文密码是不可取的。
    340244120
        60
    340244120  
       2017-02-19 23:29:25 +08:00 via Android
    @gy911201 安全性要求很高的,前端处理还是有必要,键盘钩子的问题可以用虚拟键盘等方式来应对。然后假设客户端及传输过程中安全性为 100,但不排除后端程序员中有内鬼的可能,把接收到的口令单独储存下来,或者用户担心自己的密码隐私,不愿意让自己的密码被后端直接获取。这时候前端处理的必要性就体现出来了。 总之,前端处理可以说没有必要,但不能说毫无意义。
    gy911201
        61
    gy911201  
       2017-02-19 23:49:21 +08:00
    @340244120 其实对于担心密码隐私的用户来讲,使用类似 1password 或者 浏览器自带的密码工具生成密码做到一账户一密码应该是一个更好的选择吧……
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1036 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 22:05 · PVG 06:05 · LAX 14:05 · JFK 17:05
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.