对于使用 Google 全家桶的公司,Google 文档类的信息泄露也时常发生。出现这种情况主要的原因是文档的权限设置问题,用户可能将文档配置为 anyoneCanFind, anyoneWithLink, domainCanFind, domainWithLink,这四种权限都属于比较公开的权限。后两个属于在域内可以查看到文档,一般来说也是不提倡如此设置,尤其是文档中包含敏感信息的。
Auth # 如果要使用 Google Drive 的 API,毫无疑问,Google Workspace 的 Auth 则是第一步。对于 Auth,一般可以通过 OAuth 或者 service account 来进行实现,但是 service account 有一个问题是,默认这个 service acount 并没有赋予这个 servive account 这个域内所有资源的访问权限。必须要将这个文档分享给 service account,它才可以访问。这将会影响到对于 domainCanFind 以及 domainWithLink 的文档的搜索。解决办法是需要 delegate domain-wide authority,相当于是对于这个 service account 进行额外的授权,详细的介绍可以参考这个文档。当然,这个授权需要管理员账号来进行,如果申请比较麻烦的话,还可以通过使用 OAuth 的方式来进行认证,这也是 Google Drive API 文档指引中介绍使用的方式。
通过 OAuth 来使用 Drive API 也需要三个步骤:
启用 API 配置 OAuth 应用 生成 Credentials 详细介绍可以参考谷歌的文档介绍,基本上每一步都有详细的介绍。建议可以按照文档的方式来进行操作,OAuth 生成方式会用到一个 credentials.json 文件。如果对 OAuth 流程比较了解的话,应该知道流程中会有一个授权的流程。Go 的官方文档已经提供了一个授权的 demo,通过运行代码可以获取 autorization code,通过 aurhorization code 可以生成 token.json。对于内部应用,生成的 token.json 包含 refresh_token 的话,这个 token 是不会过期的。
鄙人不才,只能做个 web 狗了。那就好好学习 web 吧。拼命地刷 writeup 就好了。上题目,Phone number。提示只有 phone number is a good thing.
打开链接可以看到是一个登陆页面,查看源代码,没有什么东西。不过,这个页面还有个注册页面,注册页面有用户名密码以及 phone,查看其源代码也没有什么异常情况。这道题初步看来应该是一道 sql 注入题了,那么注入点在哪呢?当然是 phone 了(来自于上帝视角)。如果正经地来说还是因为题目的提示啦。
注入点的确就是 phone,不过是要使用 16进制字符。为什么呢?上帝告诉我的,我也不知道。好吧,接下来就是 sql 注入四步曲了,爆数据库名,爆表名,爆字段,最后查数据,拿 flag。是不是很开心!
正常用户 # 首先,我们首先注册一个正常用户,注册之后登录,可以看到页面。这里面有一个 check 的按钮,点击一下,可以看到页面提示 There only 369 people use the same phone as you。查看源代码,可以看到注释里面有一句话:听说admin的电话藏着大秘密哦,这也是一个小提示。这里面的369应该就是通过 sql 语句从数据库拿到的,语句可能就是类似于 select count(*) from user where phonenum = 12 这种的,从而查出和你电话号码一样的用户数了,那么我可以信誓旦旦地告诉你,这就是一个注入点啦!
数据库名 # 因为 phone 可能使用的是数字,所以这是一个数字型的注入。那么,我买可以随便注册一个用户名了,首先获取数据库名的语句是 1 and 1 = 2 union select database(),把这个语句转化为16进制字符。将这个16进制字符串作为 phone 来进行注册,这里注意的一个点就是,前台对于 phone 的长度做了限制, maxlength="11",打开开发者工具设置大一点就可以了。注册成功之后,我么就可以看到:
OutOfMemoryError 异常应该可以算得上是一个非常棘手的问题。JAVA 的程序员不用像苦逼的 C 语言程序员手动地管理内存,JVM 帮助他们分配内存,释放内存。但是当遇到内存相关的问题,就比如 OutOfMemoryError,如何去排查并且解决就变成一个非常令人头疼的问题。在 JAVA 中,所有的对象都存储在堆中,通常如果 JVM 无法再分配新的内存,内存耗尽,并且垃圾回收器无法及时回收内存,就会抛出 OutOfMemoryError。
我之前在做一个工具,需要读取大量的文件,比如 word 或者 excel,而我给机器分配的最大的内存只有 2G。所以,很多人的机器往往会因为 OutOfMemoryError 异常导致程序中止运行。后来我发现一个现象,OutOfMemoryError 可以通过 Error 或者 Throwable 去捕获,OutOfMemoryError 类继承关系如下:
java.lang.Object java.lang.Throwable java.lang.Error java.lang.VirtualMachineError java.lang.OutOfMemoryError 因此 OutOfMemoryError 是一个 Error 而不是一个 Exception,并且据我观察,OutOfMemoryError 无法被 throw 到上一层函数中。
private void OutOfMemoryErrorTest() { try { // do something might lead to OutOfMemoryError error } catch (Error e) { e.printStackTrace(); } } 发生 OutOfMemoryError 的原因 # 越早找出 OutOfMemoryError 的原因就越利于我们解决问题。到底是因为 JAVA 的堆满了还是因为原生堆就满了呢?为了找到其原因,我们可以通过异常的细节信息来获得提示。
写在前面 # Github star 往往非常简单,点击一个按钮,就 star 了。但是你还去看它么,这就未必了。因此很多库长年累月的堆积在你的 star list 里面无人问津。因此,会有这样一个具有一个非常中二的名字的计划。对于 star 仓库,从后往前,一个个理解消化,不要让它无意义地堆积。
操作步骤:
fork it finish it 仓库信息 # 仓库名称:Front-end-tutorial 主要内容:这是一个博客,里面主要是前端开发的内容,内容设计比较广泛,包括 HTML, CSS, JS 以及流行的框架,以及前端开发的其他内容。 消灭计划:内容较多,打算主要消化一些感兴趣的内容,主要应该集中于原生的东西或者一些性能方面的知识。 作战内容 # JavaScript # 深拷贝 # 深拷贝可以说是一个老生重谈的问题,几乎每一个前端面试都可能会问这样的问题。Js 中的对象都是引用,所以浅拷贝时,修改拷贝后的对象会影响原对象。原仓库中其实讲的并不是很深入,我反倒是觉得评论里面的一篇文章深入剖析 JavaScript 的深复制讲得更好。
有很多第三方库实现了对于对象的深拷贝。
jQuery: $.extend(true, {}, sourceObject) loadsh: _.clone(sourceObject, true) 或者 _.cloneDeep(sourceObject) 另外有一个神奇的方法就是借助于 JSON 的 parse 和 stringify 方法,当时我才看到这个方法的时候惊为天人,这个方法还可以用来判断两个对象是否相等。当然,这个方法还是有一些限制,因为正确处理的对象只能是使用 json 可以表示的数据结构,对于函数可能就无能为力了。原文作者实现了一个深拷贝的方法,不过考虑了很多情况,在这里我们就实现一个简单版的深拷贝把。
function deepCopy(obj) { const result = {}; for (const key in obj) { if (obj.hasOwnProperty(key)) { if (Object.prototype.toString.call(obj[key]).indexOf('Array') !== -1 || Object.prototype.toString.call(obj[key]).indexOf('Object') !== -1) { result[key] = deepCopy(obj[key]); } else { result[key] = obj[key]; } } } return result; } call 和 apply # call 和 apply 应该是两个非常类似的方法,我的理解它们都是改变函数运行的作用域。不同之处就是参数不同,apply 接收两个参数,一个是函数运行的作用域,另外一个是参数数组,而 call 的第一个参数相同,后面传递的参数必须列举出来。
POI是 Apache 旗下一款读写微软家文档声名显赫的类库。应该很多人在做报表的导出,或者创建 word 文档以及读取之类的都是用过 POI。POI 也的确对于这些操作带来很大的便利性。我最近做的一个工具就是读取计算机中的 word 以及 excel 文件。下面我就两方面讲解以下遇到的一些坑:
word 篇 # 对于 word 文件,我需要的就是提取文件中正文的文字。所以可以创建一个方法来读取 doc 或者 docx 文件:
private static String readDoc(String filePath, InputStream is) { String text= ""; try { if (filePath.endsWith("doc")) { WordExtractor ex = new WordExtractor(is); text = ex.getText(); ex.close(); is.close(); } else if(filePath.endsWith("docx")) { XWPFDocument doc = new XWPFDocument(is); XWPFWordExtractor extractor = new XWPFWordExtractor(doc); text = extractor.getText(); extractor.close(); is.close(); } } catch (Exception e) { logger.error(filePath, e); } finally { if (is != null) { is.close(); } } return text; } 理论上来说,这段代码应该对于读取大多数 doc 或者 docx 文件都是有效的。但是!!!!我发现了一个奇怪的问题,就是我的代码在读取某些 doc 文件的时候,经常会给出这样的一个异常:
因为爬虫项目需要模拟登陆,可是有一个网站的登录需要输入验证码。其实这种登录有2种解决方案,一种是利用cookie,一种是识别图片。前者需要人工登录一次,而且有时效限制,故不太现实。后者可以,但是难点是如何识别出验证码。 这里面就要介绍一个神器了,tesseract-ocr这个项目是一个开源项目,可以用于图像识别。不过这个项目现在托管于google,所以不好下载,你可以搜一下,选择在国内下载。http://download.csdn.net/detail/neal1991/9502931 一开始我觉得我的验证码还挺好识别的,因为都是数字,如下图: 但是我发觉直接来识别还是来识别不了的,最好还是先要对图片进行一些预处理。说到图片的预处理就要说到另外一个软件了,就是imagemagick,这个是一个开源的图片处理项目,你可以去http://www.imagemagick.org/script/binary-releases.php根据你自己的系统进行相应得下载。这个软件还有相应的开发api,你可以自行的根据需要去下载。记住,这个软件安装后,配置环境变量后,需要重新启动的,一开始我还以为是什么问题呢。后来发现重新启动之后,就生效了,可以直接在cmd中使用。在这我就不说什么别的了。 首先是对图片进行预处理:
convert 1.jpg -colorspace gray -normalize -threshold 50% 1.tif 这里主要是先做一个灰度图转化,然后进行归一化处理,最后设立一个阈值,进行二值化,这样最后的结果还是比较清晰的,如下图: 然后再用tesseract进行识别:
tesseract 1.tif result 是不是很简单? 在github上面写了一个nodejs的程序可以直接执行,不过需要安装nodejs,链接如下: https://github.com/neal1991/code-recognition
今天打包一个安装程序,总是出现报错,internal build error -6213,然后搜遍都没有找到什么解决方案。看到一个帖子,说是因为installsheild里面的build的时候自动扫描.NET依赖库造成的原因,要把这个自动扫描功能给关掉,但是他说的在什么地方关说的不是很清楚,所以我一直找不到。 http://1978l.blog.163.com/blog/static/4494441620098704049756/原文帖子如下 后来找了半天,终于找到地方了。 如图1,图2所示,把components里面所有.NET scan at Build设置为none,这个可能是这个软件的bug把,我使用的是2011版本,免费的版本。 真心的,我实验室解决问题的能手,实验室这些妹子如果没有我,我都不知道她们该怎么活下去。
作为一个CS的研究生,发篇文章是你毕业的必要条件。现如今,学校对于文章的要求也越来越高,一般来说,还是国外的期刊或者会议更加受到认可,这样对于毕业也有好处。因此,以我自己的感受来说,论文的写作以及表达方式,合理地呈现你的实验结果,清楚的逻辑解释,显得尤为重要。让人看得懂的论文往往比一个拥有的好的想法的论文更能得到别人的认可,当然这也并不是推崇只是为了专注于论文的写作,毕竟想法才是一篇论文的灵魂。然而事实如此,做好论文的写作的重要性实在很大。 作为一个研究生,很显然并没有很多的论文的写作经验。所以,我们一般的做法就是模仿别人的论文写作。我们需要阅读大量别人的论文,这样其实也是对自己的语感的培养。当然,这里推荐你还是多读读外国人写的论文,因为他们的论文写作表达方式相对来说更为的地道。我觉得论文写作的词汇使用很讲究的,同一种意思可以有很多种表达方式。就比如说你的算法很好,你可以说:outperforms than other algorithm, has advantages over other algorithm, has impressive performances, has remarkable performances等等。我前段时间,看到有个单词就很好,circumvent,这个单词的意思是绕开。其实,我们算法的改进,很多时候并不是对这个问题的直接改进,而是绕开这个问题,从而避免这个问题,所以我就觉得这个单词用的很精妙。 其实现在的论文写作也和古代的八股文一样,有一样的套路。其实对于一个给定方向的论文,他们的套路其实基本都是一致的。老实说,对于所有的论文我们基本都有一个一致的框架结构。首先,一般在abstract里面,我们会简要的说一下我们的思想,这里要言简意赅,并且能够最大化吸引别人,突出你想发的优点。然后,在introduction里面,就是介绍相关背景知识的时候,像我们专业,一般都是介绍一些相关的算法,或者你提出的算法的基础,这些都是我们提出的算法基础。接着才是提出我们自己的算法的正确的时机。在正文里面,首先就是介绍你算法或者思想的基础,然后就是你的算法和思想了。记住,这个才是你论文的核心部分。你的论文大部分应该都是讲你自己的想法而不是别人的想法,否则也就是本末倒置了。计算机的论文,很多都是需要实验结果来佐证的。没有实验结果,你的所有想法都不具有说服力。同时,实验结果需要相应的详细的分析过程,对于实验结果你要分析的多一点,虽然觉得有时候觉得自己说的是废话,但也尽量多说一点,多换点角度表达。一般你可以从性能上去说,说我们算法的性能好;如果算法的性能差不多,那就可以从运行时间去说,可以说我们算法的运行速度快。当然,我觉得写别的方向的论文应该也是差不多的,从多个角度去表现你算法和想法的优点,这一点很有必要。另外一点,多用图和表格来表达你的实验结果,图优于表格,表格优于文字,文字最次。优秀的表达方式往往更容易吸引别人的目光,所以多学一下怎么画图。看一些TOP期刊的文章,他们是怎么画图的,这样装逼也会好一点。 其他的我也不知道还有什么好说的把。自己真心的体会,是中国人真的灌了好多水,尤其是我自己的这个方向。有时候自己也觉得很愤慨,但想想自己,何曾不是也在灌水。可能还是自己也是推动这个方向恶性循环的一份子,还是希望以后这个方向有更良性的发展吧,当然,与我无关了。
在网上看到一个全栈开发教学的例子,他是一个使用Django来作为服务器后端结合前端来做的东西,是一个全栈教学的案例。虽然作者是中国人,但是他做的东西都是用英文做出来的,http://webcoursify.github.io。在这里,我们就把他的学习教程一步步翻译出来,也当是自己学习。 开篇部分zhuyao1讲一下Django的基本概念,这个部分主要分为三个小结:
一. 客户端服务器模型和MVC设计模式 首先用一张图来简单的描述一下: 基本上所有的网络系统都符合这个模型。在网络系统中,服务器通过标准协议响应来自各种客户端发来的请求。客户端之间的请求被认为是相互独立的。这就意味着服务器如果正在响应某个客户端的请求时,他就不需要处理来自其他客户端的请求或者相同客户端的其他请求。 MVC 架构模式 这种架构模式被广泛应用于各种软件开发中,而不仅仅只是网络系统的开发。下面简单介绍一下MVC:
Model 这个组件时系统的核心问题,比如数据结构,数据存储遗迹核心逻辑等等。它经常注重的是整个系统的基础,和其他两个组件没有特别多的交互。 View 这个组件注重向用户展示信息以及接受用户的交互信息。这个组件在网络系统中往往就是前端层次。 Controller 这个组件连接前两个组件。这个组件中的函数往往是被事件所触发得。 当然这里面的名称可能和在Django里面的叫法不太一样,但具体内容应该是差不多的。
IndexDB利用数据键(key)访问,通过索引功能搜索数据,适用于大量的结构化数据,如日历,通讯簿或者记事本。
以key/value成对保存数据 IndexDB和WebStorage都是以数据键值的方式来保存数据,只要创建索引,就可以进行数据搜索和排序。 交易数据库模型 IndexDB进行数据库操作之前要先进行交易。所谓交易,就是将数据库所做的访问操作(比如增删改查)包装成一个任务来执行,这个任务可以包含多个步骤,只有所有的步骤执行成功,交易才算成功;只要有一个步骤失败,整个交易就会取消所做的更改都会被恢复。 IndexDB大部分的异步API IndexDB数据库操作并不会立即执行,而是先创建数据库操作要求,然后定义事件处理函数来响应这些要求是成功还是失败。 通过监听DOM事件取得执行结果 数据操作完成时,通过监听DOM事件来取得执行结果,DOM事件的type属性会返回成功或者失败。 每个读写操作都是请求 IndexDB随时随地都在使用请求 面向对象 IndexDB是面向对象数据库,不使用sql语法,必须以面向对象的方式来获取数据。 NOSQL的数据库系统 IndexDB的查询语言并非sql,而是查询索引获取指针,然后用指针访问查询结果。