非墨

非墨 查看完整档案

南京编辑  |  填写毕业院校北京智汇邦信息技术有限公司  |  技术总监 编辑 github.com/ihongs/ 编辑
编辑

会出错的总会出错。知乎:https://www.zhihu.com/people/...

个人动态

非墨 赞了回答 · 11月20日

解决Java 泛型能 extends 多个吗?语法对不对?

你这是咋看的……

只有一个是类型(class),剩下的都是接口(interface)好吧?

哪来的 extends 多个类型?


【补充】答完才看到题主自己发现了……

关注 1 回答 2

非墨 回答了问题 · 11月18日

解决Java 泛型能 extends 多个吗?语法对不对?

哦,没看仔细,这个 <T extends A & B & C> 语法里,第一个是类,& 后面的只能是接口。我 SB 了,Sorry!

关注 1 回答 2

非墨 提出了问题 · 11月18日

解决Java 泛型能 extends 多个吗?语法对不对?

我有个类希望泛型 extends 两个或多个类,百度查到 <T extends TestA & TestB> 这种 & 的用法,如:

https://blog.csdn.net/qq_4368...

https://blog.csdn.net/caolaos...

照这么写了 IDE 提示错误,把 jdk 版本从 1.8 改成 11 依然提示错误。直接编译还是提示语法错误,jdk 版本 11。

然后我想是不是 TestA 和 TestB 必须有个共同的父类,试了如下代码:

    public static class TestX {
        
    }
    
    public static class TestA extends TestX {
        
    }
    
    public static class TestB extends TestX {
        
    }
    
    public static class Test<T extends TestA & TestB> {
        
    }

依然编译错误。采用 Maven 编译,只给了个错误链接 http://cwiki.apache.org/confl... 没能发现有用的信息。

想请教一下,到底有没有这个语法?如果有,在哪个版本加入的,能提供一下官方的文档就更好了。

关注 1 回答 2

非墨 回答了问题 · 8月17日

Python与Java的区别与优劣?

学编程语言,学的是库,现代的编程工作,已没有可能完全自己从0写所有代码了。比较两个语言的语法是没多少实际意义的,得比较流行的库:

1、文件:Python 是类似 UNIX 惯例的 open 函数,与 C,Perl,PHP 区别都不大;Java IO 大家谈很多了,面向对象,套各种装饰器。
2、配置:Python 惯用 ini 之类,最多两层结构;Java 惯用 properties,类似 ini 但只有一层,而且有编码限制,含中文直接用记事本打开就懵逼了,另外也惯用 xml 及相关扩展,无限层级。但是,这只是说惯用什么,实际上呢,xml 相关组件都是一等公民默认入驻。
3、搜索引擎:python 拿来做爬虫有太多教程了,随便查,你不带 python 字样就搜爬虫,都能搜一堆 python 相关的文章出来;java 有 lucene 及 lucene 的衍生品,是做搜索(检索)引擎的绝配。这二者正好互补,倒不是说 java 做不了爬虫, python 做不要检索,都可以,还都有对应成熟的库。因 python 不必专门编译更利于修改,对总要试试看的爬虫来说,更方便。
4、数据分析:几乎所有流行的书籍都是用 python 来作为示例,numpy、scipy、pandas、scikit……一大堆;Java 呢,呃,也挺多,但我一下子记不起来(呵呵)。总之,python 可能依然因为他即写即用的特点占了优势,毕竟搞数据分析就跟炼金术一样,你得不停地把各种八竿子打不着的玩意凑一起熬一下试试。
……

还有很多,才疏学浅,就不继续扯淡了。

关注 3 回答 2

非墨 赞了回答 · 8月17日

解决js设置cookie取不到问题?

你不会是双击打开html文件把,file://协议写不了cookie,得开个本地服务器

关注 2 回答 1

非墨 回答了问题 · 8月6日

一般你们是怎么防御自己的服务器的?

