11. ! at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:192) [jetty-server-8.1.5.v20120716.jar:8.1.5.v20120716]
! at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1001) [jetty-server-8.1.5.v20120716.jar:8.1.5.v20120716]
! at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:129) [jetty-server-8.1.5.v20120716.jar:8.1.5.v20120716]
! at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:250) [jetty-server-8.1.5.v20120716.jar:8.1.5.v20120716]
! at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:149) [jetty-server-8.1.5.v20120716.jar:8.1.5.v20120716]
! at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:111) [jetty-server-8.1.5.v20120716.jar:8.1.5.v20120716]
! at org.eclipse.jetty.server.Server.handle(Server.java:360) [jetty-server-8.1.5.v20120716.jar:8.1.5.v20120716]
! at org.eclipse.jetty.server.AbstractHttpConnection.handleRequest(AbstractHttpConnection.java:454) [jetty-server-8.1.5.v20120716.jar:8.1.5.v20120716]
! at org.eclipse.jetty.server.AbstractHttpConnection.headerComplete(AbstractHttpConnection.java:890) [jetty-server-8.1.5.v20120716.jar:8.1.5.v20120716]
! at org.eclipse.jetty.server.AbstractHttpConnection$RequestHandler.headerComplete(AbstractHttpConnection.java:944) [jetty-server-8.1.5.v20120716.jar:8.1.5.v20120716
! at org.eclipse.jetty.http.HttpParser.parseNext(HttpParser.java:630) [jetty-http-8.1.5.v20120716.jar:8.1.5.v20120716]
! at org.eclipse.jetty.http.HttpParser.parseAvailable(HttpParser.java:230) [jetty-http-8.1.5.v20120716.jar:8.1.5.v20120716]
! at org.eclipse.jetty.server.AsyncHttpConnection.handle(AsyncHttpConnection.java:77) [jetty-server-8.1.5.v20120716.jar:8.1.5.v20120716]
! at org.eclipse.jetty.io.nio.SelectChannelEndPoint.handle(SelectChannelEndPoint.java:622) [jetty-io-8.1.5.v20120716.jar:8.1.5.v20120716]
! at org.eclipse.jetty.io.nio.SelectChannelEndPoint$1.run(SelectChannelEndPoint.java:46) [jetty-io-8.1.5.v20120716.jar:8.1.5.v20120716]
! at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:603) [jetty-util-8.1.5.v20120716.jar:8.1.5.v20120716]
! at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:538) [jetty-util-8.1.5.v20120716.jar:8.1.5.v20120716]
! at java.lang.Thread.run(Thread.java:680) [na:1.6.0_31]
Caused by: org.springframework.dao.InvalidDataAccessApiUsageException: [Assertion failed] - this argument is required; it must not be null; nested exception is java.lan
failed] - this argument is required; it must not be null
! at org.springframework.orm.jpa.EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(EntityManagerFactoryUtils.java:301) ~[spring-orm-3.1.2.RELEASE.jar:3.1
! at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:106) ~[spring-orm-3.1.2.RELEASE.jar:3.1.2.RELEASE]
! at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:58) ~[spring-tx-3.
! at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:213) ~[spring-tx-3.1.2.RELEASE.jar:3.1.2.RELEASE]
! at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:163) ~[spring-tx-3.1.2.RELEASE
! at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172) ~[spring-aop-3.1.2.RELEASE.jar:3.1.2.RELEASE]
! at org.springframework.data.jpa.repository.support.LockModeRepositoryPostProcessor$LockModePopulatingMethodIntercceptor.invoke(LockModeRepositoryPostProcessor.java
jpa-1.2.0.M1.jar:na]
! at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172) ~[spring-aop-3.1.2.RELEASE.jar:3.1.2.RELEASE]
! at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:90) ~[spring-aop-3.1.2.RELEASE.jar:3.1.2.RELEASE]
! at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172) ~[spring-aop-3.1.2.RELEASE.jar:3.1.2.RELEASE]
! at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202) ~[spring-aop-3.1.2.RELEASE.jar:3.1.2.RELEASE]
! at $Proxy44.findByNameStartsWith(Unknown Source) ~[na:na]
! ... 46 common frames omitted
Caused by: java.lang.IllegalArgumentException: [Assertion failed] - this argument is required; it must not be null
! at org.springframework.util.Assert.notNull(Assert.java:112) ~[spring-core-3.1.2.RELEASE.jar:3.1.2.RELEASE]
! at org.springframework.util.Assert.notNull(Assert.java:123) ~[spring-core-3.1.2.RELEASE.jar:3.1.2.RELEASE]
! at org.springframework.data.jpa.repository.query.ParameterMetadataProvider$ParameterMetadata.prepare(ParameterMetadataProvider.java:156) ~[spring-data-jpa-1.2.0.M1
! at org.springframework.data.jpa.repository.query.CriteriaQueryParameterBinder.bind(CriteriaQueryParameterBinder.java:68) ~[spring-data-jpa-1.2.0.M1.jar:na]
! at org.springframework.data.jpa.repository.query.ParameterBinder.bind(ParameterBinder.java:108) ~[spring-data-jpa-1.2.0.M1.jar:na]
! at org.springframework.data.jpa.repository.query.PartTreeJpaQuery$CountQueryPreparer.invokeBinding(PartTreeJpaQuery.java:196) ~[spring-data-jpa-1.2.0.M1.jar:na]
! at org.springframework.data.jpa.repository.query.PartTreeJpaQuery$QueryPreparer.createQuery(PartTreeJpaQuery.java:121) ~[spring-data-jpa-1.2.0.M1.jar:na]
! at org.springframework.data.jpa.repository.query.PartTreeJpaQuery.doCreateCountQuery(PartTreeJpaQuery.java:82) ~[spring-data-jpa-1.2.0.M1.jar:na]
! at org.springframework.data.jpa.repository.query.AbstractJpaQuery.createCountQuery(AbstractJpaQuery.java:148) ~[spring-data-jpa-1.2.0.M1.jar:na]
! at org.springframework.data.jpa.repository.query.JpaQueryExecution$PagedExecution.doExecute(JpaQueryExecution.java:99) ~[spring-data-jpa-1.2.0.M1.jar:na]
! at org.springframework.data.jpa.repository.query.JpaQueryExecution.execute(JpaQueryExecution.java:55) ~[spring-data-jpa-1.2.0.M1.jar:na]
! at org.springframework.data.jpa.repository.query.AbstractJpaQuery.doExecute(AbstractJpaQuery.java:95) ~[spring-data-jpa-1.2.0.M1.jar:na]
! at org.springframework.data.jpa.repository.query.AbstractJpaQuery.execute(AbstractJpaQuery.java:85) ~[spring-data-jpa-1.2.0.M1.jar:na]
! at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:313) ~[spring-data
! at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172) ~[spring-aop-3.1.2.RELEASE.jar:3.1.2.RELEASE]
! at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:110) ~[spring-tx-3.1.2.RELEASE.jar:3.1.2.RELEASE]
! at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172) ~[spring-aop-3.1.2.RELEASE.jar:3.1.2.RELEASE]
! at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:155) ~[spring-tx-3.1.2.RELEASE
Stack Traces
! ... 53 common frames omitted
9 Rails - Innovation and Security
12. $ irb
> a
ruby-1.9.3-p0 :045 > a
NameError: undefined local variable or method `a' for main:Object
ruby-1.9.3-p0 :046 > b
NameError: undefined local variable or method `b' for main:Object
ruby-1.9.3-p0 :047 > a = b
NameError: undefined local variable or method `b' for main:Object
ruby-1.9.3-p0 :048 > a = a
... ?
2004
10 Rails - Innovation and Security
13. $ irb
> a
ruby-1.9.3-p0 :045 > a
NameError: undefined local variable or method `a' for main:Object
ruby-1.9.3-p0 :046 > b
NameError: undefined local variable or method `b' for main:Object
ruby-1.9.3-p0 :047 > a = b
NameError: undefined local variable or method `b' for main:Object
ruby-1.9.3-p0 :048 > a = a
... ?
=> nil
2004
10 Rails - Innovation and Security
16. class
Role
<
ActiveRecord::Base
attr_accessor
:name
has_and_belongs_to_many
:clients
end
class
Client
<
ActiveRecord::Base
has_and_belongs_to_many
:roles
end
Active Record
13 Rails - Innovation and Security
17. class
Role
<
ActiveRecord::Base
attr_accessor
:name
has_and_belongs_to_many
:clients
end
class
Client
<
ActiveRecord::Base
has_and_belongs_to_many
:roles
end
client_roles
1 0..* client_id 0..* 1
Client role_id Role
name
Active Record
13 Rails - Innovation and Security
18. class
Role
<
ActiveRecord::Base
attr_accessor
:name
has_and_belongs_to_many
:clients
end
class
Client
<
ActiveRecord::Base
has_and_belongs_to_many
:roles
end
client_roles
1 0..* client_id 0..* 1
Client role_id Role
Magic!
name
Active Record
13 Rails - Innovation and Security
19. class
Role
<
ActiveRecord::Base
attr_accessor
:name
has_and_belongs_to_many
:clients
end
Metaprogramming
14 Rails - Innovation and Security
20. class
Role
<
ActiveRecord::Base
attr_accessor
:name
has_and_belongs_to_many
:clients
end
Role.find_or_create_by_name("admin")
Metaprogramming
14 Rails - Innovation and Security
21. class
Role
<
ActiveRecord::Base
attr_accessor
:name
has_and_belongs_to_many
:clients
end
Role.find_or_create_by_name("admin")
def
method_missing(m,
*args,
&block)
#
magic
end
Metaprogramming
14 Rails - Innovation and Security
22. class
Role
<
ActiveRecord::Base
attr_accessor
:name
has_and_belongs_to_many
:clients
end
Role.find_or_create_by_name("admin")
def
method_missing(m,
*args,
&block)
#
magic
end
Magic!
Metaprogramming
14 Rails - Innovation and Security
23. 2008 , Kiel
15 Rails - Innovation and Security
37. $
cap
deploy:migrations
v1
-‐>
v2
current
shared
releases
20130128231601
20130129231801
20130129161601 current
Capistrano Deployment
25 Rails - Innovation and Security
38. $
cap
deploy:migrations
v1
-‐>
v2
$
cap
deploy
rollback
current
shared
releases
20130128231601
20130129231801 current
20130129161601 current
Capistrano Deployment
25 Rails - Innovation and Security
39. class
User
<
ActiveRecord::Base
devise
:database_authenticatable,
:registerable,
:recoverable,
:rememberable,
:trackable,
:validatable
end
Devise
26 Rails - Innovation and Security
49. class
Role
<
ActiveRecord::Base
attr_accessor
:name
end
User.find_by_name(
"Robert');
DROP
TABLE
Students;
-‐-‐")
SQL Injection. Solved.
34 Rails - Innovation and Security
50. class
Role
<
ActiveRecord::Base
attr_accessor
:name
end
User.find_by_name(
"Robert');
DROP
TABLE
Students;
-‐-‐")
SQL Injection. Solved.
34 Rails - Innovation and Security
51. <script
language="javascript">
document.write("<script
src='malware.js'></script>");
</script>
Cross Site Scripting
35 Rails - Innovation and Security
57. User.find_by_id(
{:select
=>"*
from
users
limit
1
-‐-‐"})
SELECT
*
from
users
limit
1
-‐-‐
FROM
"users"
WHERE
"users"."id"
IS
NULL
LIMIT
1
=>
#<User
id:
1,
all
other
attributes
Security Leak, Jan 3rd
41 Rails - Innovation and Security
66. • Strong community
• Simple magic
• Eats resources
• Enterprise ready
• Hosting is either hard or expensive
• Open + Innovative + Secure
Asking Developers
48 Rails - Innovation and Security