阿里云购买安全中心企业版,你要是钱多还可以买云防火墙、Web 防火墙等。

非阿里云或并不想为安全额外花钱,首先及时更新自己的系统和应用;如果是 Web 方面的,尝试用 Docker 并采用 --read-only 模式启动容器,上传和临时目录用 --volume 指定或映射,Nginx 对上传目录设为不转发直接输出静态文件(如果对上传文件没有自己额外的过滤层),用 iptabels 限制入方向只有 22、80、443 等你必需的端口。

这样的话,即使您的 web 程序有问题,也改不了程序,而万一通过上传目录上传了 php,jsp,asp 等可被 web 服务执行的文件,也没法执行。但是,还要小心哦,虽然不能在你服务器执行 webshell,但还可以上传一堆不良内容的图片、音频、视频、网页、PDF 等,然后他用其他肉鸡弄个站,资源都链到你站上。不谈占你带宽,按现行法规,你也说不清。

以上措施虽然保障 web 系统的程序/文件安全,如果您用到了数据库、读写系统文件、执行外部命令等,在防注入方面也要多加关注,阿里云有这方面的安全服务,防火墙、云 DNS 等都可以防住大部分注入扫描;关键还是自己的程序要避免漏洞 —— 打铁还需自身硬。

看你的标签上还有个 DDoS,各类安全 DNS 基本都能防住,比如上面提到的阿里云的云 DNS,还有百度云加速等,这些产品/服务可以单独用,免费或花一点点钱,也并不一定要购买他们的云服务器服务。不过,如果对方是针对性的,找到了你的真实 IP,依然可以绕过那些 DNS 对你发起攻击哦。

关注 2 回答 1

非墨 回答了问题 · 8月6日

java 做的aes解密想用php 的openssl_encrypt 函数加密 老是不成功 请大家给个思路

问题也许在于你用的 base64 编码,byte[] 转字符串或字符串转 byte[] 时。如果这样,PHP 也要同等用 base64 endcode/decode。PHP 方面注意 OPENSSL_ZERO_PADDING/OPENSSL_RAW_DATA 模式。

关注 2 回答 1

非墨 回答了问题 · 8月5日

MySQL字段排序,数据混乱。

CONCAT 之后就是字串了,不再是数字。

如 CONCAT(1,10) 是 110,而 CONCAT(10,1) 是 101,显然顺序是 101,110;另外,CONCAT(1,10) 是 110,CONCAT(1,2) 是 12,都是字符串,排序就是 110,12,除非你再用 CAST 转回数字。

因此还是用 ORDER BY a, b 这种更能明确先按哪个排再按哪个排。


当然,您就是想用 CONCAT 后排序,那最好给数字左边补 0,如 CONCAT(LPAD(order_num,10,0), LPAD(id,10,0))

关注 3 回答 2

非墨 发布了文章 · 7月31日

前端 SPA 模式下的 SEO 静态化方法

当使用 Vue,React 等开发前端页面时,如果采用前端渲染模式,则对搜索引擎不太友好。可以利用 chrome 将渲染好的页面内容输出给搜索引擎,以此达到静态化页面的目的。将其完整封装到 Docker,更便于部署。

以下为 Dockerfile 及服务程序。

Dockerfile

FROM node:10

EXPOSE  3000

VOLUME  /var/www
WORKDIR /var/www

ADD package.js   /var/www
ADD package.json /var/www

ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=1

RUN apt-get update && apt-get install -y wget gnupg ca-certificates
RUN wget -q -O - "https://dl-ssl.google.com/linux/linux_signing_key.pub" | apt-key add -
RUN echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list
RUN apt-get update && apt-get install -y google-chrome-stable
RUN cd /var/www && npm install

CMD ["npm", "start"]

package.js

const puppeteer = require('puppeteer');
const path = require('path');
const koa = require('koa');
const app = new koa();
const ref = "http://www.xxx.com"; // 实际网站网址

let browser;

app.use(async ctx=>{
  if(!browser){
    browser = await puppeteer.launch({
      args: ['--no-sandbox', '--disable-setuid-sandbox'],
      ignoreHTTPSErrors: true, // 忽略 https 错误
      headless: true, // 不显示浏览器
      devtools: false // 不打开控制台
    });
  }

  const page = await browser.newPage();
  await page.goto(ref + ctx.request.url, {
    waitUntil: ['load', 'networkidle0'] // 加载完成, 无新请求, 则页面渲染完毕
  });
  const html = await page.content();
  page.close();

  ctx.response.body = html;
})

app.listen(3000);

package.json

{
  "name": "spa-seo",
  "author": "Hongs",
  "license": "MIT",
  "version": "1.0.0",
  "keywords": ["SPA","SEO"],
  "description": "SPA SEO",
  "main": "package.js",
  "scripts": {
    "start": "node package.js"
  },
  "dependencies": {
    "koa": "^2.7.0",
    "mime": "^2.4.5",
    "mkdirp": "^1.0.4",
    "rimraf": "^3.0.2",
    "hotnode": "0.0.8",
    "puppeteer": "^1.18.1",
    "extract-zip": "^2.0.0"
  }
}

构建及执行:

docker build -t xxx/seo .
docker run -m 256m -p 3000:3000 --read-only --name xxx/seo xxx/seo

nginx server 内配置:

location /path/to/spa {
    if ($http_user_agent ~* "Baiduspider|Googlebot|Googlebot-Mobile|Googlebot-Image|Mediapartners-Google|Adsbot-Google|Feedfetcher-Google|Yahoo! Slurp|Yahoo! Slurp China|YoudaoBot|Sosospider|Sogou spider|Sogou web spider|MSNBot|ia_archiver|Tomato Bot|FeedDemon|JikeSpider|Indy Library|Alexa Toolbar|AskTbFXTV|AhrefsBot|CrawlDaddy|CoolpadWebkit|Java|Feedly|UniversalFeedParser|ApacheBench|Microsoft URL Control|Swiftbot|ZmEu|oBot|jaunty|Python-urllib|lightDeckReports Bot|YYSpider|DigExt|YisouSpider|HttpClient|MJ12bot|EasouSpider|Ezooms|heritrix|qihoobot|^$")
    {
        proxy_pass http://127.0.0.1:3000;
        break;
    }
    # ...
}

如果 docker build 时卡在连 dl-ssl.google.com,原因您懂的,自己解决吧。或者试试改一下 RUN:

RUN apt-get update && apt-get install -y wget gnupg ca-certificates
RUN echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list
RUN apt-get update && apt-get install -y google-chrome-stable --allow-unauthenticated
RUN cd /var/www npm install
查看原文

赞 0 收藏 0 评论 0

非墨 发布了文章 · 7月12日

Web 上传漏洞及防范

2020 年不太平,各种牛鬼蛇神轮番登场。可能有点忘乎所以,不知哪句评论错了,被知乎封禁了一周。还好,冷静一下,再不参与zz相关的话题了。

说回正题,作为码农,网络安全一直以来是个麻烦。最近,在我司维护的一个很旧很旧的网站上,发现有人通过富文本编辑器用的上传接口,偷偷上传了一些不良内容的网页文件。

通常,我们使用富文本编辑器,以便用户可以发布图文混排的内容,甚至许可添加点附件。但方便的同时,也带来了一些安全隐患,如程序员比较熟悉的跨站攻击、点击劫持等。上传,尤其是允许上传 html 文件,这个危害是非常大的。首先,既然是 HTML,意味着可嵌入任意 JS,跨站攻击、点击劫持自然不在话下;其次,如果您的网站在搜索引擎排名不错,对方可通过 SEO 的形式,将您的网站变成一个倒流通道;如果您的网站涉及zf相关机构,对方放点黄赌毒内容,也会严重影响到某些单位的形象。

好在大部分富文本编辑器默认只提供插入图片功能,给出的服务端上传示例代码,也限定为仅支持上传图片。但也有一些功能较全的富文本编辑器,默认提供插入附件的功能,上传代码可能支持 pdf/txt/html 等浏览器可预览(执行)的文件类型。我们网站用的某款编辑器是 5、6 年以前加入的,一直也没升级,而新版编辑器早已移除默认的 html 类型。

先来说下如何利用富文本的上传漏洞往网站上传文件。富文本编辑器插入图片、视频、音频、附件,实际插入的是图片、视频、音频、附件的网址,包裹为 <img><video><audio> 等 html 标签。要么直接给一个网址,要么上传后返一个网址。对于后者,服务端需要给出一个接口,提供上传文件功能,并返回文件存入服务器后的网址。以此来看,入侵者完全不必管前端富文本编辑器的逻辑,直接利用上传接口,上传文件、拿到网址。

这要如何防范呢?我们已经知道了,入侵者根本不用管你前端用的什么编辑器、JS如何配置,他只需要探查到你的上传接口即可,因此,任何在前端限制不可插入资源都是无效的。防御方面,我认为有几点,各有利弊:

1、防盗链,为上传目录的请求加个过滤层,当程序发现 referer 不是您的域名时阻断,避免外链造成恶劣影响。这显然避免不了不良内容出现在站内。

2、临时文件,插入时先将文件上传到临时目录,待提交后内容校验通过,再转移到目标目录,同时替换内容中的网址。临时目录内文件超时自动删除。

3、图文分离,彻底抛弃富文本,或富文本仅能调节文字排版,图片、附件等用额外的字段存储,也就是说,文件与表单数据是绝对捆绑的,表单校验不通过,入侵方就不可能拿到文件网址。

4、文件转码,图片直接转为 base64 文本,利用 <img data-original="data:image/png;base64,xxx"/> 的形式与内容混合在一起;如果是图文分离模式,可将文件存入对应的 Binary 类型字段。这也是保障文件与表单数据捆绑,便于发现,更易封禁。缺点是占用数据库空间,也不便于直接使用主流 HTTP 服务的缓存功能。

以上后 3 条依然需要人工审查。现如今也出现一些 AI 内容审核的东西,但训练是件麻烦事,小企业在这方面耗费大量人力物力就得不偿失了。而阿里、百度等也有提供内容审核方面的接口,文本、图片均可,有些接口检查速度达毫秒级,完全可以封装到服务端的表单校验逻辑里。当然,天下没有免费的午餐。如果您的内容完全由内部人员维护,只用规避偷偷上传,限制某类用户可用,就够了。

本话题由富文本编辑器引起,那么,是否不用富文本编辑器就万事大吉了?从技术上来说,只要您的网站开放或半开放上传,依然可能存在被上传不良、黑链等内容的图片、文件,按照现行法律法规,这些文件只要在您服务器上,就脱不了干系,只是会不会被发现的问题。

以上面第 3 条为例,图文分离,当运营人员发现有个图片内容不良,他删除了此条数据,或标识为不公开,外部无法再浏览,通过条目ID打开也显示不存在或不可见,但对一般编程习惯来说,文件可能依然保留在原处。破坏的一方依然可以利用审查前拿到的文件网址,继续通过外部网页指向您的服务器。哪天那个黑站被端了,发现那些资源还都存在您那,冤不冤呀!

查看原文

赞 1 收藏 1 评论 0

认证与成就

  • 获得 119 次点赞
  • 获得 55 枚徽章 获得 4 枚金徽章, 获得 18 枚银徽章, 获得 33 枚铜徽章

擅长技能
编辑

开源项目 & 著作
编辑

注册于 2012-12-13
个人主页被 2.7k 人浏